def __init__(self, generator_facade): self.root = tk.Tk() self.root.title('Composer') self.root.resizable(False, False) self.model_label_text = StringVar() self.duration_seconds = StringVar() self.player_time = StringVar() self.should_timer_stop = False self.generator_facade = generator_facade self.canvas = tk.Canvas(self.root, height=self.HEIGHT, width=self.WIDTH, highlightthickness=0, bg=GUIUtils.BACKGROUND_COLOR) self.background_image = GUIUtils.get_background_image() self.canvas.create_image(0, 0, image=self.background_image, anchor='nw') self.create_model_button = GUIUtils.init_button( self.root, 'create model', self.create_model_button_callback) self.load_model_button = GUIUtils.init_button( self.root, 'load model', self.load_model_button_callback) self.save_model_button = GUIUtils.init_button( self.root, 'save model', self.save_model_button_callback, 'disabled') self.model_label = GUIUtils.set_label( self.canvas, relx=0.1, rely=0.05, stringvar=self.model_label_text, change_callback=self.on_model_label_change) self.generate_button = GUIUtils.init_button( self.root, 'generate', self.generate_button_callback, 'disabled') self.save_melody_button = GUIUtils.init_button( self.root, 'save melody', self.save_melody_button_callback, 'disabled') self.play_icon = tk.PhotoImage(file='./img/play2.png') self.stop_icon = tk.PhotoImage(file='./img/stop2.png') self.melody_progress_bar = ttk.Progressbar(self.root, orient='horizontal', length=300, mode='determinate') self.player_time_label = GUIUtils.set_label( self.canvas, relx=0.4, rely=0.65, stringvar=self.player_time, change_callback=self.on_timer_label_change) self.play_melody_button = GUIUtils.init_button( self.root, None, self.play_melody_button_callback, 'disabled', 50) self.stop_melody_button = GUIUtils.init_button( self.root, None, self.stop_melody_button_callback, 'disabled', 50) self.init_widgets()
def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.mln', 'ftypes': [('MLN files', '.mln')] }, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.emln', 'ftypes': [('MLN extension files', '.emln') ] }, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.db', 'ftypes': [('Database files', '.db')] }, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton( option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project':self.project_dir] is not None: self.load_project( os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True
class MLNQueryGUI(object): def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.mln', 'ftypes': [('MLN files', '.mln')] }, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.emln', 'ftypes': [('MLN extension files', '.emln') ] }, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={ 'extension': '.db', 'ftypes': [('Database files', '.db')] }, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton( option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath( ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project':self.project_dir] is not None: self.load_project( os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True def _got_focus(self, *_): if self.master.focus_get() == self.mln_container.editor: if not self.project.mlns and not self.mln_container.file_buffer: self.mln_container.new_file() elif self.master.focus_get() == self.db_container.editor: if not self.project.dbs and not self.db_container.file_buffer: self.db_container.new_file() elif self.master.focus_get() == self.emln_container.editor: if not self.project.emlns and not self.emln_container.file_buffer: self.emln_container.new_file() def quit(self): if self.settings_dirty.get() or self.project_dirty.get(): savechanges = messagebox.askyesnocancel( "Save changes", "You have unsaved project changes. Do you want to save them before quitting?" ) if savechanges is None: return elif savechanges: self.noask_save_project() self.master.destroy() else: # write gui settings and destroy self.write_gconfig() self.master.destroy() ####################### PROJECT FUNCTIONS ################################# def new_project(self): self.project = MLNProject() self.project.addlistener(self.project_setdirty) self.project.name = DEFAULTNAME.format('.pracmln') self.reset_gui() self.set_config(self.project.queryconf) self.mln_container.update_file_choices() self.emln_container.update_file_choices() self.db_container.update_file_choices() self.project_setdirty(dirty=True) def project_setdirty(self, dirty=False, *args): self.project_dirty.set(dirty or self.mln_container.dirty or self.db_container.dirty or self.emln_container.dirty) self.changewindowtitle() def settings_setdirty(self, *args): self.settings_dirty.set(1) self.changewindowtitle() def changewindowtitle(self): title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name) self.master.title(title) def ask_load_project(self): filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") if filename and os.path.exists(filename): self.load_project(filename) else: logger.info('No file selected.') return def load_project(self, filename): if filename and os.path.exists(filename): projdir, _ = ntpath.split(filename) self.dir = os.path.abspath(projdir) self.project_dir = os.path.abspath(projdir) self.project = MLNProject.open(filename) self.project.addlistener(self.project_setdirty) self.reset_gui() self.set_config(self.project.queryconf.config) self.mln_container.update_file_choices() self.db_container.update_file_choices() if len(self.project.mlns) > 0: self.mln_container.selected_file.set( self.project.queryconf['mln'] or list(self.project.mlns.keys())[0]) self.mln_container.dirty = False if len(self.project.emlns) > 0: self.emln_container.selected_file.set( self.project.queryconf['emln'] or list(self.project.emlns.keys())[0]) self.emln_container.dirty = False if len(self.project.dbs) > 0: self.db_container.selected_file.set( self.project.queryconf['db'] or list(self.project.dbs.keys())[0]) self.db_container.dirty = False self.write_gconfig(savegeometry=False) self.settings_dirty.set(0) self.project_setdirty(dirty=False) self.changewindowtitle() else: logger.error( 'File {} does not exist. Creating new project...'.format( filename)) self.new_project() def noask_save_project(self): if self.project.name and not self.project.name == DEFAULTNAME.format( '.pracmln'): self.save_project(os.path.join(self.project_dir, self.project.name)) else: self.ask_save_project() def ask_save_project(self): fullfilename = asksaveasfilename(initialdir=self.project_dir, confirmoverwrite=True, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") self.save_project(fullfilename) def save_project(self, fullfilename): if fullfilename: fpath, fname = ntpath.split(fullfilename) fname = fname.split('.')[0] self.project.name = fname self.dir = os.path.abspath(fpath) self.project_dir = os.path.abspath(fpath) self.mln_container.save_all_files() self.emln_container.save_all_files() self.db_container.save_all_files() self.update_config() self.project.save(dirpath=self.project_dir) self.write_gconfig() self.load_project(fullfilename) self.settings_dirty.set(0) def save_proj(self): self.project.save(dirpath=self.project_dir) self.write_gconfig() self.project_setdirty(dirty=False) ####################### MLN FUNCTIONS ##################################### def import_mln(self, name, content): self.project.add_mln(name, content) def delete_mln(self, fname): if fname in self.project.mlns: self.project.rm_mln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.mlns: self.project.rm_mln(fnamestr) def update_mln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.mln_container.selected_file.get() if new is None: new = self.mln_container.selected_file.get().strip('*') if content is None: content = self.mln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.mlns[old] = content else: if new in self.project.mlns: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.mlns[new] = content return 1 def mlnfiles(self): return list(self.project.mlns.keys()) def mlnfilecontent(self, filename): return self.project.mlns.get(filename, '').strip() # /MLN FUNCTIONS ##################################### ####################### EMLN FUNCTIONS ##################################### def import_emln(self, name, content): self.project.add_emln(name, content) def delete_emln(self, fname): if fname in self.project.emlns: self.project.rm_emln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.emlns: self.project.rm_emln(fnamestr) def update_emln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.emln_container.selected_file.get() if new is None: new = self.emln_container.selected_file.get().strip('*') if content is None: content = self.emln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.emlns[old] = content else: if new in self.project.emlns: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.emlns[new] = content return 1 def emlnfiles(self): return list(self.project.emlns.keys()) def emlnfilecontent(self, filename): return self.project.emlns.get(filename, '').strip() # /EMLN FUNCTIONS ##################################### # DB FUNCTIONS ##################################### def import_db(self, name, content): self.project.add_db(name, content) def delete_db(self, fname): if fname in self.project.dbs: self.project.rm_db(fname) fnamestr = fname.strip('*') if fnamestr in self.project.dbs: self.project.rm_db(fnamestr) def update_db(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.db_container.selected_file.get() if new is None: new = self.db_container.selected_file.get().strip('*') if content is None: content = self.db_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.dbs[old] = content else: if new in self.project.dbs: if askoverwrite: savechanges = messagebox.askyesno( "Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[new] = content else: logger.error('no name specified!') return -1 else: self.project.dbs[new] = content return 1 def dbfiles(self): return list(self.project.dbs.keys()) def dbfilecontent(self, filename): return self.project.dbs.get(filename, '').strip() # /DB FUNCTIONS ##################################### # GENERAL FUNCTIONS ################################# def select_method(self, *args): self.set_outputfilename() self.settings_setdirty() def onchange_use_emln(self, dirty=True, *args): if not self.use_emln.get(): self.emln_label.grid_forget() self.emln_container.grid_forget() else: self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky="NE") self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NWES") if dirty: self.settings_setdirty() def onchange_cw(self, *args): if self.closed_world.get(): self.entry_cw.configure(state=DISABLED) else: self.entry_cw.configure(state=NORMAL) self.settings_setdirty() def reset_gui(self): self.set_config({}) self.db_container.clear() self.emln_container.clear() self.mln_container.clear() def set_config(self, newconf): self.config = newconf self.selected_grammar.set(ifnone(newconf.get('grammar'), 'PRACGrammar')) self.selected_logic.set(ifnone(newconf.get('logic'), 'FirstOrderLogic')) self.mln_container.selected_file.set(ifnone(newconf.get('mln'), '')) if self.use_emln.get(): self.emln_container.selected_file.set( ifnone(newconf.get('mln'), '')) self.db_container.selected_file.set(ifnone(newconf.get('db'), "")) self.selected_method.set( ifnone(newconf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name)) self.multicore.set(ifnone(newconf.get('multicore'), 0)) self.profile.set(ifnone(newconf.get('profile'), 0)) self.params.set(ifnone(newconf.get('params'), '')) self.use_emln.set(ifnone(newconf.get('use_emln'), 0)) self.verbose.set(ifnone(newconf.get('verbose'), 1)) self.ignore_unknown_preds.set( ifnone(newconf.get('ignore_unknown_preds'), 0)) self.output_filename.set(ifnone(newconf.get('output_filename'), '')) self.cwPreds.set(ifnone(newconf.get('cw_preds'), '')) self.closed_world.set(ifnone(newconf.get('cw'), 0)) self.save.set(ifnone(newconf.get('save'), 0)) self.query.set(ifnone(newconf.get('queries'), '')) self.onchange_cw() def set_outputfilename(self): if not hasattr(self, "output_filename") or not hasattr( self, "db_filename") or not hasattr(self, "mln_filename"): return mln = self.mln_container.selected_file.get() db = self.db_container.selected_file.get() if "" in (mln, db): return if self.selected_method.get(): method = InferenceMethods.clazz(self.selected_method.get()) methodid = InferenceMethods.id(method) filename = config.query_output_filename(mln, methodid, db) self.output_filename.set(filename) def update_config(self): self.config = PRACMLNConfig() self.config["use_emln"] = self.use_emln.get() self.config['mln'] = self.mln_container.selected_file.get().strip( ).lstrip('*') self.config['emln'] = self.emln_container.selected_file.get().strip( ).lstrip('*') self.config["db"] = self.db_container.selected_file.get().strip( ).lstrip('*') self.config["method"] = InferenceMethods.id( self.selected_method.get().strip()) self.config["params"] = self.params.get().strip() self.config["queries"] = self.query.get() self.config["output_filename"] = self.output_filename.get().strip() self.config["cw"] = self.closed_world.get() self.config["cw_preds"] = self.cwPreds.get() self.config['profile'] = self.profile.get() self.config['logic'] = self.selected_logic.get() self.config['grammar'] = self.selected_grammar.get() self.config['multicore'] = self.multicore.get() self.config['save'] = self.save.get() self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get() self.config['verbose'] = self.verbose.get() self.config['window_loc'] = self.master.winfo_geometry() self.config['dir'] = self.dir self.project.queryconf = PRACMLNConfig() self.project.queryconf.update(self.config.config.copy()) def write_gconfig(self, savegeometry=True): self.gconf['prev_query_path'] = self.dir self.gconf['prev_query_project':self.dir] = self.project.name # save geometry if savegeometry: self.gconf['window_loc_query'] = self.master.geometry() self.gconf.dump() def infer(self, savegeometry=True, options={}, *args): mln_content = self.mln_container.editor.get("1.0", END).strip() db_content = self.db_container.editor.get("1.0", END).strip() # create conf from current gui settings self.update_config() # write gui settings self.write_gconfig(savegeometry=savegeometry) # hide gui self.master.withdraw() try: print((headline('PRACMLN QUERY TOOL'))) print() if options.get('mlnarg') is not None: mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) else: mlnobj = parse_mln( mln_content, searchpaths=[self.dir], projectpath=os.path.join(self.dir, self.project.name), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) if options.get('emlnarg') is not None: emln_content = mlnpath(options.get('emlnarg')).content else: emln_content = self.emln_container.editor.get("1.0", END).strip() if options.get('dbarg') is not None: dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get( 'ignore_unknown_preds', True)) else: out(self.config.get('ignore_unknown_preds', True)) dbobj = parse_db(mlnobj, db_content, ignore_unknown_preds=self.config.get( 'ignore_unknown_preds', True)) if options.get('queryarg') is not None: self.config["queries"] = options.get('queryarg') infer = MLNQuery(config=self.config, mln=mlnobj, db=dbobj, emln=emln_content) result = infer.run() # write to file if run from commandline, otherwise save result to project results if options.get('outputfile') is not None: output = io.StringIO() result.write(output) with open(os.path.abspath(options.get('outputfile')), 'w') as f: f.write(output.getvalue()) logger.info('saved result to {}'.format( os.path.abspath(options.get('outputfile')))) elif self.save.get(): output = io.StringIO() result.write(output) fname = self.output_filename.get() self.project.add_result(fname, output.getvalue()) self.project.save(dirpath=self.dir) logger.info( 'saved result to file results/{} in project {}'.format( fname, self.project.name)) else: logger.debug( 'No output file given - results have not been saved.') except: traceback.print_exc() # restore main window sys.stdout.flush() self.master.deiconify()
display_textbox(page_content, 2, 0, root) # text_box = tk.Text(root, height=10, width=50, padx=15, pady=15) # text_box.insert(1.0, page_content) # text_box.tag_configure("center", justify="center") # text_box.tag_add("center", 1.0, 'end') # text_box.grid(column=1, row=3) browse_text.set("Browse") display_logo('logo.png', 0, 0) # broserbbuttom browse_text = StringVar() browse_btn = Button(root, textvariable="browse_text", command=lambda: open_file(), font=("Raleway", 10), bg="white") browse_text.set("Browse") browse_btn.grid(column=2, row=1, sticky=NE, padx=50) # browse_btn = tk.Button(root, textvariable=browse_text, command=lambda: open_file(), font="Raleway", bg="#20bebe", # fg="white", height=2, width=15) # browse_text.set("Browse") # browse_btn.grid(column=1, row=2) # canvas = tk.Canvas(root, width=600, height=250) # canvas.grid(columnspan=3)
def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]}, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.emln', 'ftypes': [('MLN extension files','.emln')]}, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]}, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton(option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project': self.project_dir] is not None: self.load_project(os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True
class MLNQueryGUI(object): def __init__(self, master, gconf, directory=None): self.master = master self.initialized = False self.master.bind('<Return>', self.infer) self.master.bind('<Escape>', lambda a: self.master.quit()) self.master.protocol('WM_DELETE_WINDOW', self.quit) self.dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) self.frame = Frame(master) self.frame.pack(fill=BOTH, expand=1) self.frame.columnconfigure(1, weight=1) row = 0 # pracmln project options Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0, sticky='ES') project_container = Frame(self.frame) project_container.grid(row=row, column=1, sticky="NEWS") # new proj file self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project) self.btn_newproj.grid(row=0, column=1, sticky="WS") # open proj file self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project) self.btn_openproj.grid(row=0, column=2, sticky="WS") # save proj file self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project) self.btn_updateproj.grid(row=0, column=3, sticky="WS") # save proj file as... self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project) self.btn_saveproj.grid(row=0, column=4, sticky="WS") # grammar selection row += 1 Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E') grammars = ['StandardGrammar', 'PRACGrammar'] self.selected_grammar = StringVar() self.selected_grammar.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars)) l.grid(row=row, column=1, sticky='NWE') # logic selection row += 1 Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E') logics = ['FirstOrderLogic', 'FuzzyLogic'] self.selected_logic = StringVar() self.selected_logic.trace('w', self.settings_setdirty) l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics)) l.grid(row=row, column=1, sticky='NWE') # mln section row += 1 Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE') self.mln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]}, defaultname='*unknown{}', importhook=self.import_mln, deletehook=self.delete_mln, projecthook=self.save_proj, filecontenthook=self.mlnfilecontent, fileslisthook=self.mlnfiles, updatehook=self.update_mln, onchangehook=self.project_setdirty) self.mln_container.editor.bind("<FocusIn>", self._got_focus) self.mln_container.grid(row=row, column=1, sticky="NEWS") self.mln_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) row += 1 self.use_emln = IntVar() self.use_emln.set(0) self.cb_use_emln = Checkbutton(self.frame, text="use model extension", variable=self.use_emln, command=self.onchange_use_emln) self.cb_use_emln.grid(row=row, column=1, sticky="W") # mln extension section row += 1 self.emlncontainerrow = row self.emln_label = Label(self.frame, text="EMLN: ") self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE') self.emln_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.emln', 'ftypes': [('MLN extension files','.emln')]}, defaultname='*unknown{}', importhook=self.import_emln, deletehook=self.delete_emln, projecthook=self.save_proj, filecontenthook=self.emlnfilecontent, fileslisthook=self.emlnfiles, updatehook=self.update_emln, onchangehook=self.project_setdirty) self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS") self.emln_container.editor.bind("<FocusIn>", self._got_focus) self.emln_container.columnconfigure(1, weight=2) self.onchange_use_emln(dirty=False) self.frame.rowconfigure(row, weight=1) # db section row += 1 Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE') self.db_container = FileEditBar(self.frame, directory=self.dir, filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]}, defaultname='*unknown{}', importhook=self.import_db, deletehook=self.delete_db, projecthook=self.save_proj, filecontenthook=self.dbfilecontent, fileslisthook=self.dbfiles, updatehook=self.update_db, onchangehook=self.project_setdirty) self.db_container.grid(row=row, column=1, sticky="NEWS") self.db_container.editor.bind("<FocusIn>", self._got_focus) self.db_container.columnconfigure(1, weight=2) self.frame.rowconfigure(row, weight=1) # inference method selection row += 1 self.list_methods_row = row Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E) self.selected_method = StringVar() self.selected_method.trace('w', self.select_method) methodnames = sorted(InferenceMethods.names()) self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames)) self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE") # options row += 1 option_container = Frame(self.frame) option_container.grid(row=row, column=1, sticky="NEWS") # Multiprocessing self.multicore = IntVar() self.cb_multicore = Checkbutton(option_container, text="Use all CPUs", variable=self.multicore, command=self.settings_setdirty) self.cb_multicore.grid(row=0, column=2, sticky=W) # profiling self.profile = IntVar() self.cb_profile = Checkbutton(option_container, text='Use Profiler', variable=self.profile, command=self.settings_setdirty) self.cb_profile.grid(row=0, column=3, sticky=W) # verbose self.verbose = IntVar() self.cb_verbose = Checkbutton(option_container, text='verbose', variable=self.verbose, command=self.settings_setdirty) self.cb_verbose.grid(row=0, column=4, sticky=W) # options self.ignore_unknown_preds = IntVar() self.cb_ignore_unknown_preds = Checkbutton(option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds, command=self.settings_setdirty) self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W") # queries row += 1 Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E) self.query = StringVar() self.query.trace('w', self.settings_setdirty) Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW") # additional parameters row += 1 Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE") self.params = StringVar() self.params.trace('w', self.settings_setdirty) self.entry_params = Entry(self.frame, textvariable=self.params) self.entry_params.grid(row=row, column=1, sticky="NEW") # closed-world predicates row += 1 Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E") cw_container = Frame(self.frame) cw_container.grid(row=row, column=1, sticky='NEWS') cw_container.columnconfigure(0, weight=1) self.cwPreds = StringVar() self.cwPreds.trace('w', self.settings_setdirty) self.entry_cw = Entry(cw_container, textvariable=self.cwPreds) self.entry_cw.grid(row=0, column=0, sticky="NEWS") self.closed_world = IntVar() self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption", variable=self.closed_world, command=self.onchange_cw) self.cb_closed_world.grid(row=0, column=1, sticky='W') # output filename row += 1 output_cont = Frame(self.frame) output_cont.grid(row=row, column=1, sticky='NEWS') output_cont.columnconfigure(0, weight=1) # - filename Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE") self.output_filename = StringVar() self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename) self.entry_output_filename.grid(row=0, column=0, sticky="NEW") # - save option self.save = IntVar() self.cb_save = Checkbutton(output_cont, text="save", variable=self.save) self.cb_save.grid(row=0, column=1, sticky=W) # start button row += 1 start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer) start_button.grid(row=row, column=1, sticky="NEW") self.settings_dirty = IntVar() self.project_dirty = IntVar() self.gconf = gconf self.project = None self.project_dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd()))) if gconf['prev_query_project': self.project_dir] is not None: self.load_project(os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir])) else: self.new_project() self.config = self.project.queryconf self.project.addlistener(self.project_setdirty) self.mln_container.dirty = False self.emln_container.dirty = False self.db_container.dirty = False self.project_setdirty(dirty=False) self.master.geometry(gconf['window_loc_query']) self.initialized = True def _got_focus(self, *_): if self.master.focus_get() == self.mln_container.editor: if not self.project.mlns and not self.mln_container.file_buffer: self.mln_container.new_file() elif self.master.focus_get() == self.db_container.editor: if not self.project.dbs and not self.db_container.file_buffer: self.db_container.new_file() elif self.master.focus_get() == self.emln_container.editor: if not self.project.emlns and not self.emln_container.file_buffer: self.emln_container.new_file() def quit(self): if self.settings_dirty.get() or self.project_dirty.get(): savechanges = messagebox.askyesnocancel("Save changes", "You have unsaved project changes. Do you want to save them before quitting?") if savechanges is None: return elif savechanges: self.noask_save_project() self.master.destroy() else: # write gui settings and destroy self.write_gconfig() self.master.destroy() ####################### PROJECT FUNCTIONS ################################# def new_project(self): self.project = MLNProject() self.project.addlistener(self.project_setdirty) self.project.name = DEFAULTNAME.format('.pracmln') self.reset_gui() self.set_config(self.project.queryconf) self.mln_container.update_file_choices() self.emln_container.update_file_choices() self.db_container.update_file_choices() self.project_setdirty(dirty=True) def project_setdirty(self, dirty=False, *args): self.project_dirty.set(dirty or self.mln_container.dirty or self.db_container.dirty or self.emln_container.dirty) self.changewindowtitle() def settings_setdirty(self, *args): self.settings_dirty.set(1) self.changewindowtitle() def changewindowtitle(self): title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name) self.master.title(title) def ask_load_project(self): filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln") if filename and os.path.exists(filename): self.load_project(filename) else: logger.info('No file selected.') return def load_project(self, filename): if filename and os.path.exists(filename): projdir, _ = ntpath.split(filename) self.dir = os.path.abspath(projdir) self.project_dir = os.path.abspath(projdir) self.project = MLNProject.open(filename) self.project.addlistener(self.project_setdirty) self.reset_gui() self.set_config(self.project.queryconf.config) self.mln_container.update_file_choices() self.db_container.update_file_choices() if len(self.project.mlns) > 0: self.mln_container.selected_file.set(self.project.queryconf['mln'] or list(self.project.mlns.keys())[0]) self.mln_container.dirty = False if len(self.project.emlns) > 0: self.emln_container.selected_file.set(self.project.queryconf['emln'] or list(self.project.emlns.keys())[0]) self.emln_container.dirty = False if len(self.project.dbs) > 0: self.db_container.selected_file.set(self.project.queryconf['db'] or list(self.project.dbs.keys())[0]) self.db_container.dirty = False self.write_gconfig(savegeometry=False) self.settings_dirty.set(0) self.project_setdirty(dirty=False) self.changewindowtitle() else: logger.error('File {} does not exist. Creating new project...'.format(filename)) self.new_project() def noask_save_project(self): if self.project.name and not self.project.name == DEFAULTNAME.format('.pracmln'): self.save_project(os.path.join(self.project_dir, self.project.name)) else: self.ask_save_project() def ask_save_project(self): fullfilename = asksaveasfilename(initialdir=self.project_dir, confirmoverwrite=True, filetypes=[('PRACMLN project files','.pracmln')], defaultextension=".pracmln") self.save_project(fullfilename) def save_project(self, fullfilename): if fullfilename: fpath, fname = ntpath.split(fullfilename) fname = fname.split('.')[0] self.project.name = fname self.dir = os.path.abspath(fpath) self.project_dir = os.path.abspath(fpath) self.mln_container.save_all_files() self.emln_container.save_all_files() self.db_container.save_all_files() self.update_config() self.project.save(dirpath=self.project_dir) self.write_gconfig() self.load_project(fullfilename) self.settings_dirty.set(0) def save_proj(self): self.project.save(dirpath=self.project_dir) self.write_gconfig() self.project_setdirty(dirty=False) ####################### MLN FUNCTIONS ##################################### def import_mln(self, name, content): self.project.add_mln(name, content) def delete_mln(self, fname): if fname in self.project.mlns: self.project.rm_mln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.mlns: self.project.rm_mln(fnamestr) def update_mln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.mln_container.selected_file.get() if new is None: new = self.mln_container.selected_file.get().strip('*') if content is None: content = self.mln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.mlns[old] = content else: if new in self.project.mlns: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.mlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.mlns[new] = content return 1 def mlnfiles(self): return list(self.project.mlns.keys()) def mlnfilecontent(self, filename): return self.project.mlns.get(filename, '').strip() # /MLN FUNCTIONS ##################################### ####################### EMLN FUNCTIONS ##################################### def import_emln(self, name, content): self.project.add_emln(name, content) def delete_emln(self, fname): if fname in self.project.emlns: self.project.rm_emln(fname) fnamestr = fname.strip('*') if fnamestr in self.project.emlns: self.project.rm_emln(fnamestr) def update_emln(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.emln_container.selected_file.get() if new is None: new = self.emln_container.selected_file.get().strip('*') if content is None: content = self.emln_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.emlns[old] = content else: if new in self.project.emlns: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.emlns[new] = content else: logger.error('no name specified!') return -1 else: self.project.emlns[new] = content return 1 def emlnfiles(self): return list(self.project.emlns.keys()) def emlnfilecontent(self, filename): return self.project.emlns.get(filename, '').strip() # /EMLN FUNCTIONS ##################################### # DB FUNCTIONS ##################################### def import_db(self, name, content): self.project.add_db(name, content) def delete_db(self, fname): if fname in self.project.dbs: self.project.rm_db(fname) fnamestr = fname.strip('*') if fnamestr in self.project.dbs: self.project.rm_db(fnamestr) def update_db(self, old=None, new=None, content=None, askoverwrite=True): if old is None: old = self.db_container.selected_file.get() if new is None: new = self.db_container.selected_file.get().strip('*') if content is None: content = self.db_container.editor.get("1.0", END).strip() if old == new and askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[old] = content else: logger.error('no name specified!') return -1 elif old == new and not askoverwrite: self.project.dbs[old] = content else: if new in self.project.dbs: if askoverwrite: savechanges = messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new)) if savechanges: self.project.dbs[new] = content else: logger.error('no name specified!') return -1 else: self.project.dbs[new] = content return 1 def dbfiles(self): return list(self.project.dbs.keys()) def dbfilecontent(self, filename): return self.project.dbs.get(filename, '').strip() # /DB FUNCTIONS ##################################### # GENERAL FUNCTIONS ################################# def select_method(self, *args): self.set_outputfilename() self.settings_setdirty() def onchange_use_emln(self, dirty=True, *args): if not self.use_emln.get(): self.emln_label.grid_forget() self.emln_container.grid_forget() else: self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky="NE") self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NWES") if dirty: self.settings_setdirty() def onchange_cw(self, *args): if self.closed_world.get(): self.entry_cw.configure(state=DISABLED) else: self.entry_cw.configure(state=NORMAL) self.settings_setdirty() def reset_gui(self): self.set_config({}) self.db_container.clear() self.emln_container.clear() self.mln_container.clear() def set_config(self, newconf): self.config = newconf self.selected_grammar.set(ifnone(newconf.get('grammar'), 'PRACGrammar')) self.selected_logic.set(ifnone(newconf.get('logic'), 'FirstOrderLogic')) self.mln_container.selected_file.set(ifnone(newconf.get('mln'), '')) if self.use_emln.get(): self.emln_container.selected_file.set(ifnone(newconf.get('mln'), '')) self.db_container.selected_file.set(ifnone(newconf.get('db'), "")) self.selected_method.set(ifnone(newconf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name)) self.multicore.set(ifnone(newconf.get('multicore'), 0)) self.profile.set(ifnone(newconf.get('profile'), 0)) self.params.set(ifnone(newconf.get('params'), '')) self.use_emln.set(ifnone(newconf.get('use_emln'), 0)) self.verbose.set(ifnone(newconf.get('verbose'), 1)) self.ignore_unknown_preds.set(ifnone(newconf.get('ignore_unknown_preds'), 0)) self.output_filename.set(ifnone(newconf.get('output_filename'), '')) self.cwPreds.set(ifnone(newconf.get('cw_preds'), '')) self.closed_world.set(ifnone(newconf.get('cw'), 0)) self.save.set(ifnone(newconf.get('save'), 0)) self.query.set(ifnone(newconf.get('queries'), '')) self.onchange_cw() def set_outputfilename(self): if not hasattr(self, "output_filename") or not hasattr(self, "db_filename") or not hasattr(self, "mln_filename"): return mln = self.mln_container.selected_file.get() db = self.db_container.selected_file.get() if "" in (mln, db): return if self.selected_method.get(): method = InferenceMethods.clazz(self.selected_method.get()) methodid = InferenceMethods.id(method) filename = config.query_output_filename(mln, methodid, db) self.output_filename.set(filename) def update_config(self): self.config = PRACMLNConfig() self.config["use_emln"] = self.use_emln.get() self.config['mln'] = self.mln_container.selected_file.get().strip().lstrip('*') self.config['emln'] = self.emln_container.selected_file.get().strip().lstrip('*') self.config["db"] = self.db_container.selected_file.get().strip().lstrip('*') self.config["method"] = InferenceMethods.id(self.selected_method.get().strip()) self.config["params"] = self.params.get().strip() self.config["queries"] = self.query.get() self.config["output_filename"] = self.output_filename.get().strip() self.config["cw"] = self.closed_world.get() self.config["cw_preds"] = self.cwPreds.get() self.config['profile'] = self.profile.get() self.config['logic'] = self.selected_logic.get() self.config['grammar'] = self.selected_grammar.get() self.config['multicore'] = self.multicore.get() self.config['save'] = self.save.get() self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get() self.config['verbose'] = self.verbose.get() self.config['window_loc'] = self.master.winfo_geometry() self.config['dir'] = self.dir self.project.queryconf = PRACMLNConfig() self.project.queryconf.update(self.config.config.copy()) def write_gconfig(self, savegeometry=True): self.gconf['prev_query_path'] = self.dir self.gconf['prev_query_project': self.dir] = self.project.name # save geometry if savegeometry: self.gconf['window_loc_query'] = self.master.geometry() self.gconf.dump() def infer(self, savegeometry=True, options={}, *args): mln_content = self.mln_container.editor.get("1.0", END).strip() db_content = self.db_container.editor.get("1.0", END).strip() # create conf from current gui settings self.update_config() # write gui settings self.write_gconfig(savegeometry=savegeometry) # hide gui self.master.withdraw() try: print((headline('PRACMLN QUERY TOOL'))) print() if options.get('mlnarg') is not None: mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) else: mlnobj = parse_mln(mln_content, searchpaths=[self.dir], projectpath=os.path.join(self.dir, self.project.name), logic=self.config.get('logic', 'FirstOrderLogic'), grammar=self.config.get('grammar', 'PRACGrammar')) if options.get('emlnarg') is not None: emln_content = mlnpath(options.get('emlnarg')).content else: emln_content = self.emln_container.editor.get("1.0", END).strip() if options.get('dbarg') is not None: dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get('ignore_unknown_preds', True)) else: out(self.config.get('ignore_unknown_preds', True)) dbobj = parse_db(mlnobj, db_content, ignore_unknown_preds=self.config.get('ignore_unknown_preds', True)) if options.get('queryarg') is not None: self.config["queries"] = options.get('queryarg') infer = MLNQuery(config=self.config, mln=mlnobj, db=dbobj, emln=emln_content) result = infer.run() # write to file if run from commandline, otherwise save result to project results if options.get('outputfile') is not None: output = io.StringIO() result.write(output) with open(os.path.abspath(options.get('outputfile')), 'w') as f: f.write(output.getvalue()) logger.info('saved result to {}'.format(os.path.abspath(options.get('outputfile')))) elif self.save.get(): output = io.StringIO() result.write(output) fname = self.output_filename.get() self.project.add_result(fname, output.getvalue()) self.project.save(dirpath=self.dir) logger.info('saved result to file results/{} in project {}'.format(fname, self.project.name)) else: logger.debug('No output file given - results have not been saved.') except: traceback.print_exc() # restore main window sys.stdout.flush() self.master.deiconify()
class MainWindow: WIDTH = 500 HEIGHT = 500 def __init__(self, generator_facade): self.root = tk.Tk() self.root.title('Composer') self.root.resizable(False, False) self.model_label_text = StringVar() self.duration_seconds = StringVar() self.player_time = StringVar() self.should_timer_stop = False self.generator_facade = generator_facade self.canvas = tk.Canvas(self.root, height=self.HEIGHT, width=self.WIDTH, highlightthickness=0, bg=GUIUtils.BACKGROUND_COLOR) self.background_image = GUIUtils.get_background_image() self.canvas.create_image(0, 0, image=self.background_image, anchor='nw') self.create_model_button = GUIUtils.init_button( self.root, 'create model', self.create_model_button_callback) self.load_model_button = GUIUtils.init_button( self.root, 'load model', self.load_model_button_callback) self.save_model_button = GUIUtils.init_button( self.root, 'save model', self.save_model_button_callback, 'disabled') self.model_label = GUIUtils.set_label( self.canvas, relx=0.1, rely=0.05, stringvar=self.model_label_text, change_callback=self.on_model_label_change) self.generate_button = GUIUtils.init_button( self.root, 'generate', self.generate_button_callback, 'disabled') self.save_melody_button = GUIUtils.init_button( self.root, 'save melody', self.save_melody_button_callback, 'disabled') self.play_icon = tk.PhotoImage(file='./img/play2.png') self.stop_icon = tk.PhotoImage(file='./img/stop2.png') self.melody_progress_bar = ttk.Progressbar(self.root, orient='horizontal', length=300, mode='determinate') self.player_time_label = GUIUtils.set_label( self.canvas, relx=0.4, rely=0.65, stringvar=self.player_time, change_callback=self.on_timer_label_change) self.play_melody_button = GUIUtils.init_button( self.root, None, self.play_melody_button_callback, 'disabled', 50) self.stop_melody_button = GUIUtils.init_button( self.root, None, self.stop_melody_button_callback, 'disabled', 50) self.init_widgets() def init_widgets(self): self.canvas.pack() self.init_model_buttons() self.init_model_label() self.init_duration_frame() self.init_generate_button() self.init_save_melody_button() self.init_melody_player_frame() def init_model_buttons(self): self.create_model_button.place(relx=0.1, rely=0.1, relwidth=0.2, relheight=0.1) self.load_model_button.place(relx=0.4, rely=0.1, relwidth=0.2, relheight=0.1) self.save_model_button.place(relx=0.7, rely=0.1, relwidth=0.2, relheight=0.1) def init_model_label(self): self.set_model_label_text('') def init_duration_frame(self): self.canvas.create_text(0.1 * self.WIDTH, 0.3 * self.HEIGHT, text='duration (in seconds): ', anchor='w') seconds_entry = tk.Entry(self.root, textvariable=self.duration_seconds) seconds_entry.place(relx=0.5, rely=0.3, relwidth=0.4, anchor='w') def init_melody_player_frame(self): self.play_melody_button.place(relx=0.1, rely=0.6, relwidth=0.1, relheight=0.1) self.play_melody_button.config(image=self.play_icon, compound='left') self.stop_melody_button.place(relx=0.25, rely=0.6, relwidth=0.1, relheight=0.1) self.stop_melody_button.config(image=self.stop_icon, compound='left') self.player_time.set('00:00') self.melody_progress_bar.place(relx=0.5, rely=0.65, relwidth=0.4, anchor='w') def init_generate_button(self): self.generate_button.place(relx=0.4, rely=0.4, relwidth=0.2, relheight=0.1) def init_save_melody_button(self): self.save_melody_button.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.1) def set_model_label_text(self, model_name): self.model_label_text.set('Current model: ' + model_name) def on_model_label_change(self, varname, index, mode): self.canvas.itemconfigure(self.model_label, text=self.root.getvar(varname)) def on_timer_label_change(self, varname, index, mode): self.canvas.itemconfigure(self.player_time_label, text=self.root.getvar(varname)) def generate_button_callback(self): if GUIUtils.is_positive_integer(self.duration_seconds.get()): try: duration = int(self.duration_seconds.get()) self.generator_facade.generate_melody(duration) self.melody_progress_bar.configure(max=duration) self.refresh_buttons_after_generating_melody() except Exception as e: messagebox.showerror("Error", str(e)) else: messagebox.showerror("Error", 'Invalid duration') def save_melody_button_callback(self): try: file = asksaveasfile(mode='w', defaultextension='.midi') if file is not None: self.generator_facade.save_melody(file.name) except Exception as e: messagebox.showerror("Error", str(e)) @staticmethod def validate_spinbox(new_value): if new_value.isdigit(): new_value = int(new_value) if 0 <= new_value <= 60: return True return False def create_model_button_callback(self): window = ModelCreationWindow(self.generator_facade, self) window.display_window() def load_model_button_callback(self): try: file_path = askopenfilename( defaultextension=self.generator_facade.get_model_file_format()) if self.generator_facade.load_model(file_path): self.set_model_label_text(os.path.basename(file_path)) self.refresh_buttons_after_updating_model() except ValueError: messagebox.showerror("Error", 'Invalid file') except Exception as e: messagebox.showerror("Error", repr(e)) def save_model_button_callback(self): try: file = asksaveasfile( mode='w', defaultextension=self.generator_facade.get_model_file_format()) if file is not None: self.generator_facade.save_model(file.name) except Exception as e: messagebox.showerror("Error", str(e)) def play_melody_button_callback(self): try: self.generator_facade.play_melody() timer_thread = threading.Thread( target=self.start_timer, args=(self.generator_facade.duration, )) timer_thread.start() except Exception as e: messagebox.showerror("Error", str(e)) def stop_melody_button_callback(self): try: self.generator_facade.stop_melody() self.reset_timer() self.should_timer_stop = True except Exception as e: messagebox.showerror("Error", str(e)) def refresh_buttons_after_updating_model(self): if self.generator_facade.is_model_loaded(): self.save_model_button.config(state='normal') self.generate_button.config(state='normal') def refresh_buttons_after_generating_melody(self): if self.generator_facade.is_melody_generated(): self.save_melody_button.config(state='normal') self.play_melody_button.config(state='normal') self.stop_melody_button.config(state='normal') def display_window(self): self.root.mainloop() def reset_timer(self): self.player_time.set('00:00') self.melody_progress_bar.configure(value=0) def start_timer(self, total_time): current_time = 0 self.should_timer_stop = False while current_time <= total_time and not self.should_timer_stop: minutes, seconds = divmod(current_time, 60) minutes = round(minutes) seconds = round(seconds) formatted_time = '{:02d}:{:02d}'.format(minutes, seconds) self.player_time.set(formatted_time) self.melody_progress_bar.configure(value=current_time) time.sleep(1) current_time += 1 self.reset_timer() self.should_timer_stop = False
'keep-alive', 'Host': 'www.fabiaoqing.com', 'Cookie': Cookie, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36' } window = tk.Tk() # 创建窗口 window.title('表情包下载器 ------- Hu.Sir') window.iconbitmap('./emoji.ico') # 图标 window.resizable(0, 0) # 防止用户调整尺寸 path = 'D:/表情包/' path1 = StringVar() path1.set(path) def choice_path(): global path path_ = askdirectory() path1.set(path_ + '/表情包/') path = e1.get() menu_dict = {} def request_url(url): try:
def __init__(self, root): # if MY_OS == 'Windows': imgpad = 155 xpadd = 5 ypadd = 5 basefont = 10 entryfont = 11 buttonpad = 202 elif MY_OS == 'Linux': imgpad = 170 xpadd = 5 ypadd = 5 basefont = 12 entryfont = 14 buttonpad = 210 else: imgpad = 190 xpadd = 5 ypadd = 5 basefont = 14 entryfont = 16 buttonpad = 210 # # Main widget background image frame0 = Frame(root) logoimgpath = resource_path("UPackLogo300.jpg") logo = Image.open(logoimgpath) self.logoimage = ImageTk.PhotoImage(logo) self.logoimglabel = Label(frame0, image=self.logoimage) self.logoimglabel.configure(bg='black', bd=0, relief='flat') self.logoimglabel.grid(column=0, row=0, pady=7, padx=imgpad, sticky='e') frame0.configure(bg=hokiestone, bd=5, relief='sunken') frame0.grid(column=0, row=0, pady=0, padx=0, sticky='nsew') # Entry for the Folder that contains the items frame1 = Frame(root) itemfolder = StringVar(frame1) labl1 = Label(frame1, text='Folder of\nItems:') labl1.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl1.grid(column=0, row=0, pady=5, padx=5, sticky='e') browse1 = Button(frame1, text='Browse', command=lambda: self.ask_folder(itemfolder)) browse1.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) browse1.grid(column=2, row=0, pady=5, padx=5, sticky='w') self.e1 = Entry(frame1, width=50, textvariable=itemfolder) self.e1.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e1.grid(column=1, row=0, pady=5, padx=0, sticky='w') # Entry for the master CSV metadata file csvfile = StringVar(frame1) labl2 = Label(frame1, text='CSV File:') labl2.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl2.grid(column=0, row=1, pady=5, padx=5, sticky='e') browse2 = Button(frame1, text='Browse', command=lambda: self.ask_file(csvfile)) browse2.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont), relief='raised') browse2.grid(column=2, row=1, pady=5, padx=5, sticky='w') self.e2 = Entry(frame1, width=50, textvariable=csvfile) self.e2.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e2.grid(column=1, row=1, pady=5, padx=0, sticky='w') # Drop-Down of the column headings in the master CSV file labl3 = Label(frame1, text='CSV Col.\nw/ ID\'s:') labl3.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl3.grid(column=0, row=2, pady=5, padx=5, sticky='e') self.variable = StringVar(frame1) self.options = StringVar(frame1) self.options.trace('r', self.get_headers) firstone = ["Select CSV", "Then \'Refresh\'"] self.hdmenu = OptionMenu(frame1, self.variable, *firstone) self.hdmenu.configure(width=20, bg=vtmaroon, font=('Arial', basefont + 2)) self.hdmenu.grid(column=1, row=2, pady=5, padx=0, sticky='e') self.e3 = Entry(frame1, width=24, textvariable=self.variable) self.e3.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e3.grid(column=1, row=2, pady=5, padx=0, sticky='w') refresh1 = Button(frame1, text='Refresh', command=lambda: self.get_headers(csvfile)) refresh1.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) refresh1.grid(column=2, row=2, pady=5, padx=5, sticky='w') frame1.configure(bg=vtmaroon, bd=5, relief='raised') frame1.grid(column=0, row=1, pady=0, padx=0, sticky='nsew') # Checkbuttons frame2 = ToggleFrame(root) frame2.configure(bg=hokiestone, bd=5, relief='sunken') frame2.grid(column=0, row=2, pady=0, padx=0, sticky='n') # Buttons for Quit, Instructions, and Submit frame3 = Frame(root) cancel1 = Button(frame3, text='Quit', command=root.quit) cancel1.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) cancel1.grid(column=0, row=0, pady=5, padx=xpadd, sticky='e') instruct = Button(frame3, text='Instructions', command=lambda: instructions(basefont)) instruct.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) instruct.grid(column=1, row=0, pady=5, padx=buttonpad, sticky='e') submit1 = Button(frame3, text='Submit', command=lambda: self.run_procs(root, frame2)) submit1.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) submit1.grid(column=2, row=0, pady=5, padx=xpadd, sticky='e') frame3.configure(bg=vtmaroon, bd=5, relief='raised') frame3.grid(column=0, row=3, pady=0, padx=0, sticky='nsew')
class ObjFormatter: """ The main widget """ def __init__(self, root): # if MY_OS == 'Windows': imgpad = 155 xpadd = 5 ypadd = 5 basefont = 10 entryfont = 11 buttonpad = 202 elif MY_OS == 'Linux': imgpad = 170 xpadd = 5 ypadd = 5 basefont = 12 entryfont = 14 buttonpad = 210 else: imgpad = 190 xpadd = 5 ypadd = 5 basefont = 14 entryfont = 16 buttonpad = 210 # # Main widget background image frame0 = Frame(root) logoimgpath = resource_path("UPackLogo300.jpg") logo = Image.open(logoimgpath) self.logoimage = ImageTk.PhotoImage(logo) self.logoimglabel = Label(frame0, image=self.logoimage) self.logoimglabel.configure(bg='black', bd=0, relief='flat') self.logoimglabel.grid(column=0, row=0, pady=7, padx=imgpad, sticky='e') frame0.configure(bg=hokiestone, bd=5, relief='sunken') frame0.grid(column=0, row=0, pady=0, padx=0, sticky='nsew') # Entry for the Folder that contains the items frame1 = Frame(root) itemfolder = StringVar(frame1) labl1 = Label(frame1, text='Folder of\nItems:') labl1.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl1.grid(column=0, row=0, pady=5, padx=5, sticky='e') browse1 = Button(frame1, text='Browse', command=lambda: self.ask_folder(itemfolder)) browse1.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) browse1.grid(column=2, row=0, pady=5, padx=5, sticky='w') self.e1 = Entry(frame1, width=50, textvariable=itemfolder) self.e1.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e1.grid(column=1, row=0, pady=5, padx=0, sticky='w') # Entry for the master CSV metadata file csvfile = StringVar(frame1) labl2 = Label(frame1, text='CSV File:') labl2.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl2.grid(column=0, row=1, pady=5, padx=5, sticky='e') browse2 = Button(frame1, text='Browse', command=lambda: self.ask_file(csvfile)) browse2.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont), relief='raised') browse2.grid(column=2, row=1, pady=5, padx=5, sticky='w') self.e2 = Entry(frame1, width=50, textvariable=csvfile) self.e2.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e2.grid(column=1, row=1, pady=5, padx=0, sticky='w') # Drop-Down of the column headings in the master CSV file labl3 = Label(frame1, text='CSV Col.\nw/ ID\'s:') labl3.configure(fg='black', bg=vtgray, bd=0, font=('Arial', basefont), height=2, width=9, justify='center') labl3.grid(column=0, row=2, pady=5, padx=5, sticky='e') self.variable = StringVar(frame1) self.options = StringVar(frame1) self.options.trace('r', self.get_headers) firstone = ["Select CSV", "Then \'Refresh\'"] self.hdmenu = OptionMenu(frame1, self.variable, *firstone) self.hdmenu.configure(width=20, bg=vtmaroon, font=('Arial', basefont + 2)) self.hdmenu.grid(column=1, row=2, pady=5, padx=0, sticky='e') self.e3 = Entry(frame1, width=24, textvariable=self.variable) self.e3.configure(bg=vtsmoke, relief='sunken', bd=2, font=('Arial', entryfont + 2), justify='left') self.e3.grid(column=1, row=2, pady=5, padx=0, sticky='w') refresh1 = Button(frame1, text='Refresh', command=lambda: self.get_headers(csvfile)) refresh1.configure(bg=vtsmoke, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) refresh1.grid(column=2, row=2, pady=5, padx=5, sticky='w') frame1.configure(bg=vtmaroon, bd=5, relief='raised') frame1.grid(column=0, row=1, pady=0, padx=0, sticky='nsew') # Checkbuttons frame2 = ToggleFrame(root) frame2.configure(bg=hokiestone, bd=5, relief='sunken') frame2.grid(column=0, row=2, pady=0, padx=0, sticky='n') # Buttons for Quit, Instructions, and Submit frame3 = Frame(root) cancel1 = Button(frame3, text='Quit', command=root.quit) cancel1.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) cancel1.grid(column=0, row=0, pady=5, padx=xpadd, sticky='e') instruct = Button(frame3, text='Instructions', command=lambda: instructions(basefont)) instruct.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) instruct.grid(column=1, row=0, pady=5, padx=buttonpad, sticky='e') submit1 = Button(frame3, text='Submit', command=lambda: self.run_procs(root, frame2)) submit1.configure(bg=vtwhite, fg='black', highlightbackground=vtmaroon, font=('Arial', entryfont)) submit1.grid(column=2, row=0, pady=5, padx=xpadd, sticky='e') frame3.configure(bg=vtmaroon, bd=5, relief='raised') frame3.grid(column=0, row=3, pady=0, padx=0, sticky='nsew') def ask_folder(self, foname): foname.set( path.abspath( askdirectory(initialdir=getcwd(), title='Select the Folder'))) return foname def ask_file(self, fname): fname.set( path.abspath( askopenfilename(initialdir=getcwd(), title='Select the master CSV File'))) return fname def get_headers(self, *args): """ Retrieves the options for the drop-down menu of CSV headers """ csvfi = self.e2.get() csvpath = path.join(str(csvfi)) if path.exists(csvpath) and path.splitext(csvpath)[1] == '.csv': with open(csvfi, 'r', encoding='utf-8') as cfile: hreader = csv.DictReader(cfile) opts = hreader.fieldnames else: opts = ["Select CSV", "Then \'Refresh\'"] self.variable.set(opts[0]) menu = self.hdmenu['menu'] menu.delete(0, 'end') for headr in opts: menu.add_command( label=headr, command=lambda idcolumn=headr: self.variable.set(idcolumn)) def make_rdf(self, metacsv): """ Turns 'metadata.csv' into an RDF metadata file, called 'metadata.xml' This could be done using a CSV-to-XML conversion, but it's easier to just read the values for the fields and write the RDF file manually. """ if not path.exists(metacsv): messagebox.showwarning( message= "Error: The \'metadata.csv\' was not found.\nRDF file not created." ) return False with open(metacsv, 'r', encoding='utf-8') as src: reader2 = csv.DictReader(src) headrow2 = reader2.fieldnames for row in reader2: sysUUID = str(row['System UUID']) localID = str(row['Local ID']) deptName = str(row['Department Responsible']) persVTID = str(row['Person Responsible']) collName = str(row['Collection']) description = str(row['Brief Description']) objURI = str(row['Object URI']) collURI = str(row['Collection URI']) src.close() # messagebox.showwarning(message="It got this far! Next step is create the Graph.") g = Graph() # Namespaces rdf = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#") g.bind('rdf', rdf, False) rdfs = Namespace("http://www.w3.org/2000/01/rdf-schema#") g.bind('rdfs', rdfs, False) dc = Namespace("http://dublincore.org/2012/06/14/dcelements.rdf#") g.bind('dc', dc, False) dcterms = Namespace("http://purl.org/dc/terms#") g.bind('dcterms', dcterms, False) dcmitype = Namespace("http://purl.org/dc/dcmitype#") g.bind('dcmitype', dcmitype, False) foaf = Namespace("http://xmlns.com/foaf/spec/index.rdf#") g.bind('foaf', foaf, False) owl = Namespace("http://www.w3.org/2002/07/owl#") g.bind('owl', owl, False) premis = Namespace("http://www.loc.gov/premis/rdf/v3#") g.bind('premis', premis, False) mets = Namespace("http://www.loc.gov/standards/mets/mets.xsd#") g.bind('mets', mets, False) # Establishing subjects for triples object = URIRef(objURI) persID = BNode() g.bind('personID', persID, False) deptID = BNode() g.bind('departmentID', deptID, False) collectID = URIRef(collURI) g.bind('collectionID', collectID, False) metsCustodian = URIRef( 'http://www.loc.gov/standards/mets/mets.xsd#CUSTODIAN') g.bind('custodian', metsCustodian, False) # Adding the triples to the Graph g.add((object, dcterms.identifier, Literal('%s' % sysUUID))) g.add((object, mets.OBJID, Literal('%s' % sysUUID))) g.add((object, mets.altRecordID, Literal('%s' % localID))) g.add((object, dc.contributor, deptID)) g.add((deptID, rdf.type, foaf.Group)) g.add((deptID, mets.ROLE, metsCustodian)) g.add((deptID, foaf.name, Literal('%s' % deptName))) g.add((object, dc.contributor, persID)) g.add((persID, rdf.type, foaf.Person)) g.add((persID, mets.ROLE, metsCustodian)) g.add((persID, foaf.mbox, Literal('%s (at) vt (dot) edu' % persVTID))) # g.add((persID, foaf.name, Literal('%s' %persName))) g.add((object, dcterms.isPartOf, collectID)) g.add((collectID, foaf.name, Literal('%s' % collName))) g.add((object, dcterms.description, Literal('%s' % description))) newrdf = path.join(path.dirname(metacsv), 'metadata.xml') serialrdf = g.serialize(format='pretty-xml') # serialjson = g.serialize(format='json-ld') with open(newrdf, 'wb') as outrdf: outrdf.write(serialrdf) outrdf.close() # jsonfile = path.join(path.dirname(metacsv), 'metadata.json') # with open(jsonfile, 'w', encoding='utf-8') as outjson: # outjson.write(serialjson) # outjson.close() return True def meta_from_csv(self, csvIn, locids, fpath): nfiles = 0 rfiles = 0 overwrite_all = False firstone = True with open(csvIn, 'r', encoding='utf-8') as incsv: reader = csv.DictReader(incsv) headers = reader.fieldnames verifyHeadrs = [ 'System UUID', 'Local ID', 'Department Responsible', 'Person Responsible', 'Collection', 'Brief Description', 'Object URI', 'Collection URI' ] if not headers == verifyHeadrs: messagebox.showwarning( message= "Your input CSV is not formatted correctly.\n\nQuitting action." ) return [0, 0] for row in reader: skip1 = False foldname = row['%s' % locids] foldpath = path.join(fpath, foldname) if not path.exists(foldpath): skip1 = True # The function skips objects that are Bags or already have a # 'metadata.csv' file. Thus it skips creating a 'metadata.xml' # for these objects also. if path.exists(path.join(foldpath, 'data')): skip1 = messagebox.askyesno( message= "It appears that \'%s\' is a bag.\n\nSkip creating \'metadata.csv\' for this one item?" % foldname) if path.exists(path.join(foldpath, 'metadata.csv')) and firstone == True: firstone = False overwrite_all = messagebox.askyesno( message= "At least one \'metadata.csv\' already\nexists. Overwrite ALL of them?" ) if path.exists(path.join( foldpath, 'metadata.csv')) and overwrite_all == False: skip1 = True if skip1 == False: metafile = path.join(foldpath, 'metadata.csv') with open(metafile, 'w') as newmeta: metawriter = csv.DictWriter(newmeta, fieldnames=headers) metawriter.writeheader() metawriter.writerow(row) nfiles += 1 newmeta.close() rdfok = self.make_rdf(metafile) if rdfok == True: rfiles += 1 return [nfiles, rfiles] def create_meta(self, root, folderpath, myfile, idcolname, moreopts1): """ Generates minimal metadata files, 'metadata.csv' and 'metadata.xml' based on a master CSV or a METS xml file """ sourcetype = 'csv' # default counts = [0, 0] # default if path.splitext(myfile)[1] == '.csv': sourcetype = 'csv' else: messagebox.showwarning( message= "The metadata source file must be CSV.\nQuitting action.") runnext1 = False return runnext1 if sourcetype == 'csv': counts = self.meta_from_csv(myfile, idcolname, folderpath) if not moreopts1 == 0: if self.prompting == 0: runnext1 = True else: runnext1 = messagebox.askyesno( message= "Created %d \'metadata.csv\' and %d \'metadata.xml\' files.\n\nProceed with the next action?" % (counts[0], counts[1])) else: runnext1 = False messagebox.showwarning( message= "Created %d \'metadata.csv\' and %d \'metadata.xml\' files." % (counts[0], counts[1])) return runnext1 def gen_ID(self): """ Function to generate a System UUID. In future this will request a NOID and ARK from the naming authority """ SysUID = 'vtdata_' + str(uuid.uuid4()) return SysUID def register_obj(self, ofolder, moreopts2): """ Function to assign System UUID's to objects and register them in the UDCS (a) generate UUID from single naming authority (b) log the obj. in a system Processing Log (c) create placeholder metadata on the Metadata Server (d) update the minimal 'metadata' files with the System UUID """ renamed = 0 rfiles = 0 logfile = path.join(ofolder, 'log4preservation.csv') if not path.exists(logfile): with open(logfile, 'w', encoding='utf-8') as lfile: headrow = ['SysUID', 'LocalID', 'RegisDateTime', 'RegisPerson'] writer = csv.DictWriter(lfile, fieldnames=headrow) writer.writeheader() lfile.close() for fo in listdir(ofolder): skip3 = False fopath = path.join(ofolder, fo) if not path.isdir(fopath): skip3 = True elif path.isdir(fopath): metapath = path.join(fopath, 'metadata.csv') oldrdf = path.join(fopath, 'metadata.xml') # oldjson = path.join(fopath, 'metadata.json') if not path.exists(metapath): skip3 = True messagebox.showwarning( message= "Could not find:\n\'%s\'.\n\nSkipping registration of:\n%s." % (metapath, fo)) if not skip3: newID = self.gen_ID() with open(metapath, 'r', encoding='utf-8') as oldmeta: r = csv.reader(oldmeta) lines = list(r) lines[1][0] = newID log1 = newID log2 = lines[1][1] log3 = time.strftime("%Y.%m.%d %H:%M:%S") log4 = lines[1][3] logline = [log1, log2, log3, log4] with open(logfile, 'a', encoding='utf-8') as logoutf: cwriter = csv.writer(logoutf) cwriter.writerow(logline) with open(metapath, 'w', encoding='utf-8') as outmeta: w = csv.writer(outmeta) w.writerows(lines) if path.exists(oldrdf): remove(oldrdf) # if path.exists(oldjson): # remove(oldjson) rdfok = self.make_rdf(metapath) if rdfok == True: rfiles += 1 newpath = path.join(path.dirname(fopath), '%s' % newID) rename(fopath, newpath) renamed += 1 if not moreopts2 == 0: if self.prompting == 0: runnext2 = True else: runnext2 = messagebox.askyesno( message= "Registered %d objects.\n\nProceed with the next action?" % renamed) else: runnext2 = False messagebox.showwarning(message="Registered %d objects." % renamed) return runnext2 def md5(self, finame): """ Data Services requested Md5 hashes but Md5 is deprecated """ hash_md5 = hashlib.md5() with open(finame, "rb") as md5file: for chunk in iter(lambda: md5file.read(4096), b""): hash_md5.update(chunk) return hash_md5.hexdigest() def sha3hash(self, filname): """ Generates SHA3-256 hashes """ chunksize = io.DEFAULT_BUFFER_SIZE hash_sha3 = hashlib.sha3_256() with open(filname, "rb") as sha3file: for chunks in iter(lambda: sha3file.read(chunksize), b""): hash_sha3.update(chunks) return hash_sha3.hexdigest() def convert_size(self, size): """ Converts bytes to human readable denominations """ if (size == 0): return '0B' # size_name = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") # i = int(math.floor(math.log(size,1024))) # p = math.pow(1024,i) size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") i = int(math.floor(math.log(size, 1000))) p = math.pow(1000, i) s = round(size / p, 2) return '%s%s' % (s, size_name[i]) def run_inventory(self, indir, moreopts3): """ Runs an inventory and generates 'manifest.csv' files for each object """ manifiles = 0 for obj in listdir(indir): objpath = path.join(indir, obj) skipit = False counter = 0 if not path.isdir(objpath): skipit = True elif path.isdir(objpath): if path.exists(path.join(objpath, 'data')): isabag = messagebox.askyesno( message= "It appears that \'%s\' is a bag.\nSkip this object?" % obj) if isabag == True: skipit = True if path.exists(path.join(objpath, 'manifest.csv')): skipit = True messagebox.showwarning( message= "The file \'manifest.csv\' already exists.\nSkipping inventory of the object: \n\'%s\'" % obj) if skipit == False: manifiles += 1 tempmani = open(path.join(indir, 'temp_manifest.csv'), 'w', encoding='utf-8') tempmani.write( "No., Filename, Filesize, Filetype, C-Time, Modified, Accessed, MD5_Sum, SHA3_256, ChecksumDateTime, RelPath, => , mode, inode, device, enlink, user, group\n" ) workdir = path.dirname(objpath) for base, dirs, files in walk(objpath): for name in files: filepathname = path.join(base, name) # Deletes .DS_Store Files if path.basename(filepathname) == '.DS_Store': remove(filepathname) elif not path.basename(filepathname) == '.DS_Store': counter += 1 rownum = str(counter) statinfo = stat(filepathname) filesize = statinfo[6] csize = self.convert_size(filesize) filemime = str( mimetypes.guess_type(filepathname)[0]) filectime = time.strftime( "%Y.%m.%d %H:%M:%S", time.localtime(statinfo.st_ctime)) # note: on a Windows system, ctime is "date created" but on Unix it is # "change time", i.e. the last time the metadata was changed. modifdate = time.strftime( "%Y.%m.%d %H:%M:%S", time.localtime(statinfo.st_mtime)) accessdate = time.strftime( "%Y.%m.%d %H:%M:%S", time.localtime(statinfo.st_atime)) md5sum = self.md5(filepathname) sha3sum = self.sha3hash(filepathname) runtime = time.strftime("%Y.%m.%d %H:%M:%S") filemode = str(statinfo.st_mode) fileino = str(statinfo.st_ino) filedevice = str(statinfo.st_dev) filenlink = str(statinfo.st_nlink) fileuser = str(statinfo.st_uid) filegroup = str(statinfo.st_gid) # Displays a shortened Path for each file, excluding the directories # that precede the working directory that contains the objects. showpath = path.relpath(filepathname, workdir) tempmani.write("%s," % rownum + "\"%s\"," % name + "%s," % csize + "\"%s\"," % filemime + "%s," % filectime + "%s," % modifdate + "%s," % accessdate + "%s," % md5sum + "%s," % sha3sum + "%s," % runtime + "\"%s\"," % showpath) tempmani.write(" ,%s," % filemode + "%s," % fileino + "%s," % filedevice + "%s," % filenlink + "%s," % fileuser + "%s\n" % filegroup) tempmani.write("Comments, \n") tempmani.close() tomove = path.join(path.dirname(objpath), 'temp_manifest.csv') moveto = path.join(objpath, 'manifest.csv') shutil.move(tomove, moveto) if not moreopts3 == 0: if self.prompting == 0: runnext3 = True else: runnext3 = messagebox.askyesno( message= "Created %d \'manifest.csv\' files.\n\nProceed with the next action?" % manifiles) else: runnext3 = False messagebox.showwarning( message="Created %d \'manifest.csv\' files." % manifiles) return runnext3 def run_bagit(self, bagsdir, moreopts4): """ Bags all objects in a single directory """ validbags = 0 totalbags = 0 for f in listdir(bagsdir): inpath = path.join(bagsdir, f) cont = True if path.isdir(inpath): if path.exists(path.join(inpath, 'data')): cont = messagebox.askyesno( message= "It appears that \'%s\' is already a bag.\nBag it anyway?" % f) if cont == True: newbag = bagit.make_bag(inpath, checksums=['md5', 'sha512']) totalbags += 1 if newbag.is_valid(): validbags += 1 elif not newbag.is_valid(): messagebox.showwarning( message="Bag \'%s\' is not a valid bag." % f) # elif cont == False: # messagebox.showwarning(message="Skipped bagging of \'%s\'." %f) if not moreopts4 == 0: if self.prompting == 0: runnext4 = True else: runnext4 = messagebox.askyesno( message= "Created %d total bags,\nof which %d are valid.\n\nProceed with the next action?" % (totalbags, validbags)) else: runnext4 = False messagebox.showwarning( message="Created %d total bags,\nof which %d are valid." % (totalbags, validbags)) return runnext4 def run_tar(self, tarfolder, moreopts5): """ Tars all objects in a single directory """ tarfiles = 0 alreadytar = 0 notfolder = 0 outfolder = path.splitext(tarfolder)[0] + '-tarred' if not path.exists(outfolder): mkdir(outfolder) for i in listdir(tarfolder): infile = path.join(tarfolder, i) if path.isdir(infile): outfile = path.join(outfolder, path.splitext(i)[0] + '.tar') if path.exists(outfile): messagebox.showwarning( message= "The TAR file: \n\'%s\'\nalready exists!\nTar archive not created." % outfile) alreadytar += 1 elif not path.exists(outfile): # with tarfile.open(outfile, 'w:gz') as newtar: with tarfile.open(outfile, 'w') as newtar: tarname = path.relpath(infile, tarfolder) newtar.add(infile, arcname='%s' % tarname) tarfiles += 1 else: notfolder += 1 if not alreadytar == 0: messagebox.showwarning( message= "The folder \'%s\' already contained %d tar files which were skipped." % (outfolder, alreadytar)) # if not notfolder == 0: # messagebox.showwarning(message="The target folder contained %d files, which were ignored." %notfolder) if not moreopts5 == 0: if self.prompting == 0: runnext5 = True else: runnext5 = messagebox.askyesno( message= "Created %d tar archives.\n\nProceed with the next action?" % tarfiles) else: runnext5 = False messagebox.showwarning(message="Created %d tar archives." % tarfiles) return runnext5 def trans_manifest(self, indirectory): """ Generates a manifest of filenames and checksums for a directory of Bagged and Tarred objects """ askingdir = path.join(path.basename(path.dirname(indirectory)), path.basename(indirectory)) indir = "" tardest = messagebox.askyesno( message="Create manifest of \'%s-tarred\'?" % askingdir, default='yes') if tardest: indir = indirectory + "-tarred" elif not tardest: indir = askdirectory( initialdir=path.dirname(indirectory), title="In which folder are the objects to be transferred?") if not path.exists(indir): messagebox.showwarning( message= "The directory: \n\'%s\'\n does not exist.\n\nCancelling action." % indir) return outdir = path.dirname(indir) # messagebox.showwarning(message="The transfer manifest will be saved in: \n\'%s\'" %outdir) compfile = open(path.join( outdir, "Transfer_%s_%s.csv" % (path.basename(indir), time.strftime("%m%d_%H%M%S"))), 'w', encoding='utf-8') for base, dirs, files in walk(indir): for name in files: pathname = path.join(base, name) if path.basename(pathname) == '.DS_Store': remove(pathname) elif not path.basename(pathname) == '.DS_Store': sha3sum = self.sha3hash(pathname) compfile.write("%s, " % name + "%s\n" % sha3sum) compfile.close() messagebox.showwarning(message="Transfer Manifest Created.") return def pre_pack(self, packdir): """ Preserves departmental folder structure during Bagging by moving object contents into a subdirectory named with the local object ID """ for item in listdir(packdir): olditempath = path.join(packdir, item) if path.isdir(olditempath): newdirpath = path.join(olditempath, path.basename(olditempath)) temppath = path.join(olditempath, 'temptemptemp') shutil.copytree(olditempath, temppath) for thing in listdir(olditempath): thingpath = path.join(olditempath, thing) if not thing == 'temptemptemp': if path.isdir(thingpath): shutil.rmtree(thingpath) elif not 'meta' in thing: remove(thingpath) rename(temppath, newdirpath) return packdir def run_procs(self, root, frame2): runnext = True olditemsdir = self.e1.get() meta = frame2.metavar.get() regstr = frame2.regisvar.get() inv = frame2.invenvar.get() bagit = frame2.bagitvar.get() tar = frame2.tarvar.get() trans = frame2.transvar.get() self.prompting = frame2.prompt.get() nselect = 0 for d in [meta, regstr, inv, bagit, tar, trans]: if d == 1: nselect += 1 if olditemsdir == "": messagebox.showwarning(message="You must first select a folder.") return if not path.exists(olditemsdir): messagebox.showwarning( message="Items folder:\n\'%s\'\nnot found." % olditemsdir) return if nselect == 0: messagebox.showwarning( message="You have not selected any \'Options\'.") return # PrePack items prepack = messagebox.askyesno( title="Pre-Packaging", message= "Is this the first time running UDOF on THESE items?\n(Clicking \'yes\' will \'pre-package\' them.)", default='no') if prepack == False: itemsdir = olditemsdir else: itemsdir = self.pre_pack(olditemsdir) # Run CSV meta if meta == 1: nselect -= 1 metainput = self.e2.get() idcolumn = self.e3.get() if metainput == "": messagebox.showwarning( message="You must choose a CSV master metadata file.") return if not path.exists(metainput): messagebox.showwarning( message="CSV file:\n\'%s\'\nnot found. Stopping action." % metainput) return if path.splitext(metainput)[1] == '.csv' and idcolumn == "": messagebox.showwarning( message="You must choose the column of ID's in the CSV.") return runnext = self.create_meta(root, itemsdir, metainput, idcolumn, nselect) if runnext == False: return # Assign UUID's and Register Objects if regstr == 1: nselect -= 1 runnext = self.register_obj(itemsdir, nselect) if runnext == False: return # Run Inventory if inv == 1: nselect -= 1 runnext = self.run_inventory(itemsdir, nselect) if runnext == False: return # Run BagIt if bagit == 1: nselect -= 1 self.run_bagit(itemsdir, nselect) if runnext == False: return # Run Tar if tar == 1: nselect -= 1 runnext = self.run_tar(itemsdir, nselect) if runnext == False: return # Make Transfer Manifest if trans == 1: self.trans_manifest(itemsdir) return