class PPEditor: # *************************************** # INIT # *************************************** def __init__(self): self.editor_issue = "1.2" # get command options self.command_options = ed_options() # get directory holding the code self.pp_dir = sys.path[0] if not os.path.exists(self.pp_dir + os.sep + "pp_editor.py"): tkMessageBox.showwarning("Pi Presents", "Bad Application Directory") exit() #Initialise logging Monitor.log_path = self.pp_dir self.mon = Monitor() self.mon.on() if self.command_options['debug'] == True: Monitor.global_enable = True else: Monitor.global_enable = False self.mon.log(self, "Pi Presents Editor is starting") self.mon.log(self, " OS and separator " + os.name + ' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: code " + sys.path[0]) # set up the gui #root is the Tkinter root widget self.root = tk.Tk() self.root.title("Editor for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False, False) #define response to main window closing self.root.protocol("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = tk.StringVar() self.display_selected_track_title = tk.StringVar() self.display_show = tk.StringVar() # define menu menubar = Menu(self.root) profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black") profilemenu.add_command(label='Open', command=self.open_existing_profile) profilemenu.add_command(label='Validate', command=self.validate_profile) menubar.add_cascade(label='Profile', menu=profilemenu) ptypemenu = Menu(profilemenu, tearoff=0, bg="grey", fg="black") ptypemenu.add_command(label='Exhibit', command=self.new_exhibit_profile) ptypemenu.add_command(label='Media Show', command=self.new_mediashow_profile) ptypemenu.add_command(label='Menu', command=self.new_menu_profile) ptypemenu.add_command(label='Presentation', command=self.new_presentation_profile) ptypemenu.add_command(label='Interactive', command=self.new_interactive_profile) ptypemenu.add_command(label='Live Show', command=self.new_liveshow_profile) ptypemenu.add_command(label='RadioButton Show', command=self.new_radiobuttonshow_profile) ptypemenu.add_command(label='Hyperlink Show', command=self.new_hyperlinkshow_profile) ptypemenu.add_command(label='Blank', command=self.new_blank_profile) profilemenu.add_cascade(label='New from Template', menu=ptypemenu) showmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") showmenu.add_command(label='Delete', command=self.remove_show) showmenu.add_command(label='Edit', command=self.m_edit_show) showmenu.add_command(label='Copy To', command=self.copy_show) menubar.add_cascade(label='Show', menu=showmenu) stypemenu = Menu(showmenu, tearoff=0, bg="grey", fg="black") stypemenu.add_command(label='Menu', command=self.add_menu) stypemenu.add_command(label='MediaShow', command=self.add_mediashow) stypemenu.add_command(label='LiveShow', command=self.add_liveshow) stypemenu.add_command(label='HyperlinkShow', command=self.add_hyperlinkshow) stypemenu.add_command(label='RadioButtonShow', command=self.add_radiobuttonshow) showmenu.add_cascade(label='Add', menu=stypemenu) medialistmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='MediaList', menu=medialistmenu) medialistmenu.add_command(label='Add', command=self.add_medialist) medialistmenu.add_command(label='Delete', command=self.remove_medialist) trackmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") trackmenu.add_command(label='Delete', command=self.remove_track) trackmenu.add_command(label='Edit', command=self.m_edit_track) trackmenu.add_command(label='Add from Dir', command=self.add_tracks_from_dir) trackmenu.add_command(label='Add from File', command=self.add_track_from_file) menubar.add_cascade(label='Track', menu=trackmenu) typemenu = Menu(trackmenu, tearoff=0, bg="grey", fg="black") typemenu.add_command(label='Video', command=self.new_video_track) typemenu.add_command(label='Audio', command=self.new_audio_track) typemenu.add_command(label='Image', command=self.new_image_track) typemenu.add_command(label='Web', command=self.new_web_track) typemenu.add_command(label='Message', command=self.new_message_track) typemenu.add_command(label='Show', command=self.new_show_track) typemenu.add_command(label='Menu Background', command=self.new_menu_background_track) typemenu.add_command(label='Child Show', command=self.new_child_show_track) trackmenu.add_cascade(label='New', menu=typemenu) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu=toolsmenu) toolsmenu.add_command(label='Update All', command=self.update_all) optionsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu=optionsmenu) optionsmenu.add_command(label='Edit', command=self.edit_options) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu=helpmenu) helpmenu.add_command(label='Help', command=self.show_help) helpmenu.add_command(label='About', command=self.about) self.root.config(menu=menubar) top_frame = Frame(self.root) top_frame.pack(side=TOP) bottom_frame = Frame(self.root) bottom_frame.pack(side=TOP, fill=BOTH, expand=1) left_frame = Frame(bottom_frame, padx=5) left_frame.pack(side=LEFT) middle_frame = Frame(bottom_frame, padx=5) middle_frame.pack(side=LEFT) right_frame = Frame(bottom_frame, padx=5, pady=10) right_frame.pack(side=LEFT) updown_frame = Frame(bottom_frame, padx=5) updown_frame.pack(side=LEFT) tracks_title_frame = Frame(right_frame) tracks_title_frame.pack(side=TOP) tracks_label = Label(tracks_title_frame, text="Tracks in Selected Medialist") tracks_label.pack() tracks_frame = Frame(right_frame) tracks_frame.pack(side=TOP) shows_title_frame = Frame(left_frame) shows_title_frame.pack(side=TOP) shows_label = Label(shows_title_frame, text="Shows") shows_label.pack() shows_frame = Frame(left_frame) shows_frame.pack(side=TOP) shows_title_frame = Frame(left_frame) shows_title_frame.pack(side=TOP) medialists_title_frame = Frame(left_frame) medialists_title_frame.pack(side=TOP) medialists_label = Label(medialists_title_frame, text="Medialists") medialists_label.pack() medialists_frame = Frame(left_frame) medialists_frame.pack(side=LEFT) # define buttons add_button = Button(middle_frame, width=5, height=2, text='Edit\nShow', fg='black', command=self.m_edit_show, bg="light grey") add_button.pack(side=RIGHT) add_button = Button(updown_frame, width=5, height=1, text='Add', fg='black', command=self.add_track_from_file, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width=5, height=1, text='Edit', fg='black', command=self.m_edit_track, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width=5, height=1, text='Up', fg='black', command=self.move_track_up, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width=5, height=1, text='Down', fg='black', command=self.move_track_down, bg="light grey") add_button.pack(side=TOP) # define display of showlist scrollbar = Scrollbar(shows_frame, orient=tk.VERTICAL) self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=7, width=40, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.shows_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.shows_display.pack(side=LEFT, fill=BOTH, expand=1) self.shows_display.bind("<ButtonRelease-1>", self.e_select_show) # define display of medialists scrollbar = Scrollbar(medialists_frame, orient=tk.VERTICAL) self.medialists_display = Listbox(medialists_frame, selectmode=SINGLE, height=7, width=40, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.medialists_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.medialists_display.pack(side=LEFT, fill=BOTH, expand=1) self.medialists_display.bind("<ButtonRelease-1>", self.select_medialist) # define display of tracks scrollbar = Scrollbar(tracks_frame, orient=tk.VERTICAL) self.tracks_display = Listbox(tracks_frame, selectmode=SINGLE, height=15, width=40, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.tracks_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.tracks_display.pack(side=LEFT, fill=BOTH, expand=1) self.tracks_display.bind("<ButtonRelease-1>", self.e_select_track) # initialise editor options class self.options = Options( self.pp_dir) #creates options file in code directory if necessary # initialise variables self.init() #and enter Tkinter event loop self.root.mainloop() # *************************************** # INIT AND EXIT # *************************************** def app_exit(self): self.root.destroy() exit() def init(self): self.options.read() self.pp_home_dir = self.options.pp_home_dir self.initial_media_dir = self.options.initial_media_dir self.mon.log(self, "Data Home from options is " + self.pp_home_dir) self.mon.log(self, "Initial Media from options is " + self.initial_media_dir) self.current_medialist = None self.current_showlist = None self.current_show = None self.shows_display.delete(0, END) self.medialists_display.delete(0, END) self.tracks_display.delete(0, END) # *************************************** # MISCELLANEOUS # *************************************** def edit_options(self): """edit the options then read them from file""" eo = OptionsDialog(self.root, self.options.options_file, 'Edit Options') if eo.result == True: self.init() def show_help(self): tkMessageBox.showinfo("Help", "Read 'manual.pdf'") def about(self): tkMessageBox.showinfo( "About", "Editor for Pi Presents Profiles\n" + "For profile version: " + self.editor_issue + "\nAuthor: Ken Thompson" + "\nWebsite: http://pipresents.wordpress.com/") def validate_profile(self): val = Validator() val.validate_profile(self.root, self.pp_dir, self.pp_home_dir, self.pp_profile_dir, self.editor_issue, True) # ************** # PROFILES # ************** def open_existing_profile(self): initial_dir = self.pp_home_dir + os.sep + "pp_profiles" if os.path.exists(initial_dir) == False: self.mon.err( self, "Home directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home") return dir_path = tkFileDialog.askdirectory(initialdir=initial_dir) # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt" if len(dir_path) > 0: self.open_profile(dir_path) def open_profile(self, dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) == False: self.mon.err( self, "Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?") return self.pp_profile_dir = dir_path self.root.title("Editor for Pi Presents - " + self.pp_profile_dir) if self.open_showlist(self.pp_profile_dir) == False: self.init() return self.open_medialists(self.pp_profile_dir) self.refresh_tracks_display() def new_profile(self, profile): d = Edit1Dialog(self.root, "New Profile", "Name", "") if d.result == None: return name = str(d.result) if name == "": tkMessageBox.showwarning("New Profile", "Name is blank") return to = self.pp_home_dir + os.sep + "pp_profiles" + os.sep + name if os.path.exists(to) == True: tkMessageBox.showwarning("New Profile", "Profile exists\n(%s)" % to) return shutil.copytree(profile, to, symlinks=False, ignore=None) self.open_profile(to) def new_exhibit_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_exhibit" self.new_profile(profile) def new_interactive_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_interactive" self.new_profile(profile) def new_menu_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_menu" self.new_profile(profile) def new_presentation_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_presentation" self.new_profile(profile) def new_blank_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_blank" self.new_profile(profile) def new_mediashow_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_mediashow" self.new_profile(profile) def new_liveshow_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_liveshow" self.new_profile(profile) def new_radiobuttonshow_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_radiobuttonshow" self.new_profile(profile) def new_hyperlinkshow_profile(self): profile = self.pp_dir + "/pp_home/pp_profiles/ppt_hyperlinkshow" self.new_profile(profile) # *************************************** # Shows # *************************************** def open_showlist(self, dir): showlist_file = dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) == False: self.mon.err( self, "showlist file not found at " + dir + "\n\nHint: Have you opened the profile directory?") self.app_exit() self.current_showlist = ShowList() self.current_showlist.open_json(showlist_file) if float(self.current_showlist.sissue()) < float( self.editor_issue) or ( self.command_options['forceupdate'] == True and float(self.current_showlist.sissue()) == float( self.editor_issue)): self.update_profile() self.mon.err( self, "Version of profile has been updated to " + self.editor_issue + ", please re-open") return False if float(self.current_showlist.sissue()) > float(self.editor_issue): self.mon.err( self, "Version of profile is greater than editor, must exit") self.app_exit() self.refresh_shows_display() return True def save_showlist(self, dir): if self.current_showlist <> None: showlist_file = dir + os.sep + "pp_showlist.json" self.current_showlist.save_list(showlist_file) def add_eventshow(self): self.add_show(PPdefinitions.new_shows['eventshow']) def add_mediashow(self): self.add_show(PPdefinitions.new_shows['mediashow']) def add_liveshow(self): self.add_show(PPdefinitions.new_shows['liveshow']) def add_radiobuttonshow(self): self.add_show(PPdefinitions.new_shows['radiobuttonshow']) def add_hyperlinkshow(self): self.add_show(PPdefinitions.new_shows['hyperlinkshow']) def add_menu(self): self.add_show(PPdefinitions.new_shows['menu']) def add_start(self): self.add_show(PPdefinitions.new_shows['start']) def add_show(self, default): # append it to the showlist and then add the medialist if self.current_showlist <> None: d = Edit1Dialog(self.root, "AddShow", "Show Reference", "") if d.result == None: return name = str(d.result) if name == "": tkMessageBox.showwarning("Add Show", "Name is blank") return if self.current_showlist.index_of_show(name) <> -1: tkMessageBox.showwarning( "Add Show", "A Show with this name already exists") return copied_show = self.current_showlist.copy(default, name) mediafile = self.add_medialist(name) if mediafile <> '': copied_show['medialist'] = mediafile self.current_showlist.append(copied_show) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def remove_show(self): if self.current_showlist <> None and self.current_showlist.length( ) > 0 and self.current_showlist.show_is_selected(): if tkMessageBox.askokcancel("Delete Show", "Delete Show"): index = self.current_showlist.selected_show_index() self.current_showlist.remove(index) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def show_refs(self): _show_refs = [] for index in range(self.current_showlist.length()): if self.current_showlist.show(index)['show-ref'] <> "start": _show_refs.append( copy.deepcopy( self.current_showlist.show(index)['show-ref'])) return _show_refs def refresh_shows_display(self): self.shows_display.delete(0, self.shows_display.size()) for index in range(self.current_showlist.length()): self.shows_display.insert( END, self.current_showlist.show(index)['title'] + " [" + self.current_showlist.show(index)['show-ref'] + "]") if self.current_showlist.show_is_selected(): self.shows_display.itemconfig( self.current_showlist.selected_show_index(), fg='red') self.shows_display.see(self.current_showlist.selected_show_index()) def e_select_show(self, event): if self.current_showlist <> None and self.current_showlist.length( ) > 0: mouse_item_index = int(event.widget.curselection()[0]) self.current_showlist.select(mouse_item_index) self.refresh_shows_display() def copy_show(self): if self.current_showlist <> None and self.current_showlist.show_is_selected( ): self.add_show(self.current_showlist.selected_show()) def m_edit_show(self): self.edit_show(PPdefinitions.show_types, PPdefinitions.show_field_specs) def edit_show(self, show_types, field_specs): if self.current_showlist <> None and self.current_showlist.show_is_selected( ): d = EditItem(self.root, "Edit Show", self.current_showlist.selected_show(), show_types, field_specs, self.show_refs(), self.initial_media_dir, self.pp_home_dir, 'show') if d.result == True: self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() # *************************************** # Medialists # *************************************** def open_medialists(self, dir): self.medialists = [] for file in os.listdir(dir): if file.endswith(".json") and file <> 'pp_showlist.json': self.medialists = self.medialists + [file] self.medialists_display.delete(0, self.medialists_display.size()) for index in range(len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) self.current_medialists_index = -1 self.current_medialist = None def add_medialist(self, name=None): if name == None: d = Edit1Dialog(self.root, "Add Medialist", "File", "") if d.result == None: return '' name = str(d.result) if name == "": tkMessageBox.showwarning("Add medialist", "Name is blank") return '' if not name.endswith(".json"): name = name + (".json") path = self.pp_profile_dir + os.sep + name if os.path.exists(path) == True: tkMessageBox.showwarning("Add medialist", "Medialist file exists\n(%s)" % path) return '' nfile = open(path, 'wb') nfile.write("{") nfile.write("\"issue\": \"" + self.editor_issue + "\",\n") nfile.write("\"tracks\": [") nfile.write("]") nfile.write("}") nfile.close() # append it to the list self.medialists.append(copy.deepcopy(name)) # add title to medialists display self.medialists_display.insert(END, name) # and set it as the selected medialist self.refresh_medialists_display() return name def remove_medialist(self): if self.current_medialist <> None: if tkMessageBox.askokcancel("Delete Medialist", "Delete Medialist"): os.remove(self.pp_profile_dir + os.sep + self.medialists[self.current_medialists_index]) self.open_medialists(self.pp_profile_dir) self.refresh_medialists_display() self.refresh_tracks_display() def select_medialist(self, event): """ user clicks on a medialst in a profile so try and select it. """ # needs forgiving int for possible tkinter upgrade if len(self.medialists) > 0: self.current_medialists_index = int(event.widget.curselection()[0]) self.current_medialist = MediaList('ordered') if not self.current_medialist.open_list( self.pp_profile_dir + os.sep + self.medialists[self.current_medialists_index], self.current_showlist.sissue()): self.mon.err( self, "medialist is a different version to showlist: " + self.medialists[self.current_medialists_index]) self.app_exit() self.refresh_tracks_display() self.refresh_medialists_display() def refresh_medialists_display(self): self.medialists_display.delete(0, len(self.medialists)) for index in range(len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) if self.current_medialist <> None: self.medialists_display.itemconfig(self.current_medialists_index, fg='red') self.medialists_display.see(self.current_medialists_index) def save_medialist(self): basefile = self.medialists[self.current_medialists_index] #print type(basefile) # basefile=str(basefile) #print type(basefile) file = self.pp_profile_dir + os.sep + basefile self.current_medialist.save_list(file) # *************************************** # Tracks # *************************************** def refresh_tracks_display(self): self.tracks_display.delete(0, self.tracks_display.size()) if self.current_medialist <> None: for index in range(self.current_medialist.length()): if self.current_medialist.track(index)['track-ref'] <> "": track_ref_string = " [" + self.current_medialist.track( index)['track-ref'] + "]" else: track_ref_string = "" self.tracks_display.insert( END, self.current_medialist.track(index)['title'] + track_ref_string) if self.current_medialist.track_is_selected(): self.tracks_display.itemconfig( self.current_medialist.selected_track_index(), fg='red') self.tracks_display.see( self.current_medialist.selected_track_index()) def e_select_track(self, event): if self.current_medialist <> None and self.current_medialist.length( ) > 0: mouse_item_index = int(event.widget.curselection()[0]) self.current_medialist.select(mouse_item_index) self.refresh_tracks_display() def m_edit_track(self): self.edit_track(PPdefinitions.track_types, PPdefinitions.track_field_specs) def edit_track(self, track_types, field_specs): if self.current_medialist <> None and self.current_medialist.track_is_selected( ): d = EditItem(self.root, "Edit Track", self.current_medialist.selected_track(), track_types, field_specs, self.show_refs(), self.initial_media_dir, self.pp_home_dir, 'track') if d.result == True: self.save_medialist() self.refresh_tracks_display() def move_track_up(self): if self.current_medialist <> None and self.current_medialist.track_is_selected( ): self.current_medialist.move_up() self.refresh_tracks_display() self.save_medialist() def move_track_down(self): if self.current_medialist <> None and self.current_medialist.track_is_selected( ): self.current_medialist.move_down() self.refresh_tracks_display() self.save_medialist() def new_track(self, fields, values): if self.current_medialist <> None: #print '\nfields ', fields #print '\nvalues ', values new_track = copy.deepcopy(fields) #print ',\new track ',new_track self.current_medialist.append(new_track) #print '\nbefore values ',self.current_medialist.print_list() if values <> None: self.current_medialist.update( self.current_medialist.length() - 1, values) self.current_medialist.select(self.current_medialist.length() - 1) self.refresh_tracks_display() self.save_medialist() def new_message_track(self): self.new_track(PPdefinitions.new_tracks['message'], None) def new_video_track(self): self.new_track(PPdefinitions.new_tracks['video'], None) def new_audio_track(self): self.new_track(PPdefinitions.new_tracks['audio'], None) def new_web_track(self): self.new_track(PPdefinitions.new_tracks['web'], None) def new_image_track(self): self.new_track(PPdefinitions.new_tracks['image'], None) def new_show_track(self): self.new_track(PPdefinitions.new_tracks['show'], None) def new_menu_background_track(self): self.new_track(PPdefinitions.new_tracks['menu-background'], None) def new_child_show_track(self): self.new_track(PPdefinitions.new_tracks['child-show'], None) def remove_track(self): if self.current_medialist <> None and self.current_medialist.length( ) > 0 and self.current_medialist.track_is_selected(): if tkMessageBox.askokcancel("Delete Track", "Delete Track"): index = self.current_medialist.selected_track_index() self.current_medialist.remove(index) self.save_medialist() self.refresh_tracks_display() def add_track_from_file(self): if self.current_medialist == None: return # print "initial directory ", self.options.initial_media_dir files_path = tkFileDialog.askopenfilename( initialdir=self.options.initial_media_dir, multiple=True) # fix for tkinter bug files_path = self.root.tk.splitlist(files_path) for file_path in files_path: file_path = os.path.normpath(file_path) # print "file path ", file_path self.add_track(file_path) self.save_medialist() def add_tracks_from_dir(self): if self.current_medialist == None: return image_specs = [ PPdefinitions.IMAGE_FILES, PPdefinitions.VIDEO_FILES, PPdefinitions.AUDIO_FILES, PPdefinitions.WEB_FILES, ('All files', '*') ] #last one is ignored in finding files # in directory, for dialog box only directory = tkFileDialog.askdirectory( initialdir=self.options.initial_media_dir) # deal with tuple returned on Cancel if len(directory) == 0: return # make list of exts we recognise exts = [] for image_spec in image_specs[:-1]: image_list = image_spec[1:] for ext in image_list: exts.append(copy.deepcopy(ext)) for file in os.listdir(directory): (root_file, ext_file) = os.path.splitext(file) if ext_file.lower() in exts: file_path = directory + os.sep + file #print "file path before ", file_path file_path = os.path.normpath(file_path) #print "file path after ", file_path self.add_track(file_path) self.save_medialist() def add_track(self, afile): relpath = os.path.relpath(afile, self.pp_home_dir) #print "relative path ",relpath common = os.path.commonprefix([afile, self.pp_home_dir]) #print "common ",common if common.endswith("pp_home") == False: location = afile else: location = "+" + os.sep + relpath location = string.replace(location, '\\', '/') #print "location ",location (root, title) = os.path.split(afile) (root, ext) = os.path.splitext(afile) if ext.lower() in PPdefinitions.IMAGE_FILES: self.new_track(PPdefinitions.new_tracks['image'], { 'title': title, 'track-ref': '', 'location': location }) elif ext.lower() in PPdefinitions.VIDEO_FILES: self.new_track(PPdefinitions.new_tracks['video'], { 'title': title, 'track-ref': '', 'location': location }) elif ext.lower() in PPdefinitions.AUDIO_FILES: self.new_track(PPdefinitions.new_tracks['audio'], { 'title': title, 'track-ref': '', 'location': location }) elif ext.lower() in PPdefinitions.WEB_FILES: self.new_track(PPdefinitions.new_tracks['web'], { 'title': title, 'track-ref': '', 'location': location }) else: self.mon.err(self, afile + " - file extension not recognised") # ********************************************* # update profile # ********************************************** def update_all(self): self.init() for profile_file in os.listdir(self.pp_home_dir + os.sep + 'pp_profiles'): # self.mon.log (self,"Updating "+profile_file) self.pp_profile_dir = self.pp_home_dir + os.sep + 'pp_profiles' + os.sep + profile_file if not os.path.exists(self.pp_profile_dir + os.sep + "pp_showlist.json"): tkMessageBox.showwarning( "Pi Presents", "Not a profile, skipping " + self.pp_profile_dir) else: self.current_showlist = ShowList() #self.mon.log (self,"Checking version "+profile_file) self.current_showlist.open_json(self.pp_profile_dir + os.sep + "pp_showlist.json") if float(self.current_showlist.sissue()) < float( self.editor_issue): self.mon.log( self, "Version of profile " + profile_file + " is being updated to " + self.editor_issue) self.update_profile() elif (self.command_options['forceupdate'] == True and float(self.current_showlist.sissue()) == float( self.editor_issue)): self.mon.log( self, "Forced updating of " + profile_file + ' to ' + self.editor_issue) self.update_profile() elif float(self.current_showlist.sissue()) > float( self.editor_issue): tkMessageBox.showwarning( "Pi Presents", "Version of profile " + profile_file + " is greater than editor, skipping") else: self.mon.log( self, " Profile " + profile_file + " Already up to date ") self.init() tkMessageBox.showwarning("Pi Presents", "All profiles updated") def update_profile(self): #open showlist and update its shows # self.mon.log (self,"Updating show ") ifile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", 'rb') shows = json.load(ifile)['shows'] ifile.close() replacement_shows = self.update_shows(shows) dic = {'issue': self.editor_issue, 'shows': replacement_shows} ofile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", "wb") json.dump(dic, ofile, sort_keys=True, indent=1) # UPDATE MEDIALISTS AND THEIR TRACKS for file in os.listdir(self.pp_profile_dir): if file.endswith(".json") and file <> 'pp_showlist.json': # self.mon.log (self,"Updating medialist " + file) #open a medialist and update its tracks ifile = open(self.pp_profile_dir + os.sep + file, 'rb') tracks = json.load(ifile)['tracks'] ifile.close() replacement_tracks = self.update_tracks(tracks) dic = { 'issue': self.editor_issue, 'tracks': replacement_tracks } ofile = open(self.pp_profile_dir + os.sep + file, "wb") json.dump(dic, ofile, sort_keys=True, indent=1) def update_tracks(self, old_tracks): # get correct spec from type of field replacement_tracks = [] for old_track in old_tracks: #print '\nold track ',old_track track_type = old_track['type'] spec_fields = PPdefinitions.new_tracks[track_type] left_overs = dict() # go through track and delete fields not in spec for key in old_track.keys(): if key in spec_fields: left_overs[key] = old_track[key] #print '\n leftovers',left_overs replacement_track = copy.deepcopy( PPdefinitions.new_tracks[track_type]) #print '\n before update', replacement_track replacement_track.update(left_overs) #print '\nafter update',replacement_track replacement_tracks.append(copy.deepcopy(replacement_track)) return replacement_tracks def update_shows(self, old_shows): # get correct spec from type of field replacement_shows = [] for old_show in old_shows: show_type = old_show['type'] spec_fields = PPdefinitions.new_shows[show_type] left_overs = dict() # go through track and delete fields not in spec for key in old_show.keys(): if key in spec_fields: left_overs[key] = old_show[key] # print '\n leftovers',left_overs replacement_show = copy.deepcopy( PPdefinitions.new_shows[show_type]) replacement_show.update(left_overs) replacement_shows.append(copy.deepcopy(replacement_show)) return replacement_shows
class PPEditor: # *************************************** # INIT # *************************************** def __init__(self): self.editor_issue="1.2" # get command options self.command_options=ed_options() # get directory holding the code self.pp_dir=sys.path[0] if not os.path.exists(self.pp_dir+os.sep+"pp_editor.py"): tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit() #Initialise logging Monitor.log_path=self.pp_dir self.mon=Monitor() self.mon.on() if self.command_options['debug'] == True: Monitor.global_enable=True else: Monitor.global_enable=False self.mon.log (self, "Pi Presents Editor is starting") self.mon.log (self," OS and separator " + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: code "+sys.path[0]) # set up the gui #root is the Tkinter root widget self.root = tk.Tk() self.root.title("Editor for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False,False) #define response to main window closing self.root.protocol ("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = tk.StringVar() self.display_selected_track_title = tk.StringVar() self.display_show = tk.StringVar() # define menu menubar = Menu(self.root) profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black") profilemenu.add_command(label='Open', command = self.open_existing_profile) profilemenu.add_command(label='Validate', command = self.validate_profile) menubar.add_cascade(label='Profile', menu = profilemenu) ptypemenu = Menu(profilemenu, tearoff=0, bg="grey", fg="black") ptypemenu.add_command(label='Exhibit', command = self.new_exhibit_profile) ptypemenu.add_command(label='Media Show', command = self.new_mediashow_profile) ptypemenu.add_command(label='Menu', command = self.new_menu_profile) ptypemenu.add_command(label='Presentation', command = self.new_presentation_profile) ptypemenu.add_command(label='Interactive', command = self.new_interactive_profile) ptypemenu.add_command(label='Live Show', command = self.new_liveshow_profile) ptypemenu.add_command(label='RadioButton Show', command = self.new_radiobuttonshow_profile) ptypemenu.add_command(label='Hyperlink Show', command = self.new_hyperlinkshow_profile) ptypemenu.add_command(label='Blank', command = self.new_blank_profile) profilemenu.add_cascade(label='New from Template', menu = ptypemenu) showmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") showmenu.add_command(label='Delete', command = self.remove_show) showmenu.add_command(label='Edit', command = self.m_edit_show) showmenu.add_command(label='Copy To', command = self.copy_show) menubar.add_cascade(label='Show', menu = showmenu) stypemenu = Menu(showmenu, tearoff=0, bg="grey", fg="black") stypemenu.add_command(label='Menu', command = self.add_menu) stypemenu.add_command(label='MediaShow', command = self.add_mediashow) stypemenu.add_command(label='LiveShow', command = self.add_liveshow) stypemenu.add_command(label='HyperlinkShow', command = self.add_hyperlinkshow) stypemenu.add_command(label='RadioButtonShow', command = self.add_radiobuttonshow) showmenu.add_cascade(label='Add', menu = stypemenu) medialistmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='MediaList', menu = medialistmenu) medialistmenu.add_command(label='Add', command = self.add_medialist) medialistmenu.add_command(label='Delete', command = self.remove_medialist) trackmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") trackmenu.add_command(label='Delete', command = self.remove_track) trackmenu.add_command(label='Edit', command = self.m_edit_track) trackmenu.add_command(label='Add from Dir', command = self.add_tracks_from_dir) trackmenu.add_command(label='Add from File', command = self.add_track_from_file) menubar.add_cascade(label='Track', menu = trackmenu) typemenu = Menu(trackmenu, tearoff=0, bg="grey", fg="black") typemenu.add_command(label='Video', command = self.new_video_track) typemenu.add_command(label='Audio', command = self.new_audio_track) typemenu.add_command(label='Image', command = self.new_image_track) typemenu.add_command(label='Web', command = self.new_web_track) typemenu.add_command(label='Message', command = self.new_message_track) typemenu.add_command(label='Show', command = self.new_show_track) typemenu.add_command(label='Menu Background', command = self.new_menu_background_track) typemenu.add_command(label='Child Show', command = self.new_child_show_track) trackmenu.add_cascade(label='New', menu = typemenu) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu = toolsmenu) toolsmenu.add_command(label='Update All', command = self.update_all) optionsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu = optionsmenu) optionsmenu.add_command(label='Edit', command = self.edit_options) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu = helpmenu) helpmenu.add_command(label='Help', command = self.show_help) helpmenu.add_command(label='About', command = self.about) self.root.config(menu=menubar) top_frame=Frame(self.root) top_frame.pack(side=TOP) bottom_frame=Frame(self.root) bottom_frame.pack(side=TOP, fill=BOTH, expand=1) left_frame=Frame(bottom_frame, padx=5) left_frame.pack(side=LEFT) middle_frame=Frame(bottom_frame,padx=5) middle_frame.pack(side=LEFT) right_frame=Frame(bottom_frame,padx=5,pady=10) right_frame.pack(side=LEFT) updown_frame=Frame(bottom_frame,padx=5) updown_frame.pack(side=LEFT) tracks_title_frame=Frame(right_frame) tracks_title_frame.pack(side=TOP) tracks_label = Label(tracks_title_frame, text="Tracks in Selected Medialist") tracks_label.pack() tracks_frame=Frame(right_frame) tracks_frame.pack(side=TOP) shows_title_frame=Frame(left_frame) shows_title_frame.pack(side=TOP) shows_label = Label(shows_title_frame, text="Shows") shows_label.pack() shows_frame=Frame(left_frame) shows_frame.pack(side=TOP) shows_title_frame=Frame(left_frame) shows_title_frame.pack(side=TOP) medialists_title_frame=Frame(left_frame) medialists_title_frame.pack(side=TOP) medialists_label = Label(medialists_title_frame, text="Medialists") medialists_label.pack() medialists_frame=Frame(left_frame) medialists_frame.pack(side=LEFT) # define buttons add_button = Button(middle_frame, width = 5, height = 2, text='Edit\nShow', fg='black', command = self.m_edit_show, bg="light grey") add_button.pack(side=RIGHT) add_button = Button(updown_frame, width = 5, height = 1, text='Add', fg='black', command = self.add_track_from_file, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Edit', fg='black', command = self.m_edit_track, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Up', fg='black', command = self.move_track_up, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Down', fg='black', command = self.move_track_down, bg="light grey") add_button.pack(side=TOP) # define display of showlist scrollbar = Scrollbar(shows_frame, orient=tk.VERTICAL) self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=7, width = 40, bg="white",activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.shows_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.shows_display.pack(side=LEFT, fill=BOTH, expand=1) self.shows_display.bind("<ButtonRelease-1>", self.e_select_show) # define display of medialists scrollbar = Scrollbar(medialists_frame, orient=tk.VERTICAL) self.medialists_display = Listbox(medialists_frame, selectmode=SINGLE, height=7, width = 40, bg="white",activestyle=NONE, fg="black",yscrollcommand=scrollbar.set) scrollbar.config(command=self.medialists_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.medialists_display.pack(side=LEFT, fill=BOTH, expand=1) self.medialists_display.bind("<ButtonRelease-1>", self.select_medialist) # define display of tracks scrollbar = Scrollbar(tracks_frame, orient=tk.VERTICAL) self.tracks_display = Listbox(tracks_frame, selectmode=SINGLE, height=15, width = 40, bg="white",activestyle=NONE, fg="black",yscrollcommand=scrollbar.set) scrollbar.config(command=self.tracks_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.tracks_display.pack(side=LEFT,fill=BOTH, expand=1) self.tracks_display.bind("<ButtonRelease-1>", self.e_select_track) # initialise editor options class self.options=Options(self.pp_dir) #creates options file in code directory if necessary # initialise variables self.init() #and enter Tkinter event loop self.root.mainloop() # *************************************** # INIT AND EXIT # *************************************** def app_exit(self): self.root.destroy() exit() def init(self): self.options.read() self.pp_home_dir = self.options.pp_home_dir self.initial_media_dir = self.options.initial_media_dir self.mon.log(self,"Data Home from options is "+self.pp_home_dir) self.mon.log(self,"Initial Media from options is "+self.initial_media_dir) self.current_medialist=None self.current_showlist=None self.current_show=None self.shows_display.delete(0,END) self.medialists_display.delete(0,END) self.tracks_display.delete(0,END) # *************************************** # MISCELLANEOUS # *************************************** def edit_options(self): """edit the options then read them from file""" eo = OptionsDialog(self.root, self.options.options_file,'Edit Options') if eo.result==True: self.init() def show_help (self): tkMessageBox.showinfo("Help", "Read 'manual.pdf'") def about (self): tkMessageBox.showinfo("About","Editor for Pi Presents Profiles\n" +"For profile version: " + self.editor_issue + "\nAuthor: Ken Thompson"+ "\nWebsite: http://pipresents.wordpress.com/") def validate_profile(self): val =Validator() val.validate_profile(self.root,self.pp_dir,self.pp_home_dir,self.pp_profile_dir,self.editor_issue,True) # ************** # PROFILES # ************** def open_existing_profile(self): initial_dir=self.pp_home_dir+os.sep+"pp_profiles" if os.path.exists(initial_dir)==False: self.mon.err(self,"Home directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home") return dir_path=tkFileDialog.askdirectory(initialdir=initial_dir) # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt" if len(dir_path)>0: self.open_profile(dir_path) def open_profile(self,dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" if os.path.exists(showlist_file)==False: self.mon.err(self,"Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?") return self.pp_profile_dir = dir_path self.root.title("Editor for Pi Presents - "+ self.pp_profile_dir) if self.open_showlist(self.pp_profile_dir)==False: self.init() return self.open_medialists(self.pp_profile_dir) self.refresh_tracks_display() def new_profile(self,profile): d = Edit1Dialog(self.root,"New Profile","Name", "") if d .result == None: return name=str(d.result) if name=="": tkMessageBox.showwarning("New Profile","Name is blank") return to = self.pp_home_dir + os.sep + "pp_profiles"+ os.sep + name if os.path.exists(to)== True: tkMessageBox.showwarning( "New Profile","Profile exists\n(%s)" % to ) return shutil.copytree(profile, to, symlinks=False, ignore=None) self.open_profile(to) def new_exhibit_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_exhibit" self.new_profile(profile) def new_interactive_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_interactive" self.new_profile(profile) def new_menu_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_menu" self.new_profile(profile) def new_presentation_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_presentation" self.new_profile(profile) def new_blank_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_blank" self.new_profile(profile) def new_mediashow_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_mediashow" self.new_profile(profile) def new_liveshow_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_liveshow" self.new_profile(profile) def new_radiobuttonshow_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_radiobuttonshow" self.new_profile(profile) def new_hyperlinkshow_profile(self): profile = self.pp_dir+"/pp_home/pp_profiles/ppt_hyperlinkshow" self.new_profile(profile) # *************************************** # Shows # *************************************** def open_showlist(self,dir): showlist_file = dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file)==False: self.mon.err(self,"showlist file not found at " + dir + "\n\nHint: Have you opened the profile directory?") self.app_exit() self.current_showlist=ShowList() self.current_showlist.open_json(showlist_file) if float(self.current_showlist.sissue())<float(self.editor_issue) or (self.command_options['forceupdate'] == True and float(self.current_showlist.sissue())==float(self.editor_issue)): self.update_profile() self.mon.err(self,"Version of profile has been updated to "+self.editor_issue+", please re-open") return False if float(self.current_showlist.sissue())>float(self.editor_issue): self.mon.err(self,"Version of profile is greater than editor, must exit") self.app_exit() self.refresh_shows_display() return True def save_showlist(self,dir): if self.current_showlist<>None: showlist_file = dir + os.sep + "pp_showlist.json" self.current_showlist.save_list(showlist_file) def add_eventshow(self): self.add_show(PPdefinitions.new_shows['eventshow']) def add_mediashow(self): self.add_show(PPdefinitions.new_shows['mediashow']) def add_liveshow(self): self.add_show(PPdefinitions.new_shows['liveshow']) def add_radiobuttonshow(self): self.add_show(PPdefinitions.new_shows['radiobuttonshow']) def add_hyperlinkshow(self): self.add_show(PPdefinitions.new_shows['hyperlinkshow']) def add_menu(self): self.add_show(PPdefinitions.new_shows['menu']) def add_start(self): self.add_show(PPdefinitions.new_shows['start']) def add_show(self,default): # append it to the showlist and then add the medialist if self.current_showlist<>None: d = Edit1Dialog(self.root,"AddShow", "Show Reference", "") if d.result == None: return name=str(d.result) if name=="": tkMessageBox.showwarning( "Add Show", "Name is blank" ) return if self.current_showlist.index_of_show(name)<>-1: tkMessageBox.showwarning( "Add Show", "A Show with this name already exists" ) return copied_show=self.current_showlist.copy(default,name) mediafile=self.add_medialist(name) if mediafile<>'': copied_show['medialist']=mediafile self.current_showlist.append(copied_show) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def remove_show(self): if self.current_showlist<>None and self.current_showlist.length()>0 and self.current_showlist.show_is_selected(): if tkMessageBox.askokcancel("Delete Show","Delete Show"): index= self.current_showlist.selected_show_index() self.current_showlist.remove(index) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def show_refs(self): _show_refs=[] for index in range(self.current_showlist.length()): if self.current_showlist.show(index)['show-ref']<>"start": _show_refs.append(copy.deepcopy(self.current_showlist.show(index)['show-ref'])) return _show_refs def refresh_shows_display(self): self.shows_display.delete(0,self.shows_display.size()) for index in range(self.current_showlist.length()): self.shows_display.insert(END, self.current_showlist.show(index)['title']+" ["+self.current_showlist.show(index)['show-ref']+"]") if self.current_showlist.show_is_selected(): self.shows_display.itemconfig(self.current_showlist.selected_show_index(),fg='red') self.shows_display.see(self.current_showlist.selected_show_index()) def e_select_show(self,event): if self.current_showlist<>None and self.current_showlist.length()>0: mouse_item_index=int(event.widget.curselection()[0]) self.current_showlist.select(mouse_item_index) self.refresh_shows_display() def copy_show(self): if self.current_showlist<>None and self.current_showlist.show_is_selected(): self.add_show(self.current_showlist.selected_show()) def m_edit_show(self): self.edit_show(PPdefinitions.show_types,PPdefinitions.show_field_specs) def edit_show(self,show_types,field_specs): if self.current_showlist<>None and self.current_showlist.show_is_selected(): d=EditItem(self.root,"Edit Show",self.current_showlist.selected_show(),show_types,field_specs,self.show_refs(), self.initial_media_dir,self.pp_home_dir,'show') if d.result == True: self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() # *************************************** # Medialists # *************************************** def open_medialists(self,dir): self.medialists = [] for file in os.listdir(dir): if file.endswith(".json") and file<>'pp_showlist.json': self.medialists = self.medialists + [file] self.medialists_display.delete(0,self.medialists_display.size()) for index in range (len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) self.current_medialists_index=-1 self.current_medialist=None def add_medialist(self,name=None): if name==None: d = Edit1Dialog(self.root,"Add Medialist", "File", "") if d.result == None: return '' name=str(d.result) if name=="": tkMessageBox.showwarning( "Add medialist", "Name is blank" ) return '' if not name.endswith(".json"): name=name+(".json") path = self.pp_profile_dir + os.sep + name if os.path.exists(path)== True: tkMessageBox.showwarning("Add medialist","Medialist file exists\n(%s)" % path) return '' nfile = open(path,'wb') nfile.write("{") nfile.write("\"issue\": \""+self.editor_issue+"\",\n") nfile.write("\"tracks\": [") nfile.write("]") nfile.write("}") nfile.close() # append it to the list self.medialists.append(copy.deepcopy(name)) # add title to medialists display self.medialists_display.insert(END, name) # and set it as the selected medialist self.refresh_medialists_display() return name def remove_medialist(self): if self.current_medialist<>None: if tkMessageBox.askokcancel("Delete Medialist","Delete Medialist"): os.remove(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index]) self.open_medialists(self.pp_profile_dir) self.refresh_medialists_display() self.refresh_tracks_display() def select_medialist(self,event): """ user clicks on a medialst in a profile so try and select it. """ # needs forgiving int for possible tkinter upgrade if len(self.medialists)>0: self.current_medialists_index=int(event.widget.curselection()[0]) self.current_medialist=MediaList() if not self.current_medialist.open_list(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index],self.current_showlist.sissue()): self.mon.err(self,"medialist is a different version to showlist: "+ self.medialists[self.current_medialists_index]) self.app_exit() self.refresh_tracks_display() self.refresh_medialists_display() def refresh_medialists_display(self): self.medialists_display.delete(0,len(self.medialists)) for index in range (len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) if self.current_medialist<>None: self.medialists_display.itemconfig(self.current_medialists_index,fg='red') self.medialists_display.see(self.current_medialists_index) def save_medialist(self): basefile=self.medialists[self.current_medialists_index] #print type(basefile) # basefile=str(basefile) #print type(basefile) file = self.pp_profile_dir+ os.sep + basefile self.current_medialist.save_list(file) # *************************************** # Tracks # *************************************** def refresh_tracks_display(self): self.tracks_display.delete(0,self.tracks_display.size()) if self.current_medialist<>None: for index in range(self.current_medialist.length()): if self.current_medialist.track(index)['track-ref']<>"": track_ref_string=" ["+self.current_medialist.track(index)['track-ref']+"]" else: track_ref_string="" self.tracks_display.insert(END, self.current_medialist.track(index)['title']+track_ref_string) if self.current_medialist.track_is_selected(): self.tracks_display.itemconfig(self.current_medialist.selected_track_index(),fg='red') self.tracks_display.see(self.current_medialist.selected_track_index()) def e_select_track(self,event): if self.current_medialist<>None and self.current_medialist.length()>0: mouse_item_index=int(event.widget.curselection()[0]) self.current_medialist.select(mouse_item_index) self.refresh_tracks_display() def m_edit_track(self): self.edit_track(PPdefinitions.track_types,PPdefinitions.track_field_specs) def edit_track(self,track_types,field_specs): if self.current_medialist<>None and self.current_medialist.track_is_selected(): d=EditItem(self.root,"Edit Track",self.current_medialist.selected_track(),track_types,field_specs,self.show_refs(), self.initial_media_dir,self.pp_home_dir,'track') if d.result == True: self.save_medialist() self.refresh_tracks_display() def move_track_up(self): if self.current_medialist<>None and self.current_medialist.track_is_selected(): self.current_medialist.move_up() self.refresh_tracks_display() self.save_medialist() def move_track_down(self): if self.current_medialist<>None and self.current_medialist.track_is_selected(): self.current_medialist.move_down() self.refresh_tracks_display() self.save_medialist() def new_track(self,fields,values): if self.current_medialist<>None: #print '\nfields ', fields #print '\nvalues ', values new_track=copy.deepcopy(fields) #print ',\new track ',new_track self.current_medialist.append(new_track) #print '\nbefore values ',self.current_medialist.print_list() if values<>None: self.current_medialist.update(self.current_medialist.length()-1,values) self.current_medialist.select(self.current_medialist.length()-1) self.refresh_tracks_display() self.save_medialist() def new_message_track(self): self.new_track(PPdefinitions.new_tracks['message'],None) def new_video_track(self): self.new_track(PPdefinitions.new_tracks['video'],None) def new_audio_track(self): self.new_track(PPdefinitions.new_tracks['audio'],None) def new_web_track(self): self.new_track(PPdefinitions.new_tracks['web'],None) def new_image_track(self): self.new_track(PPdefinitions.new_tracks['image'],None) def new_show_track(self): self.new_track(PPdefinitions.new_tracks['show'],None) def new_menu_background_track(self): self.new_track(PPdefinitions.new_tracks['menu-background'],None) def new_child_show_track(self): self.new_track(PPdefinitions.new_tracks['child-show'],None) def remove_track(self): if self.current_medialist<>None and self.current_medialist.length()>0 and self.current_medialist.track_is_selected(): if tkMessageBox.askokcancel("Delete Track","Delete Track"): index= self.current_medialist.selected_track_index() self.current_medialist.remove(index) self.save_medialist() self.refresh_tracks_display() def add_track_from_file(self): if self.current_medialist==None: return # print "initial directory ", self.options.initial_media_dir files_path=tkFileDialog.askopenfilename(initialdir=self.options.initial_media_dir, multiple=True) # fix for tkinter bug files_path = self.root.tk.splitlist(files_path) for file_path in files_path: file_path=os.path.normpath(file_path) # print "file path ", file_path self.add_track(file_path) self.save_medialist() def add_tracks_from_dir(self): if self.current_medialist==None: return image_specs =[ PPdefinitions.IMAGE_FILES, PPdefinitions.VIDEO_FILES, PPdefinitions.AUDIO_FILES, PPdefinitions.WEB_FILES, ('All files', '*')] #last one is ignored in finding files # in directory, for dialog box only directory=tkFileDialog.askdirectory(initialdir=self.options.initial_media_dir) # deal with tuple returned on Cancel if len(directory)==0: return # make list of exts we recognise exts = [] for image_spec in image_specs[:-1]: image_list=image_spec[1:] for ext in image_list: exts.append(copy.deepcopy(ext)) for file in os.listdir(directory): (root_file,ext_file)= os.path.splitext(file) if ext_file.lower() in exts: file_path=directory+os.sep+file #print "file path before ", file_path file_path=os.path.normpath(file_path) #print "file path after ", file_path self.add_track(file_path) self.save_medialist() def add_track(self,afile): relpath = os.path.relpath(afile,self.pp_home_dir) #print "relative path ",relpath common = os.path.commonprefix([afile,self.pp_home_dir]) #print "common ",common if common.endswith("pp_home") == False: location = afile else: location = "+" + os.sep + relpath location = string.replace(location,'\\','/') #print "location ",location (root,title)=os.path.split(afile) (root,ext)= os.path.splitext(afile) if ext.lower() in PPdefinitions.IMAGE_FILES: self.new_track(PPdefinitions.new_tracks['image'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.VIDEO_FILES: self.new_track(PPdefinitions.new_tracks['video'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.AUDIO_FILES: self.new_track(PPdefinitions.new_tracks['audio'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.WEB_FILES: self.new_track(PPdefinitions.new_tracks['web'],{'title':title,'track-ref':'','location':location}) else: self.mon.err(self,afile + " - file extension not recognised") # ********************************************* # update profile # ********************************************** def update_all(self): self.init() for profile_file in os.listdir(self.pp_home_dir+os.sep+'pp_profiles'): # self.mon.log (self,"Updating "+profile_file) self.pp_profile_dir = self.pp_home_dir+os.sep+'pp_profiles'+ os.sep + profile_file if not os.path.exists(self.pp_profile_dir+os.sep+"pp_showlist.json"): tkMessageBox.showwarning("Pi Presents","Not a profile, skipping "+self.pp_profile_dir) else: self.current_showlist=ShowList() #self.mon.log (self,"Checking version "+profile_file) self.current_showlist.open_json(self.pp_profile_dir+os.sep+"pp_showlist.json") if float(self.current_showlist.sissue())<float(self.editor_issue): self.mon.log(self,"Version of profile "+profile_file+ " is being updated to "+self.editor_issue) self.update_profile() elif (self.command_options['forceupdate'] == True and float(self.current_showlist.sissue())==float(self.editor_issue)): self.mon.log(self, "Forced updating of " + profile_file + ' to '+self.editor_issue) self.update_profile() elif float(self.current_showlist.sissue())>float(self.editor_issue): tkMessageBox.showwarning("Pi Presents", "Version of profile " +profile_file+ " is greater than editor, skipping") else: self.mon.log(self," Profile " + profile_file + " Already up to date ") self.init() tkMessageBox.showwarning("Pi Presents","All profiles updated") def update_profile(self): #open showlist and update its shows # self.mon.log (self,"Updating show ") ifile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", 'rb') shows = json.load(ifile)['shows'] ifile.close() replacement_shows=self.update_shows(shows) dic={'issue':self.editor_issue,'shows':replacement_shows} ofile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", "wb") json.dump(dic,ofile,sort_keys=True,indent=1) # UPDATE MEDIALISTS AND THEIR TRACKS for file in os.listdir(self.pp_profile_dir): if file.endswith(".json") and file<>'pp_showlist.json': # self.mon.log (self,"Updating medialist " + file) #open a medialist and update its tracks ifile = open(self.pp_profile_dir + os.sep + file, 'rb') tracks = json.load(ifile)['tracks'] ifile.close() replacement_tracks=self.update_tracks(tracks) dic={'issue':self.editor_issue,'tracks':replacement_tracks} ofile = open(self.pp_profile_dir + os.sep + file, "wb") json.dump(dic,ofile,sort_keys=True,indent=1) def update_tracks(self,old_tracks): # get correct spec from type of field replacement_tracks=[] for old_track in old_tracks: #print '\nold track ',old_track track_type=old_track['type'] spec_fields=PPdefinitions.new_tracks[track_type] left_overs=dict() # go through track and delete fields not in spec for key in old_track.keys(): if key in spec_fields: left_overs[key]=old_track[key] #print '\n leftovers',left_overs replacement_track=copy.deepcopy(PPdefinitions.new_tracks[track_type]) #print '\n before update', replacement_track replacement_track.update(left_overs) #print '\nafter update',replacement_track replacement_tracks.append(copy.deepcopy(replacement_track)) return replacement_tracks def update_shows(self,old_shows): # get correct spec from type of field replacement_shows=[] for old_show in old_shows: show_type=old_show['type'] spec_fields=PPdefinitions.new_shows[show_type] left_overs=dict() # go through track and delete fields not in spec for key in old_show.keys(): if key in spec_fields: left_overs[key]=old_show[key] # print '\n leftovers',left_overs replacement_show=copy.deepcopy(PPdefinitions.new_shows[show_type]) replacement_show.update(left_overs) replacement_shows.append(copy.deepcopy(replacement_show)) return replacement_shows
class PPWebEditor(App): def __init__(self, *args): # print 'DOIING _INIT do not use' super(PPWebEditor, self).__init__(*args) def main(self): # print 'DOING MAIN executed once when server starts' # *************************************** # INIT # *************************************** self.editor_issue="1.3" # get directory holding the code self.editor_dir=sys.path[0] ColourMap().init() # initialise editor options OSC config class, and OSC editors self.eo=Options() self.eo.init_options(self.editor_dir) self.osc_config=OSCConfig() self.osc_ute= OSCUnitType() # initialise variables self.init() # BUILD THE GUI # frames root = gui.Widget(width=900,height=500) #1 root.set_layout_orientation(gui.Widget.LAYOUT_VERTICAL) top_frame=gui.Widget(width=900,height=40)#1 top_frame.set_layout_orientation(gui.Widget.LAYOUT_HORIZONTAL) bottom_frame=gui.Widget(width=900,height=300)#1 bottom_frame.set_layout_orientation(gui.Widget.LAYOUT_HORIZONTAL) root.append(top_frame) root.append(bottom_frame) left_frame=gui.Widget(width=350,height=400)#1 left_frame.set_layout_orientation(gui.Widget.LAYOUT_VERTICAL) left_frame.style['margin']='10px' middle_frame=gui.VBox(width=50,height=300)#1 middle_frame.style['margin']='10px' # middle_frame.set_layout_orientation(gui.Widget.LAYOUT_VERTICAL) right_frame=gui.Widget(width=350,height=400)#1 right_frame.set_layout_orientation(gui.Widget.LAYOUT_VERTICAL) updown_frame=gui.VBox(width=50,height=300)#1 updown_frame.style['margin']='10px' # updown_frame.set_layout_orientation(gui.Widget.LAYOUT_VERTICAL) bottom_frame.append(left_frame) bottom_frame.append(middle_frame) bottom_frame.append(right_frame) bottom_frame.append(updown_frame) #menu menu = gui.Menu(width=700, height=30) top_frame.append(menu) #profile menu profile_menu = gui.MenuItem('Profile',width=80, height=30) profile_open_menu = gui.MenuItem('Open',width=120, height=30) profile_open_menu.set_on_click_listener(self,'open_existing_profile') profile_validate_menu = gui.MenuItem('Validate',width=120, height=30) profile_validate_menu.set_on_click_listener(self, 'validate_profile') profile_new_menu = gui.MenuItem('New',width=120, height=30) profile_menu.append(profile_open_menu) profile_menu.append(profile_validate_menu) profile_menu.append(profile_new_menu) pmenu = gui.MenuItem('Exhibit',width=150, height=30) pmenu.set_on_click_listener(self, 'new_exhibit_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Media Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_mediashow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Art Media Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_artmediashow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Menu',width=150, height=30) pmenu.set_on_click_listener(self, 'new_menu_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Presentation',width=150, height=30) pmenu.set_on_click_listener(self, 'new_presentation_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Interactive',width=150, height=30) pmenu.set_on_click_listener(self, 'new_interactive_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Live Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_liveshow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('Art Live Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_artliveshow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem('RadioButton Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_radiobuttonshow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem( 'Hyperlink Show',width=150, height=30) pmenu.set_on_click_listener(self, 'new_hyperlinkshow_profile') profile_new_menu.append(pmenu) pmenu = gui.MenuItem( 'Blank',width=150, height=30) pmenu.set_on_click_listener(self, 'new_blank_profile') profile_new_menu.append(pmenu) # shows menu show_menu = gui.MenuItem( 'Show',width=80, height=30) show_delete_menu = gui.MenuItem('Delete',width=120, height=30) show_delete_menu.set_on_click_listener(self, 'remove_show') show_edit_menu = gui.MenuItem('Edit',width=120, height=30) show_edit_menu.set_on_click_listener(self, 'm_edit_show') show_copy_to_menu = gui.MenuItem( 'Copy To',width=120, height=30) show_copy_to_menu.set_on_click_listener(self, 'copy_show') show_add_menu = gui.MenuItem( 'Add',width=120, height=30) show_menu.append(show_delete_menu) show_menu.append(show_edit_menu) show_menu.append(show_copy_to_menu) show_menu.append(show_add_menu) pmenu = gui.MenuItem('Menu',width=150, height=30) pmenu.set_on_click_listener(self, 'add_menushow') show_add_menu.append(pmenu) pmenu = gui.MenuItem( 'Media Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_mediashow') show_add_menu.append(pmenu) pmenu = gui.MenuItem('Live Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_liveshow') show_add_menu.append(pmenu) pmenu = gui.MenuItem('Hyperlink Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_hyperlinkshow') show_add_menu.append(pmenu) pmenu = gui.MenuItem('RadioButton Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_radiobuttonshow') show_add_menu.append(pmenu) pmenu = gui.MenuItem( 'Art Mediashow Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_artmediashow') show_add_menu.append(pmenu) pmenu = gui.MenuItem( 'Art Liveshow Show',width=150, height=30) pmenu.set_on_click_listener(self, 'add_artliveshow') show_add_menu.append(pmenu) # medialists menu medialist_menu = gui.MenuItem( 'Medialist',width=80, height=30) medialist_delete_menu = gui.MenuItem( 'Delete',width=120, height=30) medialist_delete_menu.set_on_click_listener(self, 'remove_medialist') medialist_add_menu = gui.MenuItem( 'Add',width=120, height=30) medialist_add_menu.set_on_click_listener(self, 'add_medialist') medialist_copy_to_menu = gui.MenuItem('Copy To',width=120, height=30) medialist_copy_to_menu.set_on_click_listener(self, 'copy_medialist') medialist_menu.append(medialist_add_menu) medialist_menu.append(medialist_delete_menu) medialist_menu.append(medialist_copy_to_menu) # tracks menu track_menu = gui.MenuItem('Track',width=80, height=30) track_delete_menu = gui.MenuItem('Delete',width=120, height=30) track_delete_menu.set_on_click_listener(self, 'remove_track') track_edit_menu = gui.MenuItem( 'Edit',width=120, height=30) track_edit_menu.set_on_click_listener(self, 'm_edit_track') track_add_from_dir_menu = gui.MenuItem('Add Directory',width=120, height=30) track_add_from_dir_menu.set_on_click_listener(self, 'add_tracks_from_dir') track_add_from_file_menu = gui.MenuItem('Add File',width=120, height=30) track_add_from_file_menu.set_on_click_listener(self, 'add_track_from_file') track_new_menu = gui.MenuItem('New',width=120, height=30) track_new_video_menu = gui.MenuItem('Video',width=120, height=30) track_new_video_menu.set_on_click_listener(self, 'new_video_track') track_new_audio_menu = gui.MenuItem('Audio',width=120,height=30) track_new_audio_menu.set_on_click_listener(self, 'new_audio_track') track_new_image_menu = gui.MenuItem( 'Image',width=120, height=30) track_new_image_menu.set_on_click_listener(self, 'new_image_track') track_new_web_menu = gui.MenuItem( 'Web',width=120, height=30) track_new_web_menu.set_on_click_listener(self, 'new_web_track') track_new_message_menu = gui.MenuItem('Message',width=120, height=30) track_new_message_menu.set_on_click_listener(self, 'new_message_track') track_new_show_menu = gui.MenuItem('Show',width=120, height=30) track_new_show_menu.set_on_click_listener(self, 'new_show_track') track_new_menu_menu = gui.MenuItem('Menu',width=120, height=30) track_new_menu_menu.set_on_click_listener(self, 'new_menu_track') track_new_menu.append(track_new_video_menu) track_new_menu.append(track_new_audio_menu) track_new_menu.append(track_new_image_menu) track_new_menu.append(track_new_web_menu) track_new_menu.append(track_new_message_menu) track_new_menu.append(track_new_show_menu) track_new_menu.append(track_new_menu_menu) track_menu.append(track_delete_menu) track_menu.append(track_edit_menu) track_menu.append(track_add_from_dir_menu) track_menu.append(track_add_from_file_menu) track_menu.append(track_new_menu) options_menu = gui.MenuItem('Options',width=80, height=30) options_edit_menu=gui.MenuItem('Edit',width=80, height=30) options_edit_menu.set_on_click_listener(self, 'edit_options') options_menu.append(options_edit_menu) # osc menu osc_menu = gui.MenuItem( 'OSC',width=80, height=30) osc_create_menu = gui.MenuItem( 'Create',width=120, height=30) osc_create_menu.set_on_click_listener(self, 'create_osc') osc_edit_menu = gui.MenuItem( 'Edit',width=120, height=30) osc_edit_menu.set_on_click_listener(self, 'edit_osc') osc_delete_menu = gui.MenuItem( 'Delete',width=120, height=30) osc_delete_menu.set_on_click_listener(self, 'delete_osc') osc_menu.append(osc_create_menu) osc_menu.append(osc_edit_menu) osc_menu.append(osc_delete_menu) # help menu help_menu = gui.MenuItem( 'Help',width=80, height=30) help_text_menu = gui.MenuItem( 'Help',width=80, height=30) help_text_menu.set_on_click_listener(self, 'show_help') about_menu = gui.MenuItem( 'About',width=80, height=30) about_menu.set_on_click_listener(self, 'show_about') help_menu.append(help_text_menu) help_menu.append(about_menu) menu.append(profile_menu) menu.append(show_menu) menu.append(medialist_menu) menu.append(track_menu) menu.append(osc_menu) menu.append(options_menu) menu.append(help_menu) #shows and medialists shows_label=gui.Label('<b>Shows</b>',width=300, height=20) shows_label.style['margin']='5px' self.shows_display= gui.ListView(width=350, height=150) self.shows_display.set_on_selection_listener(self,'show_selected') medialists_label=gui.Label('<b>Medialists</b>',width=300, height=20) medialists_label.style['margin']='5px' self.medialists_display= gui.ListView(width=350, height=150) self.medialists_display.set_on_selection_listener(self,'medialist_selected') left_frame.append(shows_label) left_frame.append(self.shows_display) left_frame.append(medialists_label) left_frame.append(self.medialists_display) #edit show button edit_show = gui.Button('Edit\nShow',width=50, height=50) edit_show.set_on_click_listener(self, 'm_edit_show') middle_frame.append(edit_show) #tracks tracks_label=gui.Label('<b>Tracks in Selected Medialist</b>',width=300, height=20) tracks_label.style['margin']='5px' self.tracks_display= gui.ListView(width=350, height=300) self.tracks_display.set_on_selection_listener(self,'track_selected') right_frame.append(tracks_label) right_frame.append(self.tracks_display) #tracks buttons add_track = gui.Button('Add',width=50, height=50) add_track.set_on_click_listener(self, 'add_track_from_file') updown_frame.append(add_track) edit_track = gui.Button('Edit',width=50, height=50) edit_track.set_on_click_listener(self, 'm_edit_track') updown_frame.append(edit_track) up_track = gui.Button('Up',width=50, height=50) up_track.set_on_click_listener(self, 'move_track_up') updown_frame.append(up_track) down_track = gui.Button('Down',width=50, height=50) down_track.set_on_click_listener(self, 'move_track_down') updown_frame.append(down_track) return root def init(self): # print 'init' self.eo.read_options() self.pp_home_dir = self.eo.pp_home_dir self.pp_profiles_offset = self.eo.pp_profiles_offset self.initial_media_dir = self.eo.initial_media_dir self.pp_profile_dir='' self.current_medialist=None self.current_showlist=None self.current_show=None def empty_lists(self): # print 'empty lists' self.shows_display.empty() self.medialists_display.empty() self.tracks_display.empty() def show_help (self): OKDialog("Help","Please Read 'manual.pdf'",width=400,height=200).show(self) def show_about (self): OKDialog("About","Web Editor for Pi Presents Profiles<br>" +"For profiles of version: " + self.editor_issue + "<br>Author: Ken Thompson" +"<br>Website: http://pipresents.wordpress.com/<br>",width=400,height=200).show(self) def validate_profile(self): if self.current_showlist != None: val =Validator('Validation Result') val.show(self) val.validate_profile(self.editor_dir,self.pp_home_dir,self.pp_profile_dir,self.editor_issue,True) # ************** # OPTIONS # ************** def edit_options(self): self.eo.edit(self.edit_options_callback) self.eo.show(self) def edit_options_callback(self): # self.eo.show(self) self.eo.read_options() self.init() self.empty_lists() # ************** # OSC CONFIGURATION # ************** def create_osc(self): if self.pp_profile_dir=='': return # print 'create',OSCConfig.options_file if self.osc_config.read() is False: iodir=self.pp_profile_dir+os.sep+'pp_io_config' if not os.path.exists(iodir): os.makedirs(iodir) self.osc_config.create() def edit_osc(self): # print 'edit',OSCConfig.options_file if self.osc_config.read() is False: # print 'no config file' return self.osc_ute.edit(self.edit_osc_callback) self.osc_ute.show(self) def edit_osc_callback(self): # self.osc_ute.hide() # print 'edit callback', OSCConfig.current_unit_type self.osc_editor=OSCWebEditor() if OSCConfig.current_unit_type != '': self.osc_editor.edit() self.osc_editor.show(self) def delete_osc(self): if self.osc_config.read() is False: return self.osc_config.delete() # ************** # PROFILES # ************** def open_existing_profile(self): initial_dir=self.pp_home_dir+os.sep+"pp_profiles"+self.pp_profiles_offset if os.path.exists(initial_dir) is False: OKDialog('Open Profile',"Profiles directory not found: " + initial_dir + "<br><br>Hint: Data Home option must end in pp_home").show(self) return open_existing_profile_dialog = gui.FileSelectionDialog('Open Profile','Select profile',False, initial_dir) #width=600,height=200, open_existing_profile_dialog.set_on_confirm_value_listener(self, 'open_existing_profile_dialog_confirm') open_existing_profile_dialog.show(self) def open_existing_profile_dialog_confirm(self, filelist): if len(filelist)==0: OKDialog('Open Profile',"Nothing Selected").show(self) return # print 'filelist',filelist[0] self.open_profile(filelist[0]) def open_profile(self,dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" #print 'open profile',showlist_file if os.path.exists(showlist_file) is False: OKDialog('Open Profile',"Not a Profile: " + dir_path).show(self) return self.pp_profile_dir = dir_path OSCConfig.options_file=self.pp_profile_dir+ os.sep+'pp_io_config'+os.sep+'osc.cfg' # print 'profile direcotry',self.pp_profile_dir # self.root.title("Editor for Pi Presents - "+ self.pp_profile_dir) if self.open_showlist(self.pp_profile_dir) is False: self.init() self.empty_lists() return self.open_medialists(self.pp_profile_dir) self.refresh_tracks_display() self.osc_config_file=self.pp_profile_dir+os.sep+'pp_io_config'+os.sep+'osc.cfg' def new_profile(self,profile): d = gui.InputDialog("New Profile","Name",width=400,height=250) self.new_profile_template=profile d.set_on_confirm_value_listener(self, 'new_profile_confirm') d.show(self) def new_profile_confirm(self,name): if name == "": OKDialog("New Profile","Name is blank").show(self) return to = self.pp_home_dir + os.sep + "pp_profiles"+ self.pp_profiles_offset + os.sep + name if os.path.exists(to) is True: OKDialog( "New Profile","Profile exists\n(%s)" % to ).show(self) return shutil.copytree(self.new_profile_template, to, symlinks=False, ignore=None) self.open_profile(to) def new_exhibit_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_exhibit_1p3' self.new_profile(profile) def new_interactive_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_interactive_1p3' self.new_profile(profile) def new_menu_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_menu_1p3' self.new_profile(profile) def new_presentation_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_presentation_1p3' self.new_profile(profile) def new_blank_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep +"ppt_blank_1p3" self.new_profile(profile) def new_mediashow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_mediashow_1p3' self.new_profile(profile) def new_liveshow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_liveshow_1p3' self.new_profile(profile) def new_artmediashow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artmediashow_1p3' self.new_profile(profile) def new_artliveshow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artliveshow_1p3' self.new_profile(profile) def new_radiobuttonshow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_radiobuttonshow_1p3' self.new_profile(profile) def new_hyperlinkshow_profile(self): profile = self.editor_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_hyperlinkshow_1p3' self.new_profile(profile) # *************************************** # Shows # *************************************** # !!!!! changed app_exit to return def open_showlist(self,profile_dir): showlist_file = profile_dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: OKDialog('Open Profile',"showlist file not found at " + profile_dir + "<br><br>Hint: Have you opened the profile directory?").show(self) return False self.current_showlist=ShowList() self.current_showlist.open_json(showlist_file) if float(self.current_showlist.sissue())<float(self.editor_issue): self.update_profile() OKDialog('Open Profile',"Version of profile has been updated to "+self.editor_issue+", please re-open").show(self) return False if float(self.current_showlist.sissue())>float(self.editor_issue): OKDialog('Open Profile',"Version of profile is greater than editor").show(self) return False self.refresh_shows_display() return True def save_showlist(self,showlist_dir): if self.current_showlist is not None: showlist_file = showlist_dir + os.sep + "pp_showlist.json" self.current_showlist.save_list(showlist_file) def add_mediashow(self): self.add_show(PPdefinitions.new_shows['mediashow']) def add_liveshow(self): self.add_show(PPdefinitions.new_shows['liveshow']) def add_radiobuttonshow(self): self.add_show(PPdefinitions.new_shows['radiobuttonshow']) def add_hyperlinkshow(self): self.add_show(PPdefinitions.new_shows['hyperlinkshow']) def add_artliveshow(self): self.add_show(PPdefinitions.new_shows['artliveshow']) def add_artmediashow(self): self.add_show(PPdefinitions.new_shows['artmediashow']) def add_menushow(self): self.add_show(PPdefinitions.new_shows['menu']) def add_start(self): self.add_show(PPdefinitions.new_shows['start']) def add_show(self,default): # append it to the showlist and then add the medialist if self.current_showlist is not None: self.default_show=default d = gui.InputDialog("Add Show","Show Reference",width=400,height=250) d.set_on_confirm_value_listener(self, 'add_show_confirm') d.show(self) def add_show_confirm(self,name): # print 'show name',name if name == "": OKDialog("Add Show","Name is blank").show(self) return if self.current_showlist.index_of_show(name) != -1: OKDialog("Add Show","A Show with this name already exists").show(self) return # print 'copy show template',self.default_show,name copied_show=self.current_showlist.copy(self.default_show,name) # print 'add mediafile from show',name mediafile=self.add_medialist(name) # print 'mediafile added',mediafile if mediafile != '': copied_show['medialist']=mediafile self.current_showlist.append(copied_show) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def remove_show(self): if self.current_showlist is not None and self.current_showlist.length()>0 and self.current_showlist.show_is_selected(): OKCancelDialog("Delete Show","Are you sure?",self.remove_show_confirm).show(self) def remove_show_confirm(self,result): if result is True: index= self.current_showlist.selected_show_index() self.current_showlist.remove(index) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def show_refs(self): _show_refs=[] for index in range(self.current_showlist.length()): if self.current_showlist.show(index)['show-ref'] != "start": _show_refs.append(copy.deepcopy(self.current_showlist.show(index)['show-ref'])) return _show_refs def refresh_shows_display(self): self.shows_display.empty() key=0 for index in range(self.current_showlist.length()): value= self.current_showlist.show(index)['title']+" ["+self.current_showlist.show(index)['show-ref']+"]" obj = gui.ListItem(value,width=340, height=20) self.shows_display.append(obj,key=key) key+=1 if self.current_showlist.show_is_selected(): self.shows_display.select_by_key(self.current_showlist.selected_show_index()) # self.shows_display.show() def show_selected(self,event): if self.current_showlist is not None and self.current_showlist.length()>0: mouse_item_index=self.shows_display.get_key() self.current_showlist.select(mouse_item_index) self.refresh_shows_display() def copy_show(self): if self.current_showlist is not None and self.current_showlist.show_is_selected(): self.add_show(self.current_showlist.selected_show()) def m_edit_show(self): self.edit_show(PPdefinitions.show_types,PPdefinitions.show_field_specs) def edit_show(self,show_types,field_specs): if self.current_showlist is not None and self.current_showlist.show_is_selected(): self.edit_show_dialog=WebEditItem("Edit Show",self.current_showlist.selected_show(),show_types,field_specs,self.show_refs(), self.initial_media_dir,self.pp_home_dir,'show',self.finished_edit_show) self.edit_show_dialog.show(self) self.edit_show_dialog.show_tab('show') def finished_edit_show(self): self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() # *************************************** # Medialists # *************************************** def open_medialists(self,profile_dir): self.medialists = [] for this_file in os.listdir(profile_dir): if this_file.endswith(".json") and this_file not in ('pp_showlist.json','schedule.json'): self.medialists = self.medialists + [this_file] self.medialists_display.empty() key=0 for index in range (len(self.medialists)): obj = gui.ListItem(self.medialists[index],width=340, height=20) self.medialists_display.append(obj, key=key) key+=1 self.current_medialists_index=-1 self.current_medialist=None def add_medialist(self,name=None): if self.current_showlist != None: if name is None: d = gui.InputDialog("Add Medialist","File",width=400,height=250) d.set_on_confirm_value_listener(self, 'add_medialist_confirm') d.show(self) else: medialist_name=self.add_medialist_confirm(name) return medialist_name def add_medialist_confirm(self,name): # print 'add medialist',name if name == "": OKDialog("Add Medialist","Name is blank").show(self) return '' if self.current_showlist.index_of_show(name) != -1: OKDialog("Add Medialist","A medialist with this name already exists").show(self) return '' if not name.endswith(".json"): name=name+(".json") path = self.pp_profile_dir + os.sep + name if os.path.exists(path) is True: OKDialog("Add Medialist","Medialist file exists<br>(%s)" % path).show(self) return '' nfile = open(path,'wb') nfile.write("{") nfile.write("\"issue\": \""+self.editor_issue+"\",\n") nfile.write("\"tracks\": [") nfile.write("]") nfile.write("}") nfile.close() # append it to the list self.medialists.append(copy.deepcopy(name)) # print 'medialists',self.medialists # add title to medialists display # self.medialists_display.insert(END, name) # and set it as the selected medialist self.refresh_medialists_display() # print 'returning medilaist name',name return name def copy_medialist(self,to_file=None): if self.current_showlist != None: if self.current_medialist is not None: #from_file= self.current_medialist self.from_file= self.medialists[self.current_medialists_index] if to_file is None: d = gui.InputDialog("Copy Medialist","File",width=400,height=250) d.set_on_confirm_value_listener(self, 'copy_medialist_confirm') d.show(self) else: self.copy_medialist_confirm(to_file) def copy_medialist_confirm(self,to_file): # print self.from_file,to_file if to_file == "": OKDialog("Copy Medialist","Name is blank").show(self) return '' success_file = self.copy_medialist_file(self.from_file,to_file) if success_file =='': return '' # append it to the list self.medialists.append(copy.deepcopy(success_file)) # add title to medialists display # self.medialists_display.insert(END, success_file) # and reset selected medialist self.current_medialist=None self.refresh_medialists_display() self.refresh_tracks_display() return success_file def copy_medialist_file(self,from_file,to_file): if not to_file.endswith(".json"): to_file+=(".json") to_path = self.pp_profile_dir + os.sep + to_file if os.path.exists(to_path) is True: OKDialog("Copy Medialist","Medialist file exists\n(%s)" % to_path).show(self) return '' from_path= self.pp_profile_dir + os.sep + from_file if os.path.exists(from_path) is False: OKDialog("Copy Medialist","Medialist file not found\n(%s)" % from_path).show(self) return '' shutil.copy(from_path,to_path) return to_file def remove_medialist(self): if self.current_medialist is not None: OKCancelDialog("Delete Medialist","Are you sure?",self.remove_medialist_confirm).show(self) def remove_medialist_confirm(self,result): if result is True: os.remove(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index]) self.open_medialists(self.pp_profile_dir) self.refresh_medialists_display() self.refresh_tracks_display() # removed appexit def medialist_selected(self,key): """ user clicks on a medialst in a profile so try and select it. """ # print 'selected',type(self.medialists_display.get_key()),self.medialists_display.get_key() if len(self.medialists)>0: self.current_medialists_index=self.medialists_display.get_key() self.current_medialist=MediaList('ordered') if not self.current_medialist.open_list(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index],self.current_showlist.sissue()): OKDialog(self,"medialist is a different version to showlist: "+ self.medialists[self.current_medialists_index]).show(self) #self.app_exit() return self.refresh_tracks_display() self.refresh_medialists_display() def refresh_medialists_display(self): # print 'refresh medialists' self.medialists_display.empty() key=0 for index in range (len(self.medialists)): obj = gui.ListItem(self.medialists[index],width=340, height=20) self.medialists_display.append(obj,key=key) key+=1 if self.current_medialist is not None: self.medialists_display.select_by_key(self.current_medialists_index) # self.medialists_display.show(self) def save_medialist(self): basefile=self.medialists[self.current_medialists_index] # print type(basefile) # basefile=str(basefile) # print type(basefile) medialist_file = self.pp_profile_dir+ os.sep + basefile self.current_medialist.save_list(medialist_file) # *************************************** # Tracks # *************************************** def refresh_tracks_display(self): self.tracks_display.empty() if self.current_medialist is not None: key=0 for index in range(self.current_medialist.length()): if self.current_medialist.track(index)['track-ref'] != '': track_ref_string=" ["+self.current_medialist.track(index)['track-ref']+"]" else: track_ref_string="" obj = gui.ListItem(self.current_medialist.track(index)['title']+track_ref_string,width=340, height=20) self.tracks_display.append(obj,key=key) key+=1 if self.current_medialist.track_is_selected(): self.tracks_display.select_by_key(self.current_medialist.selected_track_index()) def track_selected(self,key): # print 'track sel', type(self.tracks_display.get_key()) if self.current_medialist is not None and self.current_medialist.length()>0: mouse_item_index=self.tracks_display.get_key() self.current_medialist.select(mouse_item_index) self.refresh_tracks_display() def m_edit_track(self): self.edit_track(PPdefinitions.track_types,PPdefinitions.track_field_specs) def edit_track(self,track_types,field_specs): if self.current_medialist is not None and self.current_medialist.track_is_selected(): self.edit_track_dialog=WebEditItem("Edit Track",self.current_medialist.selected_track(),track_types,field_specs, self.show_refs(),self.initial_media_dir,self.pp_home_dir,'track',self.finished_edit_track) self.edit_track_dialog.show(self) self.edit_track_dialog.show_tab('track') def finished_edit_track(self): self.refresh_tracks_display() self.save_medialist() def move_track_up(self): if self.current_medialist is not None and self.current_medialist.track_is_selected(): self.current_medialist.move_up() self.refresh_tracks_display() self.save_medialist() def move_track_down(self): if self.current_medialist is not None and self.current_medialist.track_is_selected(): self.current_medialist.move_down() self.refresh_tracks_display() self.save_medialist() def new_track(self,fields,values): if self.current_medialist is not None: # print '\nfields ', fields # print '\nvalues ', values new_track=copy.deepcopy(fields) # print ',\new track ',new_track self.current_medialist.append(new_track) # print '\nbefore values ',self.current_medialist.print_list() if values is not None: self.current_medialist.update(self.current_medialist.length()-1,values) self.current_medialist.select(self.current_medialist.length()-1) self.refresh_tracks_display() self.save_medialist() def new_message_track(self): self.new_track(PPdefinitions.new_tracks['message'],None) def new_video_track(self): self.new_track(PPdefinitions.new_tracks['video'],None) def new_audio_track(self): self.new_track(PPdefinitions.new_tracks['audio'],None) def new_web_track(self): self.new_track(PPdefinitions.new_tracks['web'],None) def new_image_track(self): self.new_track(PPdefinitions.new_tracks['image'],None) def new_show_track(self): self.new_track(PPdefinitions.new_tracks['show'],None) def new_menu_track(self): # print 'new menu track' self.new_track(PPdefinitions.new_tracks['menu'],None) def remove_track(self): if self.current_medialist is not None and self.current_medialist.length()>0 and self.current_medialist.track_is_selected(): OKCancelDialog("Delete Track","Are you sure?",self.remove_track_confirm).show(self) def remove_track_confirm(self,result): # print 'confirm',result if result is True: index= self.current_medialist.selected_track_index() self.current_medialist.remove(index) self.save_medialist() self.refresh_tracks_display() def add_track_from_file(self): if self.current_medialist is None: return add_track_from_file_dialog = gui.FileSelectionDialog('Add Track', 'Select Tracks',True, self.eo.initial_media_dir)#600,200, add_track_from_file_dialog.set_on_confirm_value_listener(self, 'add_track_from_file_dialog_confirm') add_track_from_file_dialog.show(self) def add_track_from_file_dialog_confirm(self, filelist): if len(filelist)==0: OKDialog('Add Track',"Nothing Selected").show(self) return for file_path in filelist: file_path=os.path.normpath(file_path) # print "file path ", file_path self.add_track(file_path) self.save_medialist() def add_tracks_from_dir(self): if self.current_medialist is None: return add_tracks_from_dir_dialog = gui.FileSelectionDialog('Add Directory', 'Select Directory', multiple_selection = False, allow_file_selection=False, selection_folder = self.eo.initial_media_dir) add_tracks_from_dir_dialog.set_on_confirm_value_listener(self, 'add_tracks_from_dir_dialog_confirm') add_tracks_from_dir_dialog.show(self) def add_tracks_from_dir_dialog_confirm(self, result): image_specs =[PPdefinitions.IMAGE_FILES,PPdefinitions.VIDEO_FILES,PPdefinitions.AUDIO_FILES, PPdefinitions.WEB_FILES,('All files', '*')] # last one is ignored in finding files in directory, for dialog box only if len(result) == 0: OKDialog('Add Tracks',"Nothing Selected").show(self) return directory=result[0] # make list of exts we recognise exts = [] for image_spec in image_specs[:-1]: image_list=image_spec[1:] for ext in image_list: exts.append(copy.deepcopy(ext)) for this_file in os.listdir(directory): (root_file,ext_file)= os.path.splitext(this_file) if ext_file.lower() in exts: file_path=directory+os.sep+this_file # print "file path before ", file_path file_path=os.path.normpath(file_path) # print "file path after ", file_path self.add_track(file_path) self.save_medialist() def add_track(self,afile): relpath = os.path.relpath(afile,self.pp_home_dir) # print "relative path ",relpath common = os.path.commonprefix([afile,self.pp_home_dir]) # print "common ",common if common.endswith("pp_home") is False: location = afile else: location = "+" + os.sep + relpath location = string.replace(location,'\\','/') # print "location ",location (root,title)=os.path.split(afile) (root,ext)= os.path.splitext(afile) if ext.lower() in PPdefinitions.IMAGE_FILES: self.new_track(PPdefinitions.new_tracks['image'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.VIDEO_FILES: self.new_track(PPdefinitions.new_tracks['video'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.AUDIO_FILES: self.new_track(PPdefinitions.new_tracks['audio'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.WEB_FILES: self.new_track(PPdefinitions.new_tracks['web'],{'title':title,'track-ref':'','location':location}) else: OKDialog('Add Track',afile + " - cannot determine track type, use menu track>new").show(self)