uho/mk_show.py

326 lines
12 KiB
Python
Raw Normal View History

#!/usr/bin/python3
2024-01-14 02:56:15 +01:00
import sys, os, datetime, fnmatch, glob, random, time, pathlib, re
from datetime import timedelta
2024-01-11 00:20:43 +01:00
from os.path import join
from tinytag import TinyTag
2024-01-11 00:20:43 +01:00
2024-01-07 03:07:30 +01:00
from random import shuffle
2024-01-14 02:56:15 +01:00
import sqlite3
from mk_web import *
con = sqlite3.connect("music.db")
DATE = datetime.datetime.now().strftime("%Y-%m-%d")
2024-01-14 02:56:15 +01:00
total_show_dur = 0
2024-01-08 18:01:22 +01:00
complete_playlist = []
show_array = []
2024-01-11 00:20:43 +01:00
show_cover = ""
2024-01-08 02:06:18 +01:00
archive = []
2024-01-14 02:56:15 +01:00
artists_played = []
2024-01-11 00:20:43 +01:00
artist_abreviated = []
2024-01-14 02:56:15 +01:00
episode_number = sys.argv[1]
2024-01-14 02:56:15 +01:00
show_name = "SHOWNAME" # OBED
2024-01-08 18:01:22 +01:00
path = "/home/rob/antena/"
2024-01-14 02:56:15 +01:00
web_path = "/home/rob/antena/html/episode/{0}/img".format(episode_number)
if os.path.exists(web_path):
print("path_exists_doing_nothing")
else: os.makedirs(web_path)
2024-01-08 18:01:22 +01:00
# /////////////////////////////////////////////////
2024-01-08 18:01:22 +01:00
def create_intro(show_array):
intropath = path + "texts/clips/this_is"
2024-01-08 02:06:18 +01:00
intro = random.choice(os.listdir(intropath))
2024-01-08 18:01:22 +01:00
show_array.insert(0, str(os.path.abspath(intropath)) + "/" + str(intro))
2024-01-08 02:06:18 +01:00
def add_to_tracks_played(add_to_played: str):
2024-01-11 00:20:43 +01:00
with open('playlists/track_playout_history.txt', "a") as tracks_played_file:
2024-01-14 02:56:15 +01:00
tracks_played_file.write(str(add_to_played) + "\n") # newline \n needed here?
2024-01-08 02:06:18 +01:00
2024-01-08 18:01:22 +01:00
def check_archive(track):
2024-01-08 02:06:18 +01:00
global archive
2024-01-11 00:20:43 +01:00
with open('playlists/track_playout_history.txt') as archive_file:
2024-01-08 02:06:18 +01:00
for line in archive_file:
archive.append(line)
2024-01-08 18:01:22 +01:00
if track not in archive:
print("____ TRACK NOT YET PLAYED ... ADDING _____")
return True
else:
print("____ TRACK ALREADY PLAYED _____")
return False
def load_all_music():
2024-01-11 00:20:43 +01:00
with open('playlists/complete_music_archive.pls') as playlist_file:
2024-01-08 18:01:22 +01:00
for line in playlist_file:
complete_playlist.append(line)
2024-01-14 02:56:15 +01:00
print('''
-------------------------------
loaded {0} tracks from playlist
-------------------------------
'''.format(str(len(complete_playlist))))
2024-01-08 18:01:22 +01:00
return complete_playlist
def create_show_playlist(show_array: list, complete_playlist:list):
load_all_music()
2024-01-14 02:56:15 +01:00
global total_show_dur
2024-01-08 02:06:18 +01:00
global archive
track_count = 0
2024-01-14 02:56:15 +01:00
global artists_played
max_track_dur = 10
min_track_dur = 1.8
2024-01-07 03:07:30 +01:00
2024-01-14 02:56:15 +01:00
while total_show_dur < 60 * 60 and track_count < 12 :
2024-01-08 18:01:22 +01:00
song = random.choice(random.sample(\
complete_playlist, len(complete_playlist) )).rstrip() # pick a song
2024-01-08 02:06:18 +01:00
track = TinyTag.get(song) # get its metadata
# check if the artist not in the played list and the song is less than 8mins
2024-01-14 02:56:15 +01:00
if track.artist not in artists_played:
2024-01-08 18:01:22 +01:00
if check_archive(track.title) is True:
if int(track.duration) > min_track_dur * 60:
if int(track.duration) < max_track_dur * 60:
show_array.append(song.rstrip()) # if 'not in' is true then add the song
2024-01-11 00:20:43 +01:00
art = string=re.sub("\(.*?\)","",track.artist)
2024-01-14 02:56:15 +01:00
# shorten verbose artist names such as trojnik Trojnik (Cene Resnik, Tomaž Grom, Vid Drašler)
2024-01-11 00:20:43 +01:00
art = string=re.sub("and","&",art)
2024-01-14 02:56:15 +01:00
artist_abreviated.append(art)
artists_played.append(track.artist) # and add the artist to the played list
2024-01-08 18:01:22 +01:00
add_to_tracks_played(track.title) # and write entry to archive file
2024-01-14 02:56:15 +01:00
track_count += 1; print(track_count)
total_show_dur = total_show_dur + track.duration
2024-01-11 00:20:43 +01:00
else: print("TRACK TOO SHORT..........." )
else: print("TRACK TOO LONG..........." )
else: print("SONG PLAYED IN PREVIOUS EPISODE" )
else: print("ARTIST ALREADY IN PODCAST")
2024-01-08 18:01:22 +01:00
2024-01-14 02:56:15 +01:00
total_show_dur = timedelta(seconds=round(total_show_dur))
print("total tracks = {0} \n total duration = {1} ".format(track_count, total_show_dur))
return show_array, total_show_dur
def combine_images(columns, space, images, variants:int):
global show_cover
2024-01-11 00:20:43 +01:00
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
rows = len(images) // columns
if len(images) % columns:
rows += 1
2024-01-08 02:06:18 +01:00
2024-01-11 00:20:43 +01:00
width_max = 500 #max([Image.open(image).width for image in images])
height_max = 500# max([Image.open(image).height for image in images])
background_width = width_max*columns + (space*columns)-space
background_height = height_max*rows + (space*rows)-space
#background = Image.new('RGBA', (background_width, background_height), (0, 0, 0, 255))
background = Image.new('RGBA', (width_max*columns , height_max*columns), (0, 0, 0, 255))
2024-01-08 18:01:22 +01:00
2024-01-11 00:20:43 +01:00
x = 0
y = 0
for i, image in enumerate(images):
imga = Image.open(image)
size = (500,500)
img = imga.resize(size)
x_offset = int((width_max-img.width)/2)
y_offset = int((height_max-img.height)/2)
background.paste(img, (x+x_offset, y+y_offset+100))
x += width_max + space
if (i+1) % columns == 0:
y += height_max + space
x = 0
im = ImageDraw.Draw(background)
mf_h1 = ImageFont.truetype('fonts/Antonio-Light.ttf', 280)
2024-01-14 02:56:15 +01:00
mf_h2 = ImageFont.truetype('fonts/Antonio-Light.ttf', 65)
2024-01-11 00:20:43 +01:00
mf_h3 = ImageFont.truetype('fonts/Antonio-Regular.ttf', 50)
2024-01-14 02:56:15 +01:00
mf_h4 = ImageFont.truetype('fonts/Antonio-Light.ttf', 50)
2024-01-11 00:20:43 +01:00
h2_spc = 85
h2_baseline = 1530
2024-01-14 02:56:15 +01:00
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
# Add Text to the image ----------------------------------------
# -------------------------------------------------------------------
# some logic to shuffle the list if sub sections of list are too long for layout
str_length_thresh = 50
while \
[len(s) for s in [''.join(artist_abreviated[0:3])]][0] > str_length_thresh or\
[len(s) for s in [''.join(artist_abreviated[3:6])]][0] > str_length_thresh or\
[len(s) for s in [''.join(artist_abreviated[6:9])]][0] > str_length_thresh or \
[len(s) for s in [''.join(artist_abreviated[9:12])]][0] > str_length_thresh:
print("on of the lines is longer than fits the page... shuffling the list for a better look")
random.shuffle(artist_abreviated)
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
im.text((30,10), '''an eclectic selection of contemporary independent music from slovenia: {0} - E P I S O D E #{1}
'''\
.format(DATE,episode_number), fill="white", font=mf_h3)
im.text((30,280), ''' THIS WEEK ON \n EPISODE #{0} of \n {1}!'''.upper()\
.format(episode_number, show_name), fill="white", font=mf_h1, stroke_width=2, stroke_fill='black')
im.text((30, h2_baseline + (h2_spc*1) ), '''m u s i c _ f r o m _ : {0}'''\
.format(' | '.join(artist_abreviated[0:3])), (255,255,255), font=mf_h2)
im.text((30, h2_baseline + (h2_spc*2) ), "{0}"\
.format(' | '.join(artist_abreviated[3:6])), (255,255,255), font=mf_h2)
im.text((30, h2_baseline + (h2_spc*3)), "{0}"\
.format(' | '.join(artist_abreviated[6:9])), (255,255,255), font=mf_h2)
im.text((30, h2_baseline + (h2_spc*4)), "{0}"\
.format(' | '.join(artist_abreviated[9:12])), (255,255,255), font=mf_h2)
im.text((1560,1888), ''' http://{0}.rizom.si '''\
.format(show_name, DATE,episode_number), fill="white", font=mf_h4)
# TiTiTi (Jure Boršič, Jošt Drašler, Vid Drašler)
show_cover = 'img/cover.png'.format(episode_number,DATE, variants)
#pathlib.Path.touch(show_cover)
background.save("html/" + "episode/{0}/{1}".format(episode_number, show_cover))
return show_cover
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
def create_show_coverart(show_array, variants):
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
# global show_array
#print(show_array)
2024-01-11 00:20:43 +01:00
show_cover_jpgs = []
for dir in show_array:
path = pathlib.Path(dir).parent
for file in os.listdir(path):
for i in ["cover", "COVER"]:
if i in file:
show_cover_jpgs.append(str(path) + "/" + file)
2024-01-14 02:56:15 +01:00
#print(file)
# print("\n ++++ show jpgs: +++++ {0} +++++++++number of jpgs: {1} +++++++\n"\
# .format(show_cover_jpgs, len(show_cover_jpgs) ) )
print('''
------------------------
creating show cover art
------------------------
''')
# if len(show_cover_jpgs) > 0: # duplicate this for variations of geometry
for i in range(variants):
x = show_cover_jpgs[:12]
combine_images(columns=4, space=3, images=random.sample(x,len(x)),variants=i)
2024-01-11 00:20:43 +01:00
return show_cover
2024-01-14 02:56:15 +01:00
def create_animated_gif():
import contextlib
from PIL import Image
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
# filepaths
fp_in = "/home/rob/antena/html/episode/2/img/*.png".format(episode_number)
fp_out = "/home/rob/antena/html/episode/2/img/show_cover.gif"
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
# use exit stack to automatically close opened images
with contextlib.ExitStack() as stack:
2024-01-08 18:01:22 +01:00
2024-01-14 02:56:15 +01:00
# lazily load images
imgs = (stack.enter_context(Image.open(f))
for f in sorted(glob.glob(fp_in)))
2024-01-08 18:01:22 +01:00
2024-01-14 02:56:15 +01:00
# extract first image from iterator
img = next(imgs)
2024-01-07 03:07:30 +01:00
2024-01-14 02:56:15 +01:00
# https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
img.save(fp=fp_out, format='GIF', append_images=imgs,
save_all=True, duration=200, loop=0)
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
2024-01-11 00:20:43 +01:00
2024-01-08 18:01:22 +01:00
def create_pls_file():
# write the selection as a playlist file
2024-01-08 02:06:18 +01:00
with open("shows/antena_playlist_" + DATE + ".pls","w") as file:
2024-01-08 18:01:22 +01:00
file.writelines("\n".join(show_array))
def create_podcast(show_array: list):
2024-01-14 02:56:15 +01:00
print('''
------------------------
creating show audio
------------------------
''')
2024-01-08 18:01:22 +01:00
from glob import glob
from pydub import AudioSegment
playlist_songs = [AudioSegment.from_file(flac_file) for flac_file in show_array]
show_intro = playlist_songs.pop(0)
first_song = playlist_songs[0].fade_in(3000)
intro_and_first = first_song.overlay(show_intro)
first_three_blurb = playlist_songs.pop(0)
second_three_blurb = playlist_songs.pop(0)
final_songs_blurb = playlist_songs.pop(0)
final_show_outro = playlist_songs.pop(0)
playlist = intro_and_first
for song in playlist_songs[2:3]: # first three songs (first added with intro)
# We don't want an abrupt stop at the end, so let's do a 1 second crossfades
playlist = playlist.append(song, crossfade=(10 * 1000))
2024-01-08 02:06:18 +01:00
2024-01-08 18:01:22 +01:00
# blurb about first three tracks
playlist = playlist.append(first_three_blurb) # <--------------BLURB INSERT
for song in playlist_songs[4:6]: # second three songs
# We don't want an abrupt stop at the end, so let's do a 1 second crossfades
playlist = playlist.append(song, crossfade=(10 * 1000))
playlist = playlist.append(second_three_blurb) # <--------------BLURB INSERT
2024-01-11 00:20:43 +01:00
for song in playlist_songs[7:]: # second three song # We don't want an abrupt stop at the end, so let's do a 1 second crossfades
2024-01-08 18:01:22 +01:00
playlist = playlist.append(song, crossfade=(10 * 1000))
playlist = playlist.append(final_songs_blurb) # <--------------BLURB INSERT
playlist = playlist.append(final_show_outro) # <-------------- OUTRO SEQUENCE
# get length of final show / podcast
playlist_length = len(playlist) / (1000*60)
# save the entire poidcast
2024-01-14 02:56:15 +01:00
with open("html/episode/{0}/show.flac".format(episode_number), 'wb') as out_f:
2024-01-08 18:01:22 +01:00
playlist.export(out_f, format='flac')
2024-01-11 00:20:43 +01:00
2024-01-14 02:56:15 +01:00
### ------------------------------------------------------------
def create_html_from_template():
from jinja2 import Template, Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('html/templates'))
episode_template = env.get_template('episode.jinja')
output_from_parsed_template = episode_template.render(episode_author="rrrrrrrr", episode_dur="123", about_show="bla bla", episode_playlist="playlist_songs", episode_image="episode/{0}/img/cover.png".format(episode_number))
with open("html/episode.html".format(episode_number), "w") as episode_page:
episode_page.write(output_from_parsed_template)
create_show_playlist(show_array, complete_playlist)
create_show_coverart(show_array, 1) #total_show_dur = 100
#create_animated_gif()
#convert -delay 100 -loop 0 html/episode/2/img/show_cover_2024-01-12* animatedGIF.gif
2024-01-08 18:01:22 +01:00
#create_intro(show_array)
create_pls_file()
2024-01-14 02:56:15 +01:00
create_html_from_template()
#create_web_page(show_name, show_array, episode_number, artists_played, show_cover, total_show_dur)
2024-01-11 00:20:43 +01:00
#create_podcast(show_array)
2024-01-14 02:56:15 +01:00