playlistalo.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #!/usr/bin/env python3
  2. #Playlistalo - simpatico script che legge le cartelle e genera la playlist
  3. import youtube_dl
  4. import shutil
  5. import sys
  6. import re
  7. import os
  8. import validators
  9. from glob import glob
  10. import json
  11. import time
  12. import subprocess
  13. import random
  14. scriptpath = os.path.dirname(os.path.realpath(__file__))
  15. def add(url, user = "-unknown-", sortrandom = False):
  16. #print ('--- Inizio ---')
  17. init()
  18. ydl_opts = {
  19. 'format': 'bestaudio[ext=m4a]',
  20. 'outtmpl': 'cache/%(id)s.m4a',
  21. 'noplaylist': True,
  22. 'quiet': True,
  23. }
  24. url = url.strip()
  25. print ("url: " + url)
  26. print ("user: " + user)
  27. if not validators.url(url):
  28. print ('--- URL malformato ---')
  29. return ("Err: url non valido")
  30. with youtube_dl.YoutubeDL(ydl_opts) as ydl:
  31. try:
  32. meta = ydl.extract_info(url, download = False)
  33. except youtube_dl.DownloadError as detail:
  34. print ('--- Errore video non disponibile ---')
  35. print(str(detail))
  36. return ("Err: " + str(detail))
  37. id = meta.get('id').strip()
  38. title = __normalizetext(meta.get('title'))
  39. print ('id: %s' %(id))
  40. print ('title: %s' %(title))
  41. #scrivo il json
  42. with open(os.path.join("cache", id + ".json"), 'w') as outfile:
  43. json.dump(meta, outfile, indent=4)
  44. #ho letto le info, ora controllo se il file esiste altrimenti lo scarico
  45. #miglioria: controllare se upload_date e' uguale a quella del json gia' esistente
  46. filetemp = os.path.join("cache", id + ".m4a")
  47. if not glob(filetemp):
  48. print ('--- Scarico ---')
  49. ydl.download([url]) #non ho capito perche' ma senza [] fa un carattere per volta
  50. if not os.path.isfile(filetemp):
  51. return("Err: file non scaricato")
  52. #se il file esiste gia' in playlist salto (potrebbe esserci, anche rinominato)
  53. if glob(scriptpath + "/playlist/**/*|" + id + ".*"):
  54. print ('--- File già presente ---')
  55. return ("Err: %s [%s] già presente" %(title, id))
  56. if not os.path.exists("playlist/" + user):
  57. os.makedirs("playlist/" + user)
  58. #qui compone il nome del file
  59. if sortrandom:
  60. fileout = str(random.randrange(10**6)).zfill(14) + "|" + title + "|" + id + ".m4a"
  61. else:
  62. fileout = time.strftime("%Y%m%d%H%M%S") + "|" + title + "|" + id + ".m4a"
  63. fileout = os.path.join("playlist/" + user, fileout)
  64. print ('--- Converto ---')
  65. print (fileout)
  66. subprocess.call([scriptpath + "/trimaudio.sh", filetemp, fileout])
  67. if not os.path.isfile(fileout):
  68. return("Err: file non convertito")
  69. #cerca la posizione del pezzo appena inserito
  70. pos = getposition(fileout)
  71. #print ('--- Fine ---')
  72. print ("")
  73. return ("OK: %s [%s] aggiunto alla playlist in posizione %s" %(title, id, pos))
  74. def __normalizetext(s):
  75. if s is None:
  76. return None
  77. else:
  78. s = re.sub(r'[\\|/|:|*|?|"|<|>|\|]',r'',s)
  79. s = " ".join(s.split())
  80. return s
  81. def init():
  82. if not os.path.exists("playlist"):
  83. os.makedirs("playlist")
  84. if not os.path.exists("cache"):
  85. os.makedirs("cache")
  86. if not os.path.exists("fallback"):
  87. os.makedirs("fallback")
  88. if not os.path.exists("archive"):
  89. os.makedirs("archive")
  90. def list():
  91. pl = []
  92. pl2 = []
  93. for udir in sorted(glob(scriptpath + "/playlist/*/")):
  94. #print (udir)
  95. user = os.path.basename(os.path.dirname(udir))
  96. #cerca il file last
  97. last = ""
  98. if os.path.exists(udir + "/last"):
  99. f = open(udir + "/last", "r")
  100. last = f.readline().rstrip()
  101. else:
  102. last = os.path.basename(sorted(glob(udir + "/*.m4a"))[0]).split("|")[0]
  103. #print ("LAST: " + last)
  104. #leggi i file nella cartella
  105. files = sorted(glob(udir + "/*.m4a"))
  106. seq = 0
  107. for file in files:
  108. bn = os.path.splitext(os.path.basename(file))[0]
  109. #print ("BASENAME: " + bn)
  110. seq = seq + 1
  111. dat = bn.split("|")[0]
  112. nam = bn.split("|")[1]
  113. cod = bn.split("|")[2]
  114. key = "-".join([str(seq).zfill(5), last, dat])
  115. #print ("KEY: " + key)
  116. plsong = [key, file.replace(scriptpath + "/", "") , user, nam, cod] #, file
  117. pl.append(plsong)
  118. pl.sort()
  119. #rimuove la prima colonna, che serve solo per l'ordinamento
  120. pl2 = [x[1:] for x in pl]
  121. #print (pl)
  122. #print ('\n'.join([", ".join(x) for x in pl]))
  123. #print ('\n'.join([x[0] for x in pl]))
  124. return pl2
  125. def listfallback():
  126. pl = []
  127. pl2 = []
  128. #leggi i file nella cartella
  129. files = sorted(glob(scriptpath + "/fallback/*.m4a"))
  130. seq = 0
  131. for file in files:
  132. bn = os.path.splitext(os.path.basename(file))[0]
  133. seq = seq + 1
  134. dat = bn.split("|")[0]
  135. nam = bn.split("|")[1]
  136. cod = bn.split("|")[2]
  137. key = "-".join([str(seq).zfill(5), dat])
  138. plsong = [key, file.replace(scriptpath + "/", "") , "fallback", nam, cod] #, file
  139. pl.append(plsong)
  140. pl.sort()
  141. #rimuove la prima colonna, che serve solo per l'ordinamento
  142. pl2 = [x[1:] for x in pl]
  143. return pl2
  144. def playsingle():
  145. pl = list()
  146. #print ('\n'.join([x[0] for x in pl]))
  147. if pl:
  148. firstsong = scriptpath + "/" + pl[0][0]
  149. print (firstsong)
  150. #qui fa play
  151. subprocess.call(["mplayer", "-nolirc", "-msglevel", "all=0:statusline=5", firstsong])
  152. #alla fine consuma
  153. os.rename(firstsong, scriptpath + "/archive/" + os.path.basename(firstsong))
  154. #se non ci sono + file cancella la cartella
  155. if not glob(os.path.dirname(firstsong) + "/*.m4a"):
  156. shutil.rmtree(os.path.dirname(firstsong))
  157. else:
  158. with open(os.path.dirname(firstsong) + "/last", "w") as f:
  159. f.write(time.strftime("%Y%m%d%H%M%S"))
  160. else:
  161. #usa il fallback
  162. #eventualmente aggiungere file di avviso con istruzioni veloci
  163. plf = listfallback()
  164. #print ('\n'.join([x[0] for x in plf]))
  165. if plf:
  166. firstsong = plf[0][0]
  167. print (firstsong)
  168. #qui fa play
  169. subprocess.call(["mplayer", "-nolirc", "-msglevel", "all=0:statusline=5", firstsong])
  170. #alla fine consuma
  171. fname = time.strftime("%Y%m%d%H%M%S") + "|" + "|".join(os.path.basename(firstsong).split("|")[1:])
  172. fname = os.path.dirname(firstsong) + "/" + fname
  173. os.rename(firstsong, fname)
  174. def playloop():
  175. while True:
  176. playsingle()
  177. def clean():
  178. #cancella tutto dalla playlist
  179. shutil.rmtree("playlist")
  180. os.makedirs("playlist")
  181. def shuffleusers():
  182. #scrivere un numero casuale dentro a tutti i file last
  183. for udir in sorted(glob("playlist/*/")):
  184. #print (udir)
  185. with open(udir + "/last", "w") as f:
  186. f.write(str(random.randrange(10**6)).zfill(14))
  187. def shufflefallback():
  188. #rinominare con un numero casuale i file in fallback
  189. files = sorted(glob("fallback/*.m4a"))
  190. for file in files:
  191. fname = str(random.randrange(10**6)).zfill(14) + "|" + "|".join(os.path.basename(file).split("|")[1:])
  192. fname = os.path.dirname(file) + "/" + fname
  193. os.rename(file, fname)
  194. def getposition(file):
  195. pl = list()
  196. try:
  197. return([x[0] for x in pl].index(file) + 1)
  198. except:
  199. pass
  200. if __name__ == '__main__':
  201. print ("This is a package, use other commands to run it")
  202. getposition("playlist/Itec78/20200404145736|George Baker- Little Green Bag|4b1wt3-zpzQ.m4az")