diff --git a/Editor/README.md b/Editor/README.md index 97cc1d4..5e0d87e 100644 --- a/Editor/README.md +++ b/Editor/README.md @@ -1,6 +1,4 @@ Editor ========== -A neat idea that I would one day like to make into a website or something. Users read and write text files simply by choosing the file name. If it exists, the text is returned to them for editing. If it does not, it will be created when they press Save. No logins and no file security. Since it's using a database instead of actual txt files, there are no filename character restrictions, only a maximum title length for sanity's sake. - -For now, it's just a tkinter toy. \ No newline at end of file +A neat idea that would make for a fun website. Users read and write text files by choosing the file name. If it exists, the text is returned to them for editing. If it does not, it will be created when they press Save. No logins and no file security. Since it's using a database instead of actual txt files, there are no filename character restrictions, only a maximum title length and a couple self-imposed rules for sanity's sake. \ No newline at end of file diff --git a/Editor/editor.py b/Editor/editor.py index 3e0bf3b..47bec31 100644 --- a/Editor/editor.py +++ b/Editor/editor.py @@ -5,7 +5,8 @@ import random class Editor: def __init__(self): - self.WINDOWS_BADCHARS = '\\/?:*"><|' + #self.WINDOWS_BADCHARS = '\\/?:*"><|' + self.windowtitle = 'Editor' self.sql = sqlite3.connect('textfiles.db') self.cur = self.sql.cursor() @@ -23,6 +24,7 @@ class Editor: self.maximum_title = 64 self.t = tkinter.Tk() + self.t.title(self.windowtitle) self.w = 450 self.h = 350 self.screenwidth = self.t.winfo_screenwidth() @@ -34,98 +36,115 @@ class Editor: self.geometrystring = '%dx%d+%d+%d' % (self.windowwidth, self.windowheight, self.windowx, self.windowy) self.t.geometry(self.geometrystring) - + self.reserved_filenames = ['random', 'list'] + self.has_filenames_changed = True self.entities = [] self.filename = None - self.gui_build_fileloader() + def start(self): + self.gui_build_fileloader() self.t.mainloop() def annihilate(self): - for x in self.entities: - try: - x.grid_forget() - x.pack_forget() - except: - pass - x.destroy() + while len(self.entities) > 0: + self.entities[0].destroy() + del self.entities[0] def gui_build_fileloader(self, *b): self.annihilate() - + self.t.title(self.windowtitle) + ### self.frame_fileloader = tkinter.Frame(self.t) self.entities.append(self.frame_fileloader) + # self.entry_filename = tkinter.Entry(self.frame_fileloader, font=self.font_large, justify='right') self.entry_filename.grid(row=0, column=0, columnspan=3) self.entry_filename.focus_set() self.entry_filename.bind("", self.loadfile_smart) self.entities.append(self.entry_filename) + # self.label_filename = tkinter.Label(self.frame_fileloader, font=self.font_large, text='.txt') self.label_filename.grid(row=0, column=3) self.entities.append(self.label_filename) + # self.button_fileloader = tkinter.Button(self.frame_fileloader, font=self.font_large, text='Load', command=self.loadfile_smart) self.button_fileloader.grid(row=1, column=1, pady=10) self.entities.append(self.button_fileloader) - width = self.t.winfo_width() - height = self.t.winfo_height() - if min([width, height]) < 20: - width = self.w - height = self.h + # self.frame_fileloader.pack(expand=True, anchor='center') #self.frame_fileloader.place(x=width/2, y=(height/2)-10, anchor='center') def gui_build_editor(self, filetext, *b): self.annihilate() - + ### self.frame_toolbar = tkinter.Frame(self.t) self.frame_toolbar.pack() self.entities.append(self.frame_toolbar) + # self.button_back = tkinter.Button(self.frame_toolbar, text='back', command=self.gui_build_fileloader, font=self.font_small) self.button_back.grid(row=0, column=0) self.entities.append(self.button_back) + # self.label_filename = tkinter.Label(self.frame_toolbar, text=self.filename, font=self.font_small) - self.label_filename.grid(row=0, column=1, padx=20) + self.label_filename.grid(row=0, column=1, padx=70) self.entities.append(self.label_filename) + # self.button_save = tkinter.Button(self.frame_toolbar, text='save', command=self.savefile_smart, font=self.font_small) self.button_save.grid(row=0, column=2) self.entities.append(self.button_save) + # self.label_filesize = tkinter.Label(self.frame_toolbar, text='', font=self.font_small) - self.label_filesize.grid(row=1, column=0, columnspan=10) + self.label_filesize.grid(row=1, column=0, columnspan=3) self.entities.append(self.label_filesize) - self.text_editor = tkinter.Text(self.t, wrap='word', font=self.font_med) + # + self.scrollbar_editor = tkinter.Scrollbar(self.t) + self.scrollbar_editor.pack(side='right', fill='y') + self.text_editor = tkinter.Text(self.t, wrap='word', font=self.font_med, yscrollcommand=self.scrollbar_editor.set) + self.scrollbar_editor.configure(command=self.text_editor.yview) self.text_editor.insert('end', filetext) self.text_editor.pack(expand=True, fill='both') self.text_editor.focus_set() self.text_editor.bind('', self.savefile_smart) self.text_editor.bind('', self.gui_build_fileloader) self.entities.append(self.text_editor) + self.entities.append(self.scrollbar_editor) + ### def savefile_smart(self, *b): try: filetext = self.text_editor.get('0.0', 'end') - self.savefile(self.filename, filetext) filesize = len(filetext) - 1 - self.label_filesize.configure(text=self.filesizestring(filesize)) + try: + self.savefile(self.filename, filetext) + self.label_filesize.configure(text=self.filesizestring(filesize)) + except EditorException as ee: + self.label_filesize.configure(text=ee.args[0]) except NameError: # text editor does not exist for some reason return - def savefile(self, filename, filetext): + def savefile(self, filename, filetext, permissions=False): + if filename is None: + raise EditorException('Please enter a filename') + if permissions is False and filename in self.reserved_filenames: + print('This file is restricted. You are not permitted to modify it.') + raise EditorException("Restricted file") + filename = filename.replace(' ', '_') filetext = filetext[:-1] # Text widget seems to add \n to the end at all times # So remove it. - if self.filename is None: - return False filesize = len(filetext) namesize = len(filename) if filesize > self.maximum_characters: diff = filesize-self.maximum_characters - print('File exceeds maximum character limit. %d / %d (-%d)' % (filesize, self.maximum_characters, diff)) - return False + sizeerror = 'too big: %d / %d (-%d)' % (filesize, self.maximum_characters, diff) + print('File exceeds maximum character limit. %s' % sizeerror) + raise EditorException(sizeerror) elif namesize > self.maximum_title: diff = namesize - self.maximum_title - print('Filename exceeds maximum character limit: %d / %d (-%d)' % (namesize, self.maximum_title, diff)) - return False + sizeerror = '%d / %d (-%d)' % (namesize, self.maximum_title, diff) + print('Filename exceeds maximum character limit: %s' % sizeerror) + raise EditorException('Filename too big: %s' % sizeerror) sha = self.sha(filename) self.cur.execute('SELECT * FROM textfiles WHERE id=?', [sha]) @@ -133,12 +152,19 @@ class Editor: if filesize == 0: print('Deleting %s' % filename) self.cur.execute('DELETE FROM textfiles WHERE id=?', [sha]) + if fetch: + # If fetch: It previously existed and is now deleted + # If not fetch: User just created this workspace, and + # is now closing it without adding anything + # so nothing has changed on disk. + self.has_filenames_changed = True else: if fetch: self.cur.execute('UPDATE textfiles SET filename=?, filetext=? WHERE id=?', [filename, filetext, sha]) else: self.cur.execute('INSERT INTO textfiles VALUES(?, ?, ?)', [sha, filename, filetext]) print('Wrote %s: %s' % (filename, self.filesizestring(filesize))) + self.has_filenames_changed = True self.sql.commit() return True @@ -157,11 +183,15 @@ class Editor: filetext = self.loadfile(filename) if filetext is not None: self.gui_build_editor(filetext) + self.t.title(filename) return def loadfile(self, filename): if filename == 'random': filename = self.loadrandom() + if filename == 'list': + self.generate_listfile() + filename = filename.replace(' ', '_') if len(filename) < 1: return None if len(filename) > self.maximum_title: @@ -185,6 +215,17 @@ class Editor: return "" return random.choice(fetch)[1] + def generate_listfile(self): + if self.has_filenames_changed: + print('Refreshing list file') + self.cur.execute('SELECT * FROM textfiles') + fetch = self.cur.fetchall() + fetch = [x[1] for x in fetch] + fetch.sort(key=lambda x:x.lower()) + fetch = '\n'.join(fetch) + self.savefile('list', fetch, permissions=True) + self.has_filenames_changed = False + def strip_to_filename(self, s): for bad in self.WINDOWS_BADCHARS: s = s.replace(bad, '') @@ -197,4 +238,8 @@ class Editor: sha = sha.hexdigest() return sha -editor = Editor() \ No newline at end of file +class EditorException(Exception): + pass + +editor = Editor() +editor.start() \ No newline at end of file diff --git a/Editor/textfiles.db b/Editor/textfiles.db index f1e8549..f1b08bb 100644 Binary files a/Editor/textfiles.db and b/Editor/textfiles.db differ