Skip to content

Commit f130cab

Browse files
authored
v1.1 update
1 parent 12ed949 commit f130cab

File tree

3 files changed

+139
-67
lines changed

3 files changed

+139
-67
lines changed

main.py

+133-66
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@
66
import tkinter
77
import time
88
import datetime
9-
#from PIL import Image
9+
from PIL import Image
1010

1111
# thumbnail image functions
12-
'''
12+
1313
def makeThumbnail(imagepath):
14-
IM=Image.open(imagepath)
15-
print(IM.size)
16-
'''
14+
app.debug(f'making thumbnail for {imagepath}')
15+
try:
16+
IM=Image.open(imagepath)
17+
IM = IM.resize((150,150))
18+
thumbnailpath =f'{imagepath[:-4]}_thumbnail.gif'
19+
IM.save(thumbnailpath)
20+
del IM
21+
return thumbnailpath
22+
except Exception as e:
23+
app.error(f'error making thumbnail: {e}')
24+
return 'no_image.gif'
25+
1726
# misc functions
1827

1928
def reorderLibrary():
@@ -60,8 +69,13 @@ def milliFormat(milliseconds,subtractH=True):
6069
# player functions
6170

6271
def closePlayerWindow():
63-
vlcPlayer.set_pause(1)
64-
updateLeftoffTime()
72+
try:
73+
state = str(vlcPlayer.get_state()).lower().replace('state.','')
74+
if state == 'playing' or state == 'paused':
75+
vlcPlayer.set_pause(1)
76+
updateLeftoffTime()
77+
except:
78+
pass
6579
return True
6680

6781
def updateLeftoffTime():
@@ -143,7 +157,7 @@ def queueClick(name):
143157
fullfilename = f'{directory}/{filename}'
144158
playFile(fullfilename)
145159
library[currentlyPlaying]['leftoff']['file'] = filename
146-
app.setLabel('player_current_playing_title',' '.join(app.getListBox("list_queue")))
160+
app.setLabel('player_current_playing_title',cropText(' '.join(app.getListBox("list_queue")),cropnum=17))
147161
app.setLabel('player_author',library[currentlyPlaying]['author'])
148162
app.setLabel('player_name',library[currentlyPlaying]['name'])
149163

@@ -167,17 +181,34 @@ def preparePlayer(entry):
167181
app.showSubWindow('window_player')
168182

169183

184+
def rateScaleHandler():
185+
settings = {1:0.3, 2:0.50, 3:0.8, 4:0.9, 5:1.0, 6:1.1, 7:1.20, 8:1.50, 9:1.80, 10:2.0}
186+
currate = app.getScale('scale_player_rate')
187+
setting = int(round(currate))
188+
newrate = settings[setting]
189+
app.setScale('scale_player_rate',setting,callFunction=False)
190+
try:
191+
vlcPlayer.set_rate(newrate)
192+
except BaseException as e:
193+
app.warn(f'cannot change playback rate: {e}')
194+
195+
def volumeScaleHandler():
196+
vlc.audio_set_volume(app.getScale('scale_player_volume'))
197+
170198

171199
def playerButtons(name):
200+
state = str(vlcPlayer.get_state()).lower().replace('state.','')
172201
if name == 'btn_player_play':
173-
vlcPlayer.play()
174-
app.hideButton('btn_player_play')
175-
app.showButton('btn_player_pause')
202+
if state == 'paused':
203+
vlcPlayer.set_pause(0)
204+
app.hideButton('btn_player_play')
205+
app.showButton('btn_player_pause')
176206
elif name == 'btn_player_pause':
177-
updateLeftoffTime()
178-
vlcPlayer.set_pause(1)
179-
app.showButton('btn_player_play')
180-
app.hideButton('btn_player_pause')
207+
if state == 'playing':
208+
updateLeftoffTime()
209+
vlcPlayer.set_pause(1)
210+
app.showButton('btn_player_play')
211+
app.hideButton('btn_player_pause')
181212
elif name == 'btn_player_fastforward':
182213
vlcPlayer.set_time(vlcPlayer.get_time()+30000)
183214
elif name == 'btn_player_fastbackbackward':
@@ -186,6 +217,10 @@ def playerButtons(name):
186217
nextFile()
187218
elif name == 'btn_player_previous':
188219
previousFile()
220+
elif name == 'btn_player_resetvolume':
221+
app.setScale('scale_player_volume',100,callFunction=True)
222+
elif name == 'btn_player_resetrate':
223+
app.setScale('scale_player_rate',5,callFunction=True)
189224

190225
# external file loading stuff
191226

@@ -299,8 +334,20 @@ def toolbarButtons(name):
299334
sortLibraryEntries()
300335
elif name == 'radio_color':
301336
changeColorScheme(app.getMenuRadioButton('Color scheme','radio_color'))
337+
elif name == 'Clear library':
338+
if app.yesNoBox('Confirm library deletion','Are you sure you want to clear the library? This will remove all your entries & forget their timestamps.\nNote: this will NOT remove the files themselves, you can always re-add the entries.'):
339+
try:
340+
global library
341+
app.info('clearing library')
342+
os.remove('library.json')
343+
library = {}
344+
sortLibraryEntries()
345+
app.infoBox('Clear completed','Library has been cleared.')
346+
except Exception as e:
347+
app.error(f'error deleting library.json: {e}')
348+
app.warningBox(f'Error','Error clearing library: {e}')
302349
elif name == 'About':
303-
app.infoBox('About',f'Pycasts version {version} (build {buildDate})\nMade by Anne mocha (@mocchapi) for Lilli snaog :>\nFollow development at https://github.com/mocchapi/PyCasts')
350+
app.infoBox('About',f'Version {version} - build {buildDate}\n\nPyCasts is an podcast/audiobook player made by Anne mocha (@mocchapi) for Lilli snaog :>\n\nFollow development at https://github.com/mocchapi/PyCasts')
304351

305352
def newLibButtons(name):
306353
if name == 'btn_newLib_cancel':
@@ -323,10 +370,11 @@ def newLibButtons(name):
323370
thumbnail = 'no_image.gif'
324371
else:
325372
thumbnail = entries['entry_newLib_thumbnail']
326-
if os.path.isfile(thumbnail) and thumbnail.endswith('.gif'):
327-
tempdict['thumbnail'] = thumbnail
373+
if os.path.isfile(thumbnail):
374+
generatedThumb = makeThumbnail(thumbnail)
375+
tempdict['thumbnail'] = generatedThumb
328376
else:
329-
app.warningBox('Invalid file','The entered file is invalid.\nMust be an image of type .gif @ 150x150.\nThis entry can be left blank.')
377+
app.warningBox('Invalid thumbnail file','The entered thumbnail file is invalid.\nThis entry can be left blank.')
330378
return
331379
tempdict['leftoff'] = {'file':None,'time':0}
332380
global library
@@ -397,11 +445,11 @@ def editEntry(entry):
397445
thumbnail = 'no_image.gif'
398446
else:
399447
thumbnail = entries['entry_editLib_thumbnail']
400-
if os.path.isfile(thumbnail) and thumbnail.endswith('.gif'):
401-
tempdict['thumbnail'] = thumbnail
448+
if os.path.isfile(thumbnail):
449+
generatedThumb = makeThumbnail(thumbnail)
450+
tempdict['thumbnail'] = generatedThumb
402451
else:
403-
app.warningBox('Invalid file','The entered thumbnail is invalid.\nMust be an image of type .gif @ 150x150.\nThis entry can be left blank.')
404-
return
452+
app.warningBox('Invalid thumbnail file','The entered thumbnail file is invalid.\nThis entry can be left blank.')
405453
tempdict['leftoff'] = {'file':None,'time':0}
406454
global library
407455
tempdict['leftoff'] = library[entry]['leftoff']
@@ -422,42 +470,46 @@ def removeEntry(name):
422470
app.error(f'couldnt remove entry {name}: {e}')
423471

424472
def buildEntry(entrydict):
425-
app.debug(f'building entry {entrydict["name"]}')
426-
global libraryX
427-
global libraryY
428-
name = entrydict['name']
429-
author = entrydict['author']
430-
thumbnail = entrydict['thumbnail']
431-
directory = entrydict['directory']
432-
433-
app.openScrollPane('frame_libraryView')
434-
app.startLabelFrame(f'libraryEntry_frame_{name}',libraryY,libraryX,label='')
435-
app.setSticky('n')
436-
app.setStretch('column')
437-
app.addImage(f'libraryEntry_thumbnail_{name}',thumbnail)
438-
try:
439-
app.setImageSize(f'libraryEntry_thumbnail_{name}',150,150)
440-
except:
441-
pass
442-
#app.setImageMouseOver(f'libraryEntry_thumbnail_{name}','play_button.gif')
443473
try:
444-
app.createRightClickMenu(f'libraryEntry_rClick_{name}')
445-
app.addMenuItem(f'libraryEntry_rClick_{name}',f'Edit {name}',editEntryButton)
446-
app.addMenuItem(f'libraryEntry_rClick_{name}',f'Remove {name}',removeEntryButton)
447-
except:
448-
pass
449-
app.setImageRightClick(f'libraryEntry_thumbnail_{name}',f'libraryEntry_rClick_{name}')
450-
app.setImageSubmitFunction(f'libraryEntry_thumbnail_{name}',libraryButton)
451-
app.setImagePadding(f'libraryEntry_thumbnail_{name}',[20,20])
452-
app.addLabel(f'libraryEntry_name_{name}',cropText(name,cropnum=30))
453-
app.addLabel(f'libraryEntry_author_{name}',cropText(author,cropnum=30))
454-
app.stopLabelFrame()
455-
app.stopScrollPane()
456-
if libraryX < 4:
457-
libraryX+=1
458-
else:
459-
libraryX=0
460-
libraryY+=1
474+
app.debug(f'building entry {entrydict["name"]}')
475+
global libraryX
476+
global libraryY
477+
name = entrydict['name']
478+
author = entrydict['author']
479+
thumbnail = entrydict['thumbnail']
480+
directory = entrydict['directory']
481+
482+
app.openScrollPane('frame_libraryView')
483+
app.startLabelFrame(f'libraryEntry_frame_{name}',libraryY,libraryX,label='')
484+
app.setSticky('n')
485+
app.setStretch('column')
486+
app.addImage(f'libraryEntry_thumbnail_{name}',thumbnail)
487+
try:
488+
app.setImageSize(f'libraryEntry_thumbnail_{name}',150,150)
489+
except:
490+
pass
491+
#app.setImageMouseOver(f'libraryEntry_thumbnail_{name}','play_button.gif')
492+
try:
493+
app.createRightClickMenu(f'libraryEntry_rClick_{name}')
494+
app.addMenuItem(f'libraryEntry_rClick_{name}',f'Edit {name}',editEntryButton)
495+
app.addMenuItem(f'libraryEntry_rClick_{name}',f'Remove {name}',removeEntryButton)
496+
except:
497+
pass
498+
app.setImageRightClick(f'libraryEntry_thumbnail_{name}',f'libraryEntry_rClick_{name}')
499+
app.setImageSubmitFunction(f'libraryEntry_thumbnail_{name}',libraryButton)
500+
app.setImagePadding(f'libraryEntry_thumbnail_{name}',[20,20])
501+
app.addLabel(f'libraryEntry_name_{name}',cropText(name,cropnum=30))
502+
app.addLabel(f'libraryEntry_author_{name}',cropText(author,cropnum=30))
503+
app.stopLabelFrame()
504+
app.stopScrollPane()
505+
if libraryX < 4:
506+
libraryX+=1
507+
else:
508+
libraryX=0
509+
libraryY+=1
510+
except Exception as e:
511+
app.error(f'could not build entry {entrydict["name"]}: {e}')
512+
app.warningBox('Library error',f'could not build entry {entrydict["name"]}: {e}')
461513

462514
def mainUI():
463515
app.setFont(size=15, family="Open Sans")
@@ -471,14 +523,14 @@ def mainUI():
471523
app.stopScrollPane()
472524
app.stopLabelFrame()
473525

474-
app.addMenuList('Library',['Add new entry','Sort library'],toolbarButtons)
526+
app.addMenuList('Library',['Add new entry','Sort library','Clear library'],toolbarButtons)
475527
app.addMenuList('View',['About','Open player'],toolbarButtons)
476528
app.addSubMenu('View','Ttk theme')
477529

478530

479531

480532
def playerUI():
481-
app.startSubWindow('window_player','Player',transient=False,modal=False)
533+
app.startSubWindow('window_player','PyCasts Player',transient=False,modal=False)
482534
app.setStopFunction(closePlayerWindow)
483535
app.setFont(size=12, family="Open Sans")
484536
app.setSize(600, 350)
@@ -533,7 +585,7 @@ def playerUI():
533585
app.setStretch('column')
534586
app.setSticky('nesw')
535587
app.addScale('scale_player_timeline',0,0)
536-
app.setScaleRange('scale_player_timeline',0,10000)
588+
app.setScaleRange('scale_player_timeline',0,10000 )
537589
app.setScaleChangeFunction('scale_player_timeline',timelineScrub)
538590
app.setScaleIncrement('scale_player_timeline',0)
539591
app.startFrame('frame_player_buttons',1,0,2)
@@ -546,7 +598,22 @@ def playerUI():
546598
app.hideButton('btn_player_pause')
547599
app.addIconButton('btn_player_fastforward',playerButtons,'md-fast-forward',1,3)
548600
app.addIconButton('btn_player_next',playerButtons,'md-next',1,4)
601+
602+
app.startFrame('frame_player_buttons2',2,0,4)
603+
app.setStretch('column')
604+
app.setSticky('nsw')
605+
app.addIconButton('btn_player_resetvolume',playerButtons,'md-volume-3',0,0)
606+
app.addScale('scale_player_volume',0,1)
607+
app.setSticky('nse')
608+
app.addIconButton('btn_player_resetrate',playerButtons,'time',0,3)
609+
app.addScale('scale_player_rate',0,4)
610+
app.setScaleChangeFunction('scale_player_rate',rateScaleHandler)
611+
app.setScaleRange('scale_player_volume',1,200)
612+
app.setScaleRange('scale_player_rate',1,10)
613+
app.setScale('scale_player_volume',100,callFunction=False)
614+
app.setScale('scale_player_rate',5,callFunction=False)
549615
app.stopFrame()
616+
app.stopFrame()
550617
app.stopFrame()
551618
app.stopSubWindow()
552619

@@ -567,7 +634,7 @@ def newLibUI():
567634
app.setStretch('none')
568635
app.addLabel('lbl_newLib_name','Name',3,1)
569636
app.addLabel('lbl_newLib_author','Author(s)',6,1)
570-
app.addLabel('lbl_newLib_directory','Podcast folder ',9,1)
637+
app.addLabel('lbl_newLib_directory','Audio folder ',9,1)
571638
app.addLabel('lbl_newLib_thumbnail','Thumbnail (optional) ',12,1)
572639
app.stopLabelFrame()
573640
app.setSticky('esw')
@@ -593,7 +660,7 @@ def editLibUI():
593660
app.setStretch('none')
594661
app.addLabel('lbl_editLib_name','Name',3,1)
595662
app.addLabel('lbl_editLib_author','Author(s)',6,1)
596-
app.addLabel('lbl_editLib_directory','Podcast folder ',9,1)
663+
app.addLabel('lbl_editLib_directory','Audio folder ',9,1)
597664
app.addLabel('lbl_editLib_thumbnail','Thumbnail (optional) ',12,1)
598665
app.stopLabelFrame()
599666
app.setSticky('esw')
@@ -615,8 +682,8 @@ def setup():
615682
app.setStopFunction(stopFunction)
616683

617684
if __name__ == '__main__':
618-
version = '1.0.0'
619-
buildDate = '24/5/2020'
685+
version = '1.1.0'
686+
buildDate = '15/6/2020'
620687
# very first things, init of appjar & basic global settings, stage 0
621688
starttime = time.time()
622689
app = gui('PyCasts library','10x10',useTtk=True,startWindow=None)
@@ -647,7 +714,7 @@ def setup():
647714
except BaseException as e:
648715
app.critical(f'error creating vlc instance: {e}')
649716
app.critical(f'cannot continue')
650-
app.warningBox('critical error','')
717+
app.warningBox('critical error',f'error creating vlc instance: "{e}"\nIs VLC media player installed?')
651718
exit()
652719
app.thread(saveTimeAndFile)
653720
app.registerEvent(updatePlayerInfo)

requirements-nonlinux.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
python-vlc
2+
appJar
3+
ttkthemes
4+
tkinter
5+
Pillow

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
python-vlc
22
appJar
33
ttkthemes
4-
tkinter
4+
Pillow

0 commit comments

Comments
 (0)