diff --git a/README.md b/README.md index ed2fbed..50e16d0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ now using a venv so : python3 -m venv .venv source .venv/bin/activate -pip install tinytag scikit-image +pip install tinytag scikit-image popen ## run the script diff --git a/database/show.db b/database/show.db index a3c79f0..a48a537 100644 Binary files a/database/show.db and b/database/show.db differ diff --git a/html/templates/episode.jinja b/html/templates/episode.jinja index a83917b..992d040 100644 --- a/html/templates/episode.jinja +++ b/html/templates/episode.jinja @@ -92,7 +92,7 @@
-

{{show_title}}

+

{{show_name}} | Episode #{{episode_number}}

{{episode_author}} / {{episode_date}} / {{episode_dur}}
@@ -119,6 +119,7 @@ + @@ -130,12 +131,13 @@ - - - - - - + + + + + +
# TRACK ARTIST ALBUM
{{track[0]}}{{track[1]}}{{track[2]}}{{track[3]}}{{track[4]}}{{track[5]}} + {{track[0]}}{{track[1]}}{{track[2]}}{{track[3]}}{{track[4]}}{{track[5]}}{{track[6]}} diff --git a/html/templates/homepage.jinja b/html/templates/homepage.jinja index 322a88a..a1e4a9f 100644 --- a/html/templates/homepage.jinja +++ b/html/templates/homepage.jinja @@ -94,7 +94,7 @@

Latest Episode: # {{episode_number}}

-
{{episode_artists}}
+
This week music from: {{episode_artists}}
{{episode_author}} / Zavod Rizoma | 16 September 2017 | 1:30:20

Episode Details and Player

@@ -127,7 +127,7 @@

Episode: # {{episode.episode_number}}

Presented by Rob Canning / {{episode.episode_date}} / {{episode.episode_duration}}
-

On this weeks show music from: {{episode.episode_artists}}

+

On this weeks show music from: {{episode.episode_artists}}

@@ -164,108 +164,96 @@
-
-
-
-

Behind The Mic

-
-
-
-
-
+
- Image + + + + + + + + + + + -
+ -

Rob Canning

- Creative Director -

Lorem ipsum dolor sit amet consectetur adipisicing elit ullam reprehenderit nemo.

-

- - - -

-
+ -
-
+ + + + + + + + + -
-
+ + - Image - -
- -

Brooke Cagle

- Creative Director -

Lorem ipsum dolor sit amet consectetur adipisicing elit ullam reprehenderit nemo.

-

- - - -

-
- -
-
+ + + -
-
-
-
-

Featured Labels

-
-
- -
-
+ + + @@ -280,43 +268,43 @@

{{about_show}}

- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -354,16 +342,16 @@
-
-
- + + + -
-
- Image placeholder - -
-
+ + + + + +
diff --git a/mk_music_library_db.py b/mk_music_library_db.py index 5144f71..eb514e2 100755 --- a/mk_music_library_db.py +++ b/mk_music_library_db.py @@ -12,6 +12,7 @@ import uuid #import pypika # sql query builder from pypika import Query, Table, Field, Column + music_library_path = "/home/rob/antena/music/" conn = sqlite3.connect("database/show.db") @@ -22,7 +23,7 @@ labelnames = [("sploh", "https://sploh.bandcamp.com"), ("terraformer"), ("pharam mus_lib = Query \ .create_table("MUSIC_LIBRARY") \ .columns( - Column("id", "INT", nullable=True), + Column("id", "VARCHAR(32)", nullable=False), Column("label", "VARCHAR(100)", nullable=True), Column("album", "VARCHAR(100)", nullable=True), Column("track", "VARCHAR(200)", nullable=True), @@ -34,8 +35,8 @@ mus_lib = Query \ Column("path", "VARCHAR(120)", nullable=False), Column("lastplay", "DATETINE", nullable=True), Column("comment", "VARCHAR(120)", nullable=True))\ - .unique("path") \ - .primary_key("path") + .unique("id") \ + .primary_key("id") def database_create(conn): # the MUSIC LIBRARY TABLE @@ -43,6 +44,22 @@ def database_create(conn): conn.execute(str(mus_lib)) print('''MUSIC LIBRARY Table created successfully'''); + print(''' +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣠⠤⠤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⢀⣤⠾⠛⠉⠀⠀⠀⠀⠀⠀⠉⠛⠷⣤⡀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠐⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⠂⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⣰⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣆⠀⠀⠀⠀ +⠀⠀⠀⣰⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣆⠀⠀⠀ +⠀⠀⢰⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡆⠀⠀ +⠀⠀⣾⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⣷⠀⠀ +⠀⢰⡇⠀⣰⣶⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣶⣆⠀⢸⡆⠀ +⠀⢈⠁⢠⣿⣿⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣿⣿⡄⠈⡁⠀ +⠀⢸⡇⢸⣿⣿⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣿⣿⡇⢸⡇⠀ +⠀⠈⠁⠸⣿⣿⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣿⣿⠇⠈⠁⠀ +⠀⠀⠀⠀⠻⣿⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣿⠟⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + '''); + def database_create_episodes_table(conn): # the show database @@ -51,6 +68,7 @@ def database_create_episodes_table(conn): .columns( Column("id", "INT", nullable=True), Column("episode", "INT", nullable=True), + Column("track_number", "INT", nullable=True), Column("date", 'DATETIME', nullable=True), Column("album", "VARCHAR(200)", nullable=True), Column("track", "VARCHAR(120)", nullable=True), @@ -61,8 +79,9 @@ def database_create_episodes_table(conn): Column("path", "VARCHAR(120)", nullable=False), Column("label", "VARCHAR(120)", nullable=False), Column("comment", "VARCHAR(120)", nullable=False))\ - .unique("path") \ - .primary_key("path") + .unique("id") \ + .primary_key("id") + #TODO get the unique path back into action find bug conn.execute(str(q)) @@ -84,7 +103,8 @@ def mk_db_entry(conn): track = TinyTag.get(os.path.join(subdir, file))# get metadata from file cursor = conn.cursor() mus_lib = Table('MUSIC_LIBRARY') - q = mus_lib.insert(1, label, track.album, track.title, track.artist, \ + id = str(uuid.uuid4()) + q = mus_lib.insert(id, label, track.album, track.title, track.artist, \ track.genre, track.duration, track.year, \ label_url, str(filepath), 1970-1-1, track.comment) cursor.execute(str(q)); diff --git a/mk_show.py b/mk_show.py index f460ed7..bd7fd11 100755 --- a/mk_show.py +++ b/mk_show.py @@ -8,6 +8,7 @@ from os.path import join from tinytag import TinyTag from random import shuffle import sqlite3, json +import subprocess import uuid from pypika import Query, Table, Field, Column @@ -52,28 +53,80 @@ def create_intro(episode_playlist): intro = random.choice(os.listdir(intropath)) episode_playlist.insert(0, str(os.path.abspath(intropath)) + "/" + str(intro)) -def add_to_tracks_played(add_to_played: str): - with open('playlists/track_playout_history.txt', "a") as tracks_played_file: - tracks_played_file.write(str(add_to_played) + "\n") # newline \n needed here? +# TODO make this go away.... +#def add_to_tracks_played(add_to_played: str): +# with open('playlists/track_playout_history.txt', "a") as tracks_played_file: +# tracks_played_file.write(str(add_to_played) + "\n") # newline \n needed here? #TODO replace the below with database stuff + def check_archive(track): + global archive + cursor = conn.cursor() + cursor.execute("SELECT * FROM EPISODES WHERE path = ?", (track,)) + data=cursor.fetchone() + + if data is None: + print('') + #print('There is no component named ?', [track]) + else: + print('Component ? found with rowid ? /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////', [track, data[0]]) + + + + + with open('playlists/track_playout_history.txt') as archive_file: for line in archive_file: archive.append(line) if track not in archive: - print("____ TRACK NOT YET PLAYED ... ADDING _____") + #print("____ TRACK NOT YET PLAYED ... ADDING _____") return True else: - print("____ TRACK ALREADY PLAYED _____") + #print("____ TRACK ALREADY PLAYED _____") return False +def playlist_replace_track(conn, episode_playlist, episode_number, track_to_replace): + cursor = conn.cursor() + cursor.execute("SELECT * FROM MUSIC_LIBRARY ORDER BY RANDOM() LIMIT 1 ;") + r = cursor.fetchone() # FETCH ONE RANDOM TRACK FROM THE DATABASE + print('new suggestion================================' + str(r)) + # for t in r: + song = str(r[9]) + track_label = str(r[1]) + track_album = str(r[2]) + track_title = str(r[3]) + track_artist = str(r[4]) + track_duration = float(r[6]) + track_genre = str(r[5]) + track_year = str(r[7]) + track_path = song #'/'.join(song.split('/')[0:-1]) + track_comment = str(r[11]) + + e = Table('EPISODES') + + # TODO This is not replace at the desired index / row but appending to the end of the table + q = e.insert(1, episode_number, track_to_replace, episode_date,\ + track_album, track_title, track_artist, \ + track_duration,track_genre, track_year, \ + track_path, track_label, track_comment).where('e.track_number'==1)('e.episode'==1) + cursor.execute(str(q)) + conn.commit() + print("sqlite: Episode track successfully updated into SHOW table"); + + #cursor = conn.cursor() + #cursor.execute('INSERT OR REPLACE FROM EPISODES WHERE EPISODE=? and track_number=?', [episode_number, track_to_replace]) + #preview = cursor.fetchall() + #for i in preview: + # print('{0} : {1} {2} {3} {4} \n'.format(i[2], i[4], i[5], i[6], i[7],)) + + def create_episode_playlist(conn, episode_playlist: list, episode_number): - global episode_duration + episode_duration = 0 global archive - + track_number = 0 track_count = 0 global artists_played max_track_dur = 9 @@ -81,7 +134,7 @@ def create_episode_playlist(conn, episode_playlist: list, episode_number): # first clear the sqlite table rows for the episode cursor = conn.cursor() - cursor.execute('DELETE FROM episodes WHERE episode = {0}'.format(episode_number)) + cursor.execute('DELETE FROM EPISODES WHERE episode = {0}'.format(episode_number)) # TODO what is most important 12 tracks or 60 minutes @@ -89,7 +142,6 @@ def create_episode_playlist(conn, episode_playlist: list, episode_number): cursor.execute("SELECT * FROM MUSIC_LIBRARY ORDER BY RANDOM() LIMIT 1 ;") r = cursor.fetchone() # FETCH ONE RANDOM TRACK FROM THE DATABASE - # for t in r: song = str(r[9]) track_label = str(r[1]) @@ -101,11 +153,12 @@ def create_episode_playlist(conn, episode_playlist: list, episode_number): track_year = str(r[7]) track_path = song #'/'.join(song.split('/')[0:-1]) track_comment = str(r[11]) + # SOME LOGIC TO SEE IF WE ALLOW THAT TRACK OR NOT # TODO here we need to append to DB not the static file if track_artist not in artists_played: - if check_archive(track_title) is True: + if check_archive(track_path) is True: if track_duration > min_track_dur * 60: if int(track_duration) < max_track_dur * 60: episode_playlist.append(song.rstrip()) # if 'not in' is true then add the song @@ -115,39 +168,86 @@ def create_episode_playlist(conn, episode_playlist: list, episode_number): art = string=re.sub("and","&",art) artist_abreviated.append(art) artists_played.append(track_artist) # and add the artist to the played list - add_to_tracks_played(track_title) # and write entry to archive file + #add_to_tracks_played(track_path) # and write entry to archive file if not track_year: # where missing metadata give a dummy value - track_year = 0000 + track_year = "0000" e = Table('EPISODES') - q = e.insert(1, episode_number, episode_date, \ + track_number = track_count + id = str(uuid.uuid4()) + q = e.insert(id, episode_number, track_number, episode_date,\ track_album, track_title, track_artist, \ track_duration,track_genre, track_year, \ track_path, track_label, track_comment) cursor.execute(str(q)) - # ID, EPISODE, DATE, ALBUM, TRACK, ARTIST, TRACKDUR, YEAR, PATH) \ - # VALUES (NULL, ?, ?, ?, ?, ?,?,?,? )", [episode_number, episode_date, \ - # track_album, track_title, track_artist, \ - # track_duration, track_year, track_path]); conn.commit() - print("sqlite: Episode track successfully inserted into SHOW table"); + # print("sqlite: Episode track successfully inserted into SHOW table"); - track_count += 1; print(track_count) + track_count += 1; episode_duration = episode_duration + track_duration - else: print("TRACK TOO SHORT..........." ) - else: print("TRACK TOO LONG..........." ) - else: print("SONG PLAYED IN PREVIOUS EPISODE" ) - else: print("ARTIST ALREADY IN PODCAST") + # else: print("TRACK TOO SHORT..........." ) + # else: print("TRACK TOO LONG..........." ) + # else: print("SONG PLAYED IN PREVIOUS EPISODE" ) + #else: print("ARTIST ALREADY IN PODCAST") - # - - episode_duration = timedelta(seconds=round(episode_duration)) + #TODO am i happy with track selection? change an entry ? add a specific entry? to replace + # preview and modify option -TODO move to its own function + cursor = conn.cursor() + cursor.execute('SELECT * FROM EPISODES WHERE EPISODE=?', [episode_number]) + preview = cursor.fetchall() + print("/////////////////////////////////////////////////") + for i in preview: + print('{0} : {1} {2} {3} {4}'.format(i[2], i[4], i[5], i[6], i[7],)) - print("total tracks = {0} \n total duration = {1} ".format(track_count, episode_duration)) + dj_is_unsure=True + + cursor = conn.cursor() + + if dj_is_unsure: + + user_input = input("nice playlist? [y to proceed, anything else to suggest new] :") + + if user_input == 'y': + print("action") + create_episode_playlist(conn, episode_playlist, episode_number) + elif user_input == 'p': + # preview a track -------------------------------------- + preview_track = input("which track would you like to preview [0-12]:") + cursor.execute('SELECT path FROM EPISODES WHERE EPISODE=? AND track_number=?', [episode_number, preview_track ]) + preview_track_path = cursor.fetchone()[0] + print(preview_track_path) + #os.system("mplayer '{0}' &".format(preview_track_path)) + subprocess.Popen(["nohup mplayer '{0}' &".format(preview_track_path)], shell=True) + #Popen.run("mplayer '{0}' &".format(preview_track_path)) + track_previewed = input("track OK? :") + if track_previewed == 'y': + print("ok groovy choice then...") + else: + input("do the db replace logic") + playlist_replace_track(conn, episode_playlist, episode_number, preview_track) + + + else: + print("Goodbye happy dj") + + + return user_input + + + + +def modify_playlist(conn, episode_playlist, episode_number): + + cursor = conn.cursor() + cursor.execute('SELECT * FROM EPISODES WHERE EPISODE=?', [episode_number]) + preview = cursor.fetchall() + for i in preview: + print('{0} : {1} {2} {3} {4} \n'.format(i[2], i[4], i[5], i[6], i[7],)) + # episode_duration = timedelta(seconds=round(episode_duration)) + # print("Total Tracks = {0} \nTotal Duration = {1}".format(track_count, episode_duration)) - return episode_playlist, episode_duration def combine_images(columns, space, images, variants:int): global show_cover @@ -227,8 +327,9 @@ def combine_images(columns, space, images, variants:int): im.text((1540,1888), ''' http://{0}.rizom.si '''\ .format(show_name, episode_date,episode_number), fill="white", font=mf_h4) - show_cover = 'img/cover.png'.format(episode_number,episode_date, variants) + show_cover = 'img/cover{2}.png'.format(episode_number,episode_date, variants) background.save("html/" + "episode/{0}/{1}".format(episode_number, show_cover)) + #convert -delay 100 -loop 0 html/episode/2/img/show_cover_2024-01-12* animatedGIF.gif return show_cover def create_show_coverart(episode_playlist, variants): @@ -276,10 +377,6 @@ def create_animated_gif(): img.save(fp=fp_out, format='GIF', append_images=imgs, save_all=True, duration=200, loop=0) -def create_pls_file(): - # write the selection as a playlist file - with open("shows/antena_playlist_" + episode_date + ".pls","w") as file: - file.writelines("\n".join(episode_playlist)) def create_podcast(episode_playlist: list): @@ -396,7 +493,8 @@ def create_html_homepage_from_template(episode_playlist): episodes.append(an_episode) episodes = reversed(episodes[1:episode_number]) # reversed order to most recent episode appears first in list - + + cursor = conn.cursor() cursor.execute('SELECT * FROM EPISODES WHERE episode=?', [episode_number]) r = cursor.fetchall() @@ -404,24 +502,25 @@ def create_html_homepage_from_template(episode_playlist): for t in r: song = str(t[0]) #track_label = str(t[1]) - track_album = str(t[2]) - track_title = str(t[3]) - track_artist = str(t[4]) - track_duration = float(t[6]) - track_genre = str(t[7]) - track_year = str(t[8]) + track_number = str(t[2]) + track_album = str(t[3]) + track_title = str(t[4]) + track_artist = str(t[5]) + track_duration = float(t[7]) + track_genre = str(t[8]) + track_year = str(t[9]) detail = str(track_artist) + " | " + str(track_album) + \ " | " + str(track_title) + " | " + str(track_year) + \ " | " + str(timedelta(seconds=round(track_duration))) show_info.append("" + detail) - + #TODO remove single quptes not working in episode_artists output_from_parsed_template = homepage_template.render(\ show_name=''.join(random.choice((str.upper,str.lower))(x) for x in show_name), \ episodes=episodes, episode_author="Rob Canning",\ episode_duration=episode_duration, episode_number=episode_number, \ - episode_artists=episode_artists[episode_number], \ - about_show=show_short_description, episode_playlist=show_info, \ + episode_artists=str(episode_artists[episode_number]).strip("[").strip("]").strip("\'").strip("'"), \ + about_show=show_short_description, episode_playlist=episode_playlist, \ episode_image="episode/{0}/img/cover.png".format(episode_number)) with open("html/index.html".format(episode_number), "w") as episode_page: @@ -441,35 +540,35 @@ def create_html_episode_from_template(episode_playlist, episode_number): # maybe a jinja2 template loop here instead cursor = conn.cursor() - e = Table('EPISODES') + e = Table('episodes') q = Query.from_(e).select( e.episode ).where( e.episode == episode_number) # raw 'SELECT * FROM EPISODES WHERE EPISODE=?', [episode_number] cursor.execute('SELECT * FROM EPISODES WHERE EPISODE=?', [episode_number]) + #cursor.execute(str(q)) r = cursor.fetchall() for t in r: song = str(t[0]) - track_album = str(t[3]) - track_title = str(t[4]) - track_artist = str(t[5]).upper() - track_duration = float(t[6]) - track_genre = str(t[7]) - track_year = str(t[8]) - track_label = str(t[10]) - track_comment = str(t[11]) + track_number = str(t[2]) + track_album = str(t[4]) + track_title = str(t[5]) + track_artist = str(t[6]).upper() + track_duration = float(t[7]) + track_genre = str(t[8]) + track_year = str(t[9]) + track_label = str(t[11]) + track_comment = str(t[12]) detail = str(track_artist) + " | " + str(track_album) + \ " | " + str(track_title) + " | " + str(track_year) + \ " | " + str(timedelta(seconds=round(track_duration))) - playlist_entry = [track_title, track_artist, track_album, track_year, timedelta(seconds=round(track_duration)), track_label.upper() ] + playlist_entry = [track_number, track_title, track_artist, track_album, track_year, timedelta(seconds=round(track_duration)), track_label.upper() ] playlist_table.append(playlist_entry) show_info.append("" + detail) - #TODO FIX THIS UP TO SEND COLUMNS FROM LIST TO JINJA - output_from_parsed_template = episode_template.render(\ show_name=show_name, episode_author="Rob Canning",\ episode_number=episode_number, episode_duration=episode_duration, \ @@ -487,39 +586,43 @@ def create_RSS_XML_from_template(): env = Environment(loader=FileSystemLoader('html/templates')) rss_template = env.get_template('show_RSS.jinja.xml') - output_from_parsed_template = rss_template.render(\ - show_name=show_name, \ - episode_number=int(episode_number), episode_author="Rob Canning",\ - episode_duration=episode_duration, about_show=show_short_description, \ - episode_image="img/cover.png".format(episode_number)) + output_from_parsed_template = \ + rss_template.render(\ + show_name=show_name, \ + episode_number=int(episode_number), episode_author="Rob Canning",\ + episode_duration=episode_duration, about_show=show_short_description, \ + episode_image="img/cover.png".format(episode_number)) with open("html/show_rss.xml".format(episode_number), "w") as rss_page: rss_page.write(output_from_parsed_template) - def main(): -# database_create_episodes_table() set_episode_date(input_date) + + # while create_episode_playlist(conn, episode_playlist, episode_number) != 'y': + # create_episode_playlist(conn, episode_playlist, episode_number) + create_episode_playlist(conn, episode_playlist, episode_number) - create_show_coverart(episode_playlist, 1) #episode_duration = 100 + + + + + + + +# modify_playlist(conn, episode_playlist, episode_number) + + + create_show_coverart(episode_playlist, 4) #episode_duration = 100 #create_animated_gif() create_intro(episode_playlist) - create_pls_file() create_html_episode_from_template(episode_playlist, episode_number) create_html_homepage_from_template(episode_playlist) create_RSS_XML_from_template() conn.close() create_podcast(episode_playlist) - - - - main() - - - - -#convert -delay 100 -loop 0 html/episode/2/img/show_cover_2024-01-12* animatedGIF.gif +# diff --git a/playlists/track_playout_history.txt b/playlists/track_playout_history.txt deleted file mode 100644 index 97e813f..0000000 --- a/playlists/track_playout_history.txt +++ /dev/null @@ -1,13 +0,0 @@ - -YuWrong -Action XIV -things i decided against -Domen Gnezda - Misnomer II - 02 Misnomer 24 -Crushing Trauma -Nicholas Cage -The Great White Buffalo -Integral [Excerpt] -Slika 4 -Tomaž Grom - Sam, za... - 05 G.V. -Styröfoam - Moonmiles -The Oppressed 1 (Outtake)