88import time
99import argparse
1010import math
11- import pickle
1211import configparser
1312from enum import Enum
1413from tempfile import NamedTemporaryFile
4443LOADING_IMAGE = "loading.png"
4544BUTTON_BACK_IMAGE = "button_back.png"
4645BUTTON_NEXT_IMAGE = "button_next.png"
46+ BUTTON_NEW_IMAGE = "button_new.png"
4747
4848# Asset Paths
4949IMAGES_PATH = os .path .dirname (sys .argv [0 ]) + "images/"
@@ -167,10 +167,9 @@ def __init__(self, rotation=0):
167167 self .rotation = rotation
168168 self .images = {}
169169 self .fonts = {}
170+ self .buttons = {}
170171 self .width = 0
171172 self .height = 0
172- self .back_button = None
173- self .next_button = None
174173 self .textarea = None
175174 self .screen = None
176175 self .saved_screen = None
@@ -224,23 +223,44 @@ def start(self):
224223 # Add buttons
225224 back_button_image = pygame .image .load (IMAGES_PATH + BUTTON_BACK_IMAGE )
226225 next_button_image = pygame .image .load (IMAGES_PATH + BUTTON_NEXT_IMAGE )
226+ new_button_image = pygame .image .load (IMAGES_PATH + BUTTON_NEW_IMAGE )
227227 button_spacing = (
228- self .width - (back_button_image .get_width () + next_button_image .get_width ())
229- ) // 3
228+ self .width
229+ - (
230+ back_button_image .get_width ()
231+ + next_button_image .get_width ()
232+ + new_button_image .get_width ()
233+ )
234+ ) // 4
230235 button_ypos = (
231236 self .height
232237 - PAGE_NAV_HEIGHT
233238 + (PAGE_NAV_HEIGHT - next_button_image .get_height ()) // 2
234239 )
235- self .back_button = Button (
240+
241+ self ._load_button (
242+ "back" ,
236243 button_spacing ,
237244 button_ypos ,
238245 back_button_image ,
239246 self .previous_page ,
240247 self ._display_surface ,
241248 )
242- self .next_button = Button (
243- self .width - button_spacing - next_button_image .get_width (),
249+
250+ self ._load_button (
251+ "new" ,
252+ button_spacing * 2 + back_button_image .get_width (),
253+ button_ypos ,
254+ new_button_image ,
255+ self .new_story ,
256+ self ._display_surface ,
257+ )
258+
259+ self ._load_button (
260+ "next" ,
261+ button_spacing * 3
262+ + back_button_image .get_width ()
263+ + new_button_image .get_width (),
244264 button_ypos ,
245265 next_button_image ,
246266 self .next_page ,
@@ -255,8 +275,6 @@ def start(self):
255275 self .height - PAGE_NAV_HEIGHT - PAGE_TOP_MARGIN - PAGE_BOTTOM_MARGIN ,
256276 )
257277
258- self .load_settings ()
259-
260278 # Start the sleep check thread after everything is initialized
261279 self ._sleep_check_thread = threading .Thread (target = self ._handle_sleep )
262280 self ._sleep_check_thread .start ()
@@ -309,7 +327,7 @@ def _handle_mousedown_event(self, event):
309327 if event .button == 1 :
310328 # If button pressed while visible, trigger action
311329 coords = self ._rotate_mouse_pos (event .pos )
312- for button in [ self .back_button , self . next_button ] :
330+ for button in self .buttons . values () :
313331 if button .visible and button .is_in_bounds (coords ):
314332 button .action ()
315333
@@ -334,6 +352,9 @@ def _load_image(self, name, filename):
334352 except pygame .error :
335353 pass
336354
355+ def _load_button (self , name , x , y , image , action , display_surface ):
356+ self .buttons [name ] = Button (x , y , image , action , display_surface )
357+
337358 def _load_font (self , name , details ):
338359 self .fonts [name ] = pygame .font .Font (details [0 ], details [1 ])
339360
@@ -369,6 +390,7 @@ def display_current_page(self):
369390 self ._display_surface (self .images ["background" ], 0 , 0 )
370391 pygame .display .update ()
371392
393+ print (f"Loading page { self .page } of { len (self .pages )} " )
372394 page_data = self .pages [self .page ]
373395
374396 # Display the title
@@ -385,8 +407,9 @@ def display_current_page(self):
385407
386408 # Display the navigation buttons
387409 if self .page > 0 or self .story > 0 :
388- self .back_button .show ()
389- self .next_button .show ()
410+ self .buttons ["back" ].show ()
411+ self .buttons ["next" ].show ()
412+ self .buttons ["new" ].show ()
390413 pygame .display .update ()
391414 self ._busy = False
392415
@@ -463,7 +486,11 @@ def next_page(self):
463486 self .load_story (self .stories [self .story ])
464487 self .page = 0
465488 else :
466- self .new_story ()
489+ self .generate_new_story ()
490+ self .display_current_page ()
491+
492+ def new_story (self ):
493+ self .generate_new_story ()
467494 self .display_current_page ()
468495
469496 def display_loading (self ):
@@ -485,10 +512,13 @@ def load_story(self, story):
485512 # Parse out the title and story and render into pages
486513 self ._busy = True
487514 self .pages = []
488- title = story .split ("Title: " )[1 ].split ("\n \n " )[0 ]
515+ if not story .startswith ("Title: " ):
516+ print ("Unexpected story format from ChatGPT. Missing Title." )
517+ title = "A Story"
518+ else :
519+ title = story .split ("Title: " )[1 ].split ("\n \n " )[0 ]
489520 page = self ._add_page (title )
490521 paragraphs = story .split ("\n \n " )[1 :]
491- paragraphs .append ("The End." )
492522 for paragraph in paragraphs :
493523 lines = self ._wrap_text (paragraph , self .fonts ["text" ], self .textarea .width )
494524 for line in lines :
@@ -524,47 +554,9 @@ def _add_page(self, title=None):
524554 self .pages .append (page )
525555 return page
526556
527- def load_settings (self ):
528- storydata = {
529- "history" : [],
530- "settings" : {
531- "story" : 0 ,
532- "page" : 0 ,
533- },
534- }
535- # Load the story data if it exists
536- if os .path .exists (os .path .dirname (sys .argv [0 ]) + "storydata.bin" ):
537- print ("Loading previous story data" )
538- with open (os .path .dirname (sys .argv [0 ]) + "storydata.bin" , "rb" ) as f :
539- storydata = pickle .load (f )
540- self .stories = storydata ["history" ]
541- self .story = storydata ["settings" ]["story" ]
542-
543- if storydata ["history" ] and storydata ["settings" ]["story" ] < len (
544- storydata ["history" ]
545- ):
546- # Load the last story
547- self .load_story (storydata ["history" ][storydata ["settings" ]["story" ]])
548- self .page = storydata ["settings" ]["page" ]
549- # If something changed and caused the current page to be too
550- # large, just go to the last page of the story
551- if self .page >= len (self .pages ):
552- self .page = len (self .pages ) - 1
553-
554- def save_settings (self ):
555- storydata = {
556- "history" : self .stories ,
557- "settings" : {
558- "story" : self .story ,
559- "page" : self .page ,
560- },
561- }
562- with open (os .path .dirname (sys .argv [0 ]) + "storydata.bin" , "wb" ) as f :
563- pickle .dump (storydata , f )
564-
565- def new_story (self ):
557+ def generate_new_story (self ):
566558 self ._busy = True
567- self .display_message ("What story would you like to hear today? " )
559+ self .display_message ("Speak aloud the story you wish to read. " )
568560
569561 if self ._sleep_request :
570562 self ._busy = False
@@ -604,10 +596,9 @@ def show_waiting():
604596 self .stories .append (response )
605597 self .story = len (self .stories ) - 1
606598 self .page = 0
607- self .save_settings ()
599+ self ._busy = False
608600
609601 self .load_story (response )
610- self ._busy = False
611602
612603 def _sleep (self ):
613604 # Set a sleep request flag so that any busy threads know to finish up
@@ -699,19 +690,14 @@ def main(args):
699690 book = Book (args .rotation )
700691 try :
701692 book .start ()
702-
703- # If no stories, start a new one
704- if not book .stories :
705- book .new_story ()
706-
693+ book .generate_new_story ()
707694 book .display_current_page ()
708695
709696 while True :
710697 book .handle_events ()
711698 except KeyboardInterrupt :
712699 pass
713700 finally :
714- book .save_settings ()
715701 book .deinit ()
716702 pygame .quit ()
717703
@@ -721,4 +707,4 @@ def main(args):
721707
722708# TODO:
723709# * Figure out how to get the script to start on boot
724- # * Play with prompt parameters
710+ # * Play with chatgpt prompt parameters
0 commit comments