Attached a quick version of a plugin to automate archiving pages. What it does: 1/ Adds a menu item "File --> Archive" - this menu item moves current page to the archive and adds date stamp 2/ Adds a menu item "View --> Archived versions" - shows a dialog with all archived versions of the current page (if any)
Still to do: 1/ Change search dialog to hide archived pages but add a button "show X results from archived pages" 2/ Change auto-completion in "jump to" dialog to put archive lower in the list Please let me know what you think Regards, Jaap
# -*- coding: utf-8 -*- # Copyright 2015 Jaap Karssenberg <jaap.karssenb...@gmail.com> # TODO - hook into search dialog - hide archive + show button with "show X archived pages" # TODO - hook into auto-completion - put archive lower in the list from __future__ import with_statement import gobject import gtk import re import datetime import logging from zim.plugins import PluginClass, extends, WindowExtension from zim.actions import action from zim.notebook import Path from zim.gui.widgets import ui_environment, Dialog, Button, \ WindowSidePaneWidget, LEFT_PANE, TOP, WIDGET_POSITIONS, \ BrowserTreeView, ScrolledWindow logger = logging.getLogger('zim.plugins.archive') class ArchivePlugin(PluginClass): plugin_info = { 'name': _('Archive'), # T: plugin name 'description': _('''\ This plugin uses a section of the notebook as an archive. This archive section is used to get pages out of the way from the active notebook structere. '''), # T: plugin description 'author': 'Jaap Karssenberg', 'help': 'Plugins:Archive', } plugin_preferences = ( # key, type, label, default ('namespace', 'namespace', _('Section'), Path(':Archive')), # T: input label #~ ('embedded', 'bool', _('Show calendar in sidepane instead of as dialog'), False), # T: preferences option #~ ('pane', 'choice', _('Position in the window'), (LEFT_PANE, TOP), WIDGET_POSITIONS), # T: preferences option ) # TODO disable pane setting if not embedded def __init__(self, config=None): PluginClass.__init__(self, config) #~ self.preferences.connect('changed', self.on_preferences_changed) #~ self.on_preferences_changed(self.preferences) #~ def on_preferences_changed(self, preferences): #~ if preferences['embedded']: #~ self.set_extension_class('MainWindow', MainWindowExtensionEmbedded) #~ else: #~ self.set_extension_class('MainWindow', MainWindowExtensionDialog) def archive_page(self, notebook, page): postfix = datetime.date.today().strftime("_%Y%m%d") section = self.preferences['namespace'] newpage = notebook.get_page(section + (page.name + postfix)) if newpage.exists(): i = 1 postfix = postfix + '_(%i)' % i newpage = notebook.get_page(section + (page.name + postfix)) while new_page.exists(): i += 1 postfix = postfix + '_(%i)' % i newpage = notebook.get_page(Path(page.name + postfix)) notebook.move_page(page, newpage) def list_archived_versions(self, notebook, page): # Find all pages in archive that look like page + postfix # Find all pages in archive that look like page where parent # has a postfix # Yield pages and archive dates def _versions(trunk, remainder): basename = remainder.pop(0) pattern = re.compile(re.escape(basename) + r'[ _](\d{8})([ _]\(\d+\))?$') for path in notebook.index.list_pages(trunk): match = pattern.search(path.basename) if match: # branch with archive date date = match.group(1) if remainder: child = path + remainder if notebook.get_page(child).exists(): yield child, date else: yield path, date elif path.basename == basename: if remainder: # follow trunk for r in _versions(path, remainder): yield r else: pass # empty parent of archived pages section = self.preferences['namespace'] for path, date in _versions(section, page.parts): yield path, date @extends('MainWindow') class MainWindowExtensionDialog(WindowExtension): '''Extension used to add calendar dialog to mainwindow''' uimanager_xml = ''' <ui> <menubar name='menubar'> <menu action='file_menu'> <placeholder name='page_modification_actions'> <menuitem action='archive_page'/> </placeholder> </menu> <menu action='view_menu'> <placeholder name='plugin_items'> <menuitem action='show_archived_versions'/> </placeholder> </menu> </menubar> </ui> ''' @action(_('_Archive Page')) # T: menu item def archive_page(self): self.window.ui.save_page() # XXX notebook = self.window.ui.notebook # XXX page = self.window.pageview.get_page() self.plugin.archive_page(notebook, page) @action(_('_Archived Versions...'), tooltip=_('Show Archived Versions...')) # T: menu item def show_archived_versions(self): notebook = self.window.ui.notebook # XXX page = self.window.pageview.get_page() opener = self.window.get_resource_opener() dialog = ArchivedVersionsDialog(self.window, self.plugin, notebook, page, opener) dialog.present() #~ @extends('SearchDialog') #~ class SearchDialogExtension(WindowExtension): #~ def __init__(self, plugin, window): #~ WindowExtension.__init__(self, plugin, window) # Install filter + button #~ def teardown(self): # REmove filter + button class ArchivedVersionsDialog(Dialog): # TODO "open" button that opens current selected version def __init__(self, parent, plugin, notebook, page, opener): Dialog.__init__(self, parent, _('Archived Pages'), # T: dialog title defaultwindowsize=(400, 300), buttons=gtk.BUTTONS_CLOSE, ) label = gtk.Label(_('Archived versions of: <b>%s</b>') % page.name) # T: label, "%s" is the full page name label.set_use_markup(True) self.vbox.pack_start(label, False) model = gtk.ListStore(str, str) # date, page for path, date in plugin.list_archived_versions(notebook, page): # TODO - get ctime and mtime for page # TODO - get more user readable rendering of date - same as in "recent pages" dialog date = "%s-%s-%s" % (date[0:4], date[4:6] ,date[6:8]) # year, month, day model.append((date, path.name)) model.set_sort_column_id(0, gtk.SORT_DESCENDING) treeview = BrowserTreeView() self.vbox.add(ScrolledWindow(treeview)) cell_renderer = gtk.CellRendererText() for name, i in ( (_('Date'), 0), # T: Column header archive dialog (_('Page'), 1), # T: Column header archive dialog ): column = gtk.TreeViewColumn(name, cell_renderer, text=i) column.set_sort_column_id(i) treeview.append_column(column) treeview.set_model(model) def on_open_page(view, path, col): page = Path( view.get_model()[path][1].decode('utf-8') ) opener.open_page(page) treeview.connect('row-activated', on_open_page)
_______________________________________________ Mailing list: https://launchpad.net/~zim-wiki Post to : zim-wiki@lists.launchpad.net Unsubscribe : https://launchpad.net/~zim-wiki More help : https://help.launchpad.net/ListHelp