playlistalo/playlistalo.py

255 lines
7.6 KiB
Python
Executable file

#!/usr/bin/env python3
#Playlistalo - simpatico script che legge le cartelle e genera la playlist
import youtube_dl
import shutil
import sys
import re
import os
import validators
from glob import glob
import json
import time
import subprocess
import random
scriptpath = os.path.dirname(os.path.realpath(__file__))
def add(url, user = "-unknown-", sortrandom = False):
print ('--- Inizio ---')
init()
ydl_opts = {
'format': 'bestaudio[ext=m4a]',
'outtmpl': 'cache/%(id)s.m4a',
'noplaylist': True,
}
url = url.strip()
print (url)
print (user)
if not validators.url(url):
print ('--- URL malformato ---')
return ("Err: url non valido")
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
try:
meta = ydl.extract_info(url, download = False)
except youtube_dl.DownloadError as detail:
print ('--- Errore video non disponibile ---')
print(str(detail))
return ("Err: " + str(detail))
id = meta.get('id').strip()
title = __normalizetext(meta.get('title'))
print ('id : %s' %(id))
print ('title : %s' %(title))
#scrivo il json
with open(os.path.join("cache", id + ".json"), 'w') as outfile:
json.dump(meta, outfile, indent=4)
#ho letto le info, ora controllo se il file esiste altrimenti lo scarico
#miglioria: controllare se upload_date e' uguale a quella del json gia' esistente
filetemp = os.path.join("cache", id + ".m4a")
if not glob(filetemp):
print ('--- Scarico ---')
ydl.download([url]) #non ho capito perche' ma senza [] fa un carattere per volta
#se il file esiste gia' in playlist salto (potrebbe esserci, anche rinominato)
if glob(scriptpath + "/playlist/**/*|" + id + ".*"):
print ('--- File già presente ---')
return ("Err: %s [%s] già presente" %(title, id))
print ('--- Scarico ---')
if not os.path.exists("playlist/" + user):
os.makedirs("playlist/" + user) #qui compone il nome del file
if sortrandom:
fileout = str(random.randrange(10**6)).zfill(14) + "|" + title + "|" + id + ".m4a"
else:
fileout = time.strftime("%Y%m%d%H%M%S") + "|" + title + "|" + id + ".m4a"
print (fileout)
fileout = os.path.join("playlist/" + user, fileout)
if not os.path.isfile(filetemp):
return("Err: file non scaricato")
#copia il file nella cartella playlist
#shutil.copy(filetemp, fileout)
print ('--- Converto ---')
subprocess.call([scriptpath + "/trimaudio.sh", filetemp, fileout])
if not os.path.isfile(fileout):
return("Err: file non convertito")
#cerca la posizione del pezzo appena inserito
pos = getposition(fileout)
print ('--- Fine ---')
print ("")
return ("OK: %s [%s] aggiunto alla playlist in posizione %s" %(title, id, pos))
def __normalizetext(s):
if s is None:
return None
else:
s = re.sub(r'[\\|/|:|*|?|"|<|>|\|]',r'',s)
s = " ".join(s.split())
return s
def init():
if not os.path.exists("playlist"):
os.makedirs("playlist")
if not os.path.exists("cache"):
os.makedirs("cache")
if not os.path.exists("fallback"):
os.makedirs("fallback")
if not os.path.exists("archive"):
os.makedirs("archive")
def list():
pl = []
pl2 = []
for udir in sorted(glob(scriptpath + "/playlist/*/")):
#print (udir)
user = os.path.basename(os.path.dirname(udir))
#cerca il file last
last = ""
if os.path.exists(udir + "/last"):
f = open(udir + "/last", "r")
last = f.readline().rstrip()
else:
last = os.path.basename(sorted(glob(udir + "/*.m4a"))[0]).split("|")[0]
#print ("LAST: " + last)
#leggi i file nella cartella
files = sorted(glob(udir + "/*.m4a"))
seq = 0
for file in files:
bn = os.path.splitext(os.path.basename(file))[0]
#print ("BASENAME: " + bn)
seq = seq + 1
dat = bn.split("|")[0]
nam = bn.split("|")[1]
cod = bn.split("|")[2]
key = "-".join([str(seq).zfill(5), last, dat])
#print ("KEY: " + key)
plsong = [key, file.replace(scriptpath + "/", "") , user, nam, cod] #, file
pl.append(plsong)
pl.sort()
#rimuove la prima colonna, che serve solo per l'ordinamento
pl2 = [x[1:] for x in pl]
#print (pl)
#print ('\n'.join([", ".join(x) for x in pl]))
#print ('\n'.join([x[0] for x in pl]))
return pl2
def listfallback():
pl = []
pl2 = []
#leggi i file nella cartella
files = sorted(glob(scriptpath + "/fallback/*.m4a"))
seq = 0
for file in files:
bn = os.path.splitext(os.path.basename(file))[0]
seq = seq + 1
dat = bn.split("|")[0]
nam = bn.split("|")[1]
cod = bn.split("|")[2]
key = "-".join([str(seq).zfill(5), dat])
plsong = [key, file.replace(scriptpath + "/", "") , "fallback", nam, cod] #, file
pl.append(plsong)
pl.sort()
#rimuove la prima colonna, che serve solo per l'ordinamento
pl2 = [x[1:] for x in pl]
return pl2
def playsingle():
pl = list()
#print ('\n'.join([x[0] for x in pl]))
if pl:
firstsong = scriptpath + "/" + pl[0][0]
print (firstsong)
#qui fa play
subprocess.call(["mplayer", "-nolirc", "-msglevel", "all=0:statusline=5", firstsong])
#alla fine consuma
os.rename(firstsong, scriptpath + "/archive/" + os.path.basename(firstsong))
#se non ci sono + file cancella la cartella
if not glob(os.path.dirname(firstsong) + "/*.m4a"):
shutil.rmtree(os.path.dirname(firstsong))
else:
with open(os.path.dirname(firstsong) + "/last", "w") as f:
f.write(time.strftime("%Y%m%d%H%M%S"))
else:
#usa il fallback
#eventualmente aggiungere file di avviso con istruzioni veloci
plf = listfallback()
#print ('\n'.join([x[0] for x in plf]))
if plf:
firstsong = plf[0][0]
print (firstsong)
#qui fa play
subprocess.call(["mplayer", "-nolirc", "-msglevel", "all=0:statusline=5", firstsong])
#alla fine consuma
fname = time.strftime("%Y%m%d%H%M%S") + "|" + "|".join(os.path.basename(firstsong).split("|")[1:])
fname = os.path.dirname(firstsong) + "/" + fname
os.rename(firstsong, fname)
def playloop():
while True:
playsingle()
def clean():
#cancella tutto dalla playlist
shutil.rmtree("playlist")
os.makedirs("playlist")
def shuffleusers():
#scrivere un numero casuale dentro a tutti i file last
for udir in sorted(glob("playlist/*/")):
#print (udir)
with open(udir + "/last", "w") as f:
f.write(str(random.randrange(10**6)).zfill(14))
def shufflefallback():
#rinominare con un numero casuale i file in fallback
files = sorted(glob("fallback/*.m4a"))
for file in files:
fname = str(random.randrange(10**6)).zfill(14) + "|" + "|".join(os.path.basename(file).split("|")[1:])
fname = os.path.dirname(file) + "/" + fname
os.rename(file, fname)
def getposition(file):
pl = list()
try:
return([x[0] for x in pl].index(file) + 1)
except:
pass
if __name__ == '__main__':
print ("This is a package, use other commands to run it")
getposition("playlist/Itec78/20200404145736|George Baker- Little Green Bag|4b1wt3-zpzQ.m4az")