def _get(self, clipboard, selectiondata, id, *a): '''Callback to get the data in a specific format @param clipboard: a C{gtk.Clipboard} objet @param selectiondata: a C{gtk.SelectionData} object to set the data on @param id: target id for the requested data format @param a: any additional arguments are discarded ''' logger.debug("Clipboard requests data as '%s', we have a parsetree", selectiondata.target) if id == PARSETREE_TARGET_ID: # TODO make links absolute (?) xml = self.parsetree.tostring().encode('utf-8') selectiondata.set(PARSETREE_TARGET_NAME, 8, xml) elif id == HTML_TARGET_ID: dumper = get_format('html').Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) html = ''.join(dumper.dump(self.parsetree)) html = wrap_html(html, target=selectiondata.target) #~ print 'PASTING: >>>%s<<<' % html selectiondata.set(selectiondata.target, 8, html) elif id == TEXT_TARGET_ID: logger.debug("Clipboard requested text, we provide '%s'" % self.format) #~ print ">>>>", self.format, parsetree.tostring() if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) text = ''.join(dumper.dump(self.parsetree)).encode('utf-8') selectiondata.set_text(text) else: assert False, 'Unknown target id %i' % id
def main(orig_file, notebook_path): assert(os.path.isdir(notebook_path)) assert(os.path.isfile(orig_file)) dumper = get_format('wiki').Dumper() parser = get_format('wiki').Parser() text = open(orig_file).read() parsetree = parser.parse(text) newtree = ParseTree().fromstring("<zim-tree></zim-tree>") for para in parsetree.findall('p'): p = Element("p") for node in flatten_list(para, para): p.append(node) newtree.getroot().extend(p) # new todo list text = ''.join(dumper.dump(newtree)).encode('utf-8') tomorrow = date.today() + timedelta(1) directory = os.path.join(notebook_path, "Calendar", str("%04d" % tomorrow.year), str("%02d" % tomorrow.month)) filename = "%02d.txt" % tomorrow.day if (not os.path.exists(directory)): os.makedirs(directory) # write tasks to tomorrow page. with open(os.path.join(directory, filename), 'a+') as the_file: the_file.write(text) # update original wiki page. text = ''.join(dumper.dump(parsetree) ).encode('utf-8') with open(orig_file, 'w') as the_file: the_file.write(text)
def _get(self, clipboard, selectiondata, id, *a): '''Callback to get the data in a specific format @param clipboard: a C{gtk.Clipboard} objet @param selectiondata: a C{gtk.SelectionData} object to set the data on @param id: target id for the requested data format @param a: any additional arguments are discarded ''' logger.debug("Clipboard requests data as '%s', we have a parsetree", selectiondata.target) if id == PARSETREE_TARGET_ID: # TODO make links absolute (?) xml = self.parsetree.tostring().encode('utf-8') selectiondata.set(PARSETREE_TARGET_NAME, 8, xml) elif id == HTML_TARGET_ID: dumper = get_format('html').Dumper( linker=StaticExportLinker(self.notebook, source=self.path) ) html = ''.join( dumper.dump(self.parsetree) ) html = wrap_html(html, target=selectiondata.target) #~ print 'PASTING: >>>%s<<<' % html selectiondata.set(selectiondata.target, 8, html) elif id == TEXT_TARGET_ID: logger.debug("Clipboard requested text, we provide '%s'" % self.format) #~ print ">>>>", self.format, parsetree.tostring() if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticExportLinker(self.notebook, source=self.path) ) text = ''.join( dumper.dump(self.parsetree) ).encode('utf-8') selectiondata.set_text(text) else: assert False, 'Unknown target id %i' % id
def __init__(self, notebook, config=None, template='Default'): '''Constructor @param notebook: a L{Notebook} object @param config: optional C{ConfigManager} object @param template: html template for zim pages ''' assert isinstance(notebook, Notebook) self.notebook = notebook self.config = config or ConfigManager(profile=notebook.profile) self.output = None if template is None: template = 'Default' if isinstance(template, basestring): from zim.templates import get_template self.template = get_template('html', template) if not self.template: raise AssertionError('Could not find html template: %s' % template) else: self.template = template self.linker_factory = partial(WWWLinker, self.notebook, self.template.resources_dir) self.dumper_factory = get_format('html').Dumper # XXX self.plugins = PluginManager(self.config) self.plugins.extend(notebook) self.plugins.extend(self)
def __init__(self, notebook, config=None, template='Default'): '''Constructor @param notebook: a L{Notebook} object @param config: optional C{ConfigManager} object @param template: html template for zim pages ''' assert isinstance(notebook, Notebook) self.notebook = notebook self.config = config or ConfigManager(profile=notebook.profile) self.output = None if template is None: template = 'Default' if isinstance(template, basestring): from zim.templates import get_template self.template = get_template('html', template) if not self.template: raise AssertionError, 'Could not find html template: %s' % template else: self.template = template self.linker_factory = partial(WWWLinker, self.notebook, self.template.resources_dir) self.dumper_factory = get_format('html').Dumper # XXX self.plugins = PluginManager(self.config) self.plugins.extend(notebook.index) self.plugins.extend(notebook) self.plugins.extend(self)
def __init__(self, notebook, path, file=None): memory.Store.__init__(self, notebook, path) self.file = file assert self.store_has_file() self.format = get_format('wiki') # FIXME store format in XML header if self.file.exists(): self.parse(self.file.read())
def __init__(self, notebook, format, template=None, index_page=None, document_root_url=None): '''Constructor. The 'notebook' is the source for pages to be exported. (The export target is given as an argument to export_all() or export().) The 'format' and 'template' arguments determine the output format. If 'index_page' is given a page index is generated and 'document_root_url' is used to prefix any file links that start with '/'. ''' self.notebook = notebook self.index_page = index_page self.document_root_url = document_root_url self.linker = StaticLinker(format, notebook, document_root_url=document_root_url) if isinstance(format, basestring): self.format = get_format(format) else: self.format = format if template and isinstance(template, basestring): self.template = get_template(format, template) else: self.template = template if self.template: self.template.set_linker(self.linker)
def __init__(self, **args): memory.Store.__init__(self, **args) self.format = get_format('plain') if 'file' in args: self.file = file assert self.has_file() self.read_file()
def __init__(self, notebook, template='Default', auth_creds=None): '''Constructor @param notebook: a L{Notebook} object @param template: html template for zim pages @param auth_creds: credentials for HTTP-authentication ''' assert isinstance(notebook, Notebook) self.notebook = notebook self.auth_creds = auth_creds self.output = None if template is None: template = 'Default' if isinstance(template, str): from zim.templates import get_template self.template = get_template('html', template) if not self.template: raise AssertionError('Could not find html template: %s' % template) else: self.template = template self.linker_factory = partial(WWWLinker, self.notebook, self.template.resources_dir) self.dumper_factory = get_format('html').Dumper # XXX
def index_page(self, index, path, page): # DGT Aqui comienza if not self.db_initialized: return if not self.allow_index: return if self._excluded(path): return # ~ print '>>>>>', path, page, page.hascontent qCodesfound = self.remove_page(index, path, _emit=False) if self._excluded(path): if qCodesfound: self.emit('qdacodes-changed') return parsetree = page.get_parsetree() if not parsetree: return if page._ui_object: dumper = get_format('wiki').Dumper() text = ''.join(dumper.dump(parsetree)).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) # ~ print '!! Checking for codes in', path codes = self._extract_codes(parsetree) # ~ print 'qCodeS', codes if codes: # Do insert with a single commit with self.index.db_commit: self._insertTag(path, 0, codes) # qdaMap if self.allow_map : qdaExp = doQdaExportMapDoc( self ) zPage = qdaExp.do_MapDocCodes( page ) with self.index.db_commit: self._insertMap( zPage) if codes or qCodesfound: self.emit('qdacodes-changed')
def __init__(self, notebook, path): '''Construct a memory store. Pass args needed for StoreClass init. ''' StoreClass.__init__(self, notebook, path) self.format = get_format('wiki') # TODO make configable self._nodetree = [] self.readonly = False
def __init__(self, format, notebook, path=None, document_root_url=None): BaseLinker.__init__(self) if isinstance(format, basestring): format = get_format(format) self.notebook = notebook self.path = path self.document_root_url = document_root_url self._extension = '.' + format.info['extension']
def __init__(self, notebook, path, file=None): zim.stores.memory.MemoryStore.__init__(self, notebook, path) self.file = file if not self.store_has_file(): raise AssertionError, 'XMl store needs file' # not using assert here because it could be optimized away self.format = get_format('wiki') # FIXME store format in XML header if self.file.exists(): self.parse(self.file.read())
def __init__(self, notebook, path, dir=None): '''Contruct a files store. Takes an optional 'dir' attribute. ''' StoreClass.__init__(self, notebook, path) self.dir = dir assert self.store_has_dir() self.format = get_format('wiki') # TODO make configable
def crypt_selection(self): buffer = self.pageview.textview.get_buffer() try: sel_start, sel_end = buffer.get_selection_bounds() except ValueError: msg = Gtk.MessageDialog( None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.CLOSE, _("Please select the text to be encrypted, first.")) msg.run() msg.destroy() # T: Error message in "crypt selection" dialog, %s will be replaced # by application name return first_lineno = sel_start.get_line() last_lineno = sel_end.get_line() with buffer.user_action: assert buffer.get_has_selection(), 'No Selection present' sel_text = self.pageview.get_selection(format='wiki') self_bounds = (sel_start.get_offset(), sel_end.get_offset()) if ((re.match(r'[\n\s]*\-{5}BEGIN PGP MESSAGE\-{5}', sel_text) is None) or re.search(r'\s*\-{5}END PGP MESSAGE\-{5}[\n\s]*$', sel_text) is None): # default is encryption: encrypt = True cryptcmd = shlex.split( self.plugin.preferences['encryption_command']) else: # on-the-fly decryption if selection is a full PGP encrypted block encrypt = False cryptcmd = shlex.split( self.plugin.preferences['decryption_command']) newtext = None p = Popen(cryptcmd, stdin=PIPE, stdout=PIPE) newtext, err = p.communicate(input=sel_text.encode()) if p.returncode == 0: # replace selection only if crypt command was successful # (incidated by returncode 0) if encrypt is True: bounds = map(buffer.get_iter_at_offset, self_bounds) buffer.delete(*bounds) buffer.insert_at_cursor("\n%s\n" % newtext.decode()) else: # replace selection with decrypted text parser = get_format('wiki').Parser() tree = parser.parse(newtext.decode()) with buffer.user_action: bounds = map(buffer.get_iter_at_offset, self_bounds) buffer.delete(*bounds) buffer.insert_parsetree_at_cursor(tree, interactive=True) else: logger.warn("crypt command '%s' returned code %d." % (cryptcmd, p.returncode))
def __init__(self, format, notebook, path=None, document_root_url=None): BaseLinker.__init__(self) if isinstance(format, basestring): format = get_format(format) self.notebook = notebook self.path = path self.document_root_url = document_root_url self.target_dir = None self.target_file = None self._extension = '.' + format.info['extension']
def get_data_as(self, targetid): if targetid == PARSETREE_TARGET_ID: # TODO make links absolute (?) return self.parsetree.tostring() elif targetid == HTML_TARGET_ID: dumper = get_format('html').Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) html = ''.join(dumper.dump(self.parsetree)) return wrap_html(html, target=selectiondata.get_target().name()) elif targetid == TEXT_TARGET_ID: if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) return ''.join(dumper.dump(self.parsetree)) else: raise ValueError('Unknown target id %i' % targetid)
def _get(self, clipboard, selectiondata, id, *a): '''Callback to get the data in a specific format @param clipboard: a C{gtk.Clipboard} objet @param selectiondata: a C{gtk.SelectionData} object to set the data on @param id: target id for the requested data format @param a: any additional arguments are discarded ''' logger.debug("Clipboard requests data as '%s', we have a parsetree", selectiondata.target) if id == PARSETREE_TARGET_ID: # TODO make links absolute (?) xml = self.parsetree.tostring().encode('utf-8') selectiondata.set(PARSETREE_TARGET_NAME, 8, xml) elif id == HTML_TARGET_ID: # FIXME - HACK - dump and parse as wiki first to work # around glitches in pageview parsetree dumper # main visibility when copy pasting bullet lists # Same hack in print to browser plugin dumper = get_format('wiki').Dumper() text = ''.join( dumper.dump(self.parsetree) ).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) #-- dumper = get_format('html').Dumper( linker=StaticLinker('html', self.notebook, self.path) ) html = ''.join( dumper.dump(parsetree) ) html = wrap_html(html, target=selectiondata.target) #~ print 'PASTING: >>>%s<<<' % html selectiondata.set(selectiondata.target, 8, html) elif id == TEXT_TARGET_ID: logger.debug("Clipboard requested text, we provide '%s'" % self.format) #~ print ">>>>", self.format, parsetree.tostring() if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticLinker(self.format, self.notebook, self.path) ) text = ''.join( dumper.dump(self.parsetree) ).encode('utf-8') selectiondata.set_text(text) else: assert False, 'Unknown target id %i' % id
def build_single_file_exporter(file, format, template, namespace=None, **opts): '''Returns an L{Exporter} that is suitable for exporting a set of pages to a single file ''' from zim.export.layouts import SingleFileLayout from zim.export.exporters.files import SingleFileExporter template = get_template(format, template) ext = get_format(format).info['extension'] layout = SingleFileLayout(file) return SingleFileExporter(layout, template, format, **opts)
def __init__(self, layout, template, format, document_root_url=None): '''Constructor @param layout: a L{ExportLayout} to map pages to files @param template: a L{Template} object @param format: the format for the file content @param document_root_url: optional URL for the document root ''' self.layout = layout self.template = template self.format = get_format(format) # XXX self.document_root_url = document_root_url
def build_page_exporter(file, format, template, page, **opts): '''Returns an L{Exporter} that is suitable for exporting a page with subpages to a file and a folder (e.g. "page.html" with "page_files/") ''' from zim.export.layouts import FileLayout from zim.export.exporters.files import MultiFileExporter template = get_template(format, template) ext = get_format(format).info['extension'] layout = FileLayout(file, page, ext) return MultiFileExporter(layout, template, format, **opts)
def build_notebook_exporter(dir, format, template, **opts): '''Returns an L{Exporter} that is suitable for exporting a whole notebook to a folder with one file per page ''' from zim.export.layouts import MultiFileLayout from zim.export.exporters.files import MultiFileExporter template = get_template(format, template) ext = get_format(format).info['extension'] layout = MultiFileLayout(dir, ext) return MultiFileExporter(layout, template, format, **opts)
def get_data_as(self, targetid): if targetid == PARSETREE_TARGET_ID: set_parsetree_attributes_to_resolve_links(self.parsetree, self.notebook, self.path) return self.parsetree.tostring() elif targetid == HTML_TARGET_ID: dumper = get_format('html').Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) html = ''.join(dumper.dump(self.parsetree)) return wrap_html(html, self.format) elif targetid == TEXT_TARGET_ID: if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticExportLinker(self.notebook, source=self.path)) return ''.join(dumper.dump(self.parsetree)) else: raise ValueError('Unknown target id %i' % targetid)
def _get(self, clipboard, selectiondata, id, *a): '''Callback to get the data in a specific format @param clipboard: a C{gtk.Clipboard} objet @param selectiondata: a C{gtk.SelectionData} object to set the data on @param id: target id for the requested data format @param a: any additional arguments are discarded ''' logger.debug("Clipboard requests data as '%s', we have a parsetree", selectiondata.target) if id == PARSETREE_TARGET_ID: # TODO make links absolute (?) xml = self.parsetree.tostring().encode('utf-8') selectiondata.set(PARSETREE_TARGET_NAME, 8, xml) elif id == HTML_TARGET_ID: # FIXME - HACK - dump and parse as wiki first to work # around glitches in pageview parsetree dumper # main visibility when copy pasting bullet lists # Same hack in print to browser plugin dumper = get_format('wiki').Dumper() text = ''.join( dumper.dump(self.parsetree) ).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) #-- dumper = get_format('html').Dumper( linker=StaticLinker('html', self.notebook, self.path) ) html = ''.join( dumper.dump(parsetree) ) html = wrap_html(html, target=selectiondata.target) #~ print 'PASTING: >>>%s<<<' % html selectiondata.set(selectiondata.target, 8, html) elif id == TEXT_TARGET_ID: logger.debug("Clipboard requested text, we provide '%s'" % self.format) if self.format != 'wiki': # FIXME - HACK - dump and parse as wiki first to work # around glitches in pageview parsetree dumper # main visibility when copy pasting bullet lists # Same hack in print to browser plugin dumper = get_format('wiki').Dumper() text = ''.join( dumper.dump(self.parsetree) ).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) if self.parsetree.ispartial: parsetree.getroot().attrib['partial'] = True #-- else: parsetree = self.parsetree #~ print ">>>>", self.format, parsetree.tostring() if self.format in ('wiki', 'plain'): dumper = get_format(self.format).Dumper() else: dumper = get_format(self.format).Dumper( linker=StaticLinker(self.format, self.notebook, self.path) ) text = ''.join( dumper.dump(parsetree) ).encode('utf-8') selectiondata.set_text(text) else: assert False, 'Unknown target id %i' % id
def index_page(self, index, path, page): if not self.db_initialized: return # ~ print '>>>>>', path, page, page.hascontent tasksfound = self.remove_page(index, path, _emit=False) if self._excluded(path): if tasksfound: self.emit('tasklist-changed') return parsetree = page.get_parsetree() if not parsetree: return if page._ui_object: # FIXME - HACK - dump and parse as wiki first to work # around glitches in pageview parsetree dumper # make sure we get paragraphs and bullets are nested properly # Same hack in gui clipboard code dumper = get_format('wiki').Dumper() text = ''.join(dumper.dump(parsetree)).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) # ~ print '!! Checking for tasks in', path dates = daterange_from_path(path) if dates and self.preferences['deadline_by_page']: deadline = dates[2] else: deadline = None tasks = self._extract_tasks(parsetree, deadline) # ~ print 'TASKS', tasks if tasks: # Do insert with a single commit with self.index.db_commit: self._insert(path, 0, tasks) if tasks or tasksfound: self.emit('tasklist-changed')
def print_to_file(self, page): # FIXME - HACK - dump and parse as wiki first to work # around glitches in pageview parsetree dumper # main visibility when copy pasting bullet lists # Same hack in gui clipboard code from zim.notebook import Path, Page from zim.formats import get_format parsetree = page.get_parsetree() dumper = get_format('wiki').Dumper() text = ''.join( dumper.dump(parsetree) ).encode('utf-8') parser = get_format('wiki').Parser() parsetree = parser.parse(text) page = Page(Path(page.name), parsetree=parsetree) #-- file = TmpFile('print-to-browser.html', persistent=True, unique=False) template = zim.templates.get_template('html', 'Print') template.set_linker(StaticLinker('html', self.ui.notebook, page)) html = template.process(self.ui.notebook, page) file.writelines(html) return file
def __init__(self, notebook, format, template=None, index_page=None, document_root_url=None): '''Constructor. Takes all input parameters on how to format the exported content. @param notebook: the L{Notebook} object @param format: the output format as string, or formatting module object @param template: the template name as string, or a L{Template} object, if C{None} no template is used @param index_page: path name for the index page, if C{None} no index page is generated @param document_root_url: prefix for links that link to the document root (e.g. URL for the document root on some server). If C{None} document root files are considered the same as other files. @todo: check why index_page is a string and not a Path object ''' self.notebook = notebook self.document_root_url = document_root_url self.linker = StaticLinker(format, notebook, document_root_url=document_root_url) if index_page: self.index_page = notebook.cleanup_pathname(index_page) else: self.index_page = None if isinstance(format, basestring): self.format = get_format(format) else: self.format = format if template and not isinstance(template, Template): self.template = get_template(format, template) else: self.template = template if self.template: self.template.set_linker(self.linker)
def __init__(self, notebook, path, dir=None): '''Constructor @param notebook: a L{Notebook} object @param path: a L{Path} object for the mount point within the notebook @keyword dir: a L{Dir} object When no dir is given and the notebook has a dir already the dir is derived based on the path parameter. In the easiest case when path is the root, the notebook dir is copied. ''' StoreClass.__init__(self, notebook, path) self.dir = dir if not self.store_has_dir(): raise AssertionError, 'File store needs directory' # not using assert here because it could be optimized away self.format = get_format('wiki') # TODO make configurable
def __init__(self, folder, endofline=_EOL, default_format='wiki', default_extension='.txt'): '''Constructor @param folder: a L{Folder} object @param endofline: either "dos" or "unix", default per OS ''' assert isinstance(folder, Folder) self.root = folder self.endofline = endofline if not default_extension.startswith('.'): default_extension = '.' + default_extension self.default_extension = default_extension self.default_format = get_format(default_format)
def parsetree_from_selectiondata(selectiondata, notebook=None, path=None): '''Function to get a parsetree based on the selectiondata contents if at all possible. Used by both copy-paste and drag-and-drop methods. The 'notebook' and optional 'path' arguments are used to format links relative to the page which is the target for the pasting or drop operation. For image data, the parameters notebook and page are used to save the image to the correct attachment folder and return a parsetree with the correct image link. @param selectiondata: a C{gtk.SelectionData} object @param notebook: a L{Notebook} object @param path: a L{Path} object @returns: a L{ParseTree} or C{None} ''' # TODO: check relative linking for all parsetrees !!! targetname = str(selectiondata.target) if targetname == PARSETREE_TARGET_NAME: return ParseTree().fromstring(selectiondata.data) elif targetname in (INTERNAL_PAGELIST_TARGET_NAME, PAGELIST_TARGET_NAME) \ or targetname in URI_TARGET_NAMES: links = unpack_urilist(selectiondata.data) return _link_tree(links, notebook, path) elif targetname in TEXT_TARGET_NAMES: # plain text parser should highlight urls etc. # FIXME some apps drop text/uri-list as a text/plain mimetype # try to catch this situation by a check here text = selectiondata.get_text() if text: return get_format('plain').Parser().parse(text.decode('utf-8')) else: return None elif targetname in IMAGE_TARGET_NAMES: # save image pixbuf = selectiondata.get_pixbuf() if not pixbuf: return None dir = notebook.get_attachments_dir(path) if not dir.exists(): logger.debug("Creating attachment dir: %s", dir) dir.touch() format, extension = _get_image_info(targetname) if format is None or format == 'bmp': # default to png format # special casing bmp since many window apps use it internally # but is quite large to store, so compress by using png format, extension = 'png', 'png' file = dir.new_file('pasted_image.%s' % extension) logger.debug("Saving image from clipboard to %s", file) pixbuf.save(file.path, format) links = [file.uri] return _link_tree(links, notebook, path) else: return None
class FilesLayout(NotebookLayout): '''Layout is responsible for mapping between pages and files. This is the most basic version, where each page maps to the like-named file. ''' default_extension = '.txt' default_format = get_format('wiki') def __init__(self, folder, endofline=_EOL): '''Constructor @param folder: a L{Folder} object @param endofline: either "dos" or "unix", default per OS ''' assert isinstance(folder, Folder) self.root = folder self.endofline = _EOL def map_page(self, pagename): '''Map a pagename to a (default) file @param pagename: a L{Path} @returns: a 2-tuple of a L{File} for the source and a L{Folder} for the attachments. Neither of these needs to exist. ''' path = encode_filename(pagename.name) file = self.root.file(path + self.default_extension) file.endofline = self.endofline ## TODO, make this auto-detect for existing files ? folder = self.root.folder(path) if path else self.root return file, folder def get_attachments_folder(self, pagename): file, folder = self.map_page(pagename) return FilesAttachmentFolder(folder, self.default_extension) def map_file(self, file): '''Map a filepath to a pagename @param file: a L{File} or L{FilePath} object @returns: a L{Path} and a file type (C{FILE_TYPE_PAGE_SOURCE}, F{FILE_TYPE_ATTACHMENT}) ''' path = file.relpath(self.root) return self.map_filepath(path) def map_filepath(self, path): '''Like L{map_file} but takes a string with relative path''' if path.endswith(self.default_extension): path = path[:-len(self.default_extension)] type = FILE_TYPE_PAGE_SOURCE else: if _SEP in path: path, x = path.rsplit(_SEP, 1) else: path = ':' # ROOT_PATH type = FILE_TYPE_ATTACHMENT if path == ':': return Path(':'), type else: name = decode_filename(path) Path.assertValidPageName(name) return Path(name), type def resolve_conflict(self, *filepaths): '''Decide which is the real page file when multiple files map to the same page. @param filepaths: 2 or more L{FilePath} objects @returns: L{FilePath} that should take precedent as te page source ''' filespaths.sort(key=lambda p: (p.ctime(), p.basename)) return filepaths[0] def get_format(self, file): if file.path.endswith(self.default_extension): return self.default_format else: raise AssertionError, 'Unknown file type for page: %s' % file def index_list_children(self, pagename): # Convenience method - remove if no longer used by the index file, folder = self.map_page(pagename) if not folder.exists(): return [] names = set() for object in folder: if isinstance(object, File): if object.path.endswith(self.default_extension): name = object.basename[:-len(self.default_extension)] else: continue else: # Folder name = object.basename pname = decode_filename(name) if encode_filename( pname) == name: # will reject e.g. whitespace in file name names.add(pname) return [pagename + basename for basename in sorted(names)]
def parsetree_from_selectiondata(selectiondata, notebook=None, path=None, text_format='plain'): '''Function to get a parsetree based on the selectiondata contents if at all possible. Used by both copy-paste and drag-and-drop methods. The 'notebook' and optional 'path' arguments are used to format links relative to the page which is the target for the pasting or drop operation. For image data, the parameters notebook and page are used to save the image to the correct attachment folder and return a parsetree with the correct image link. @param selectiondata: a C{Gtk.SelectionData} object @param notebook: a L{Notebook} object @param path: a L{Path} object @param text_format: format to parse pasted text, as a special case - "verbatim" will wrap content in VERBARIM_BLOCK or VERBATIM element based on the content - "verbatim-pre" will wrap the content in a VERBATIM_BLOCK element and - "verbatim-code" will wrap the content in a VERBATIM element @returns: a L{ParseTree} or C{None} ''' # TODO: check relative linking for all parsetrees !!! targetname = selectiondata.get_target().name() if targetname == PARSETREE_TARGET_NAME: return ParseTree().fromstring(selectiondata.get_data()) elif targetname in (INTERNAL_PAGELIST_TARGET_NAME, PAGELIST_TARGET_NAME) \ or targetname in URI_TARGET_NAMES: links = selectiondata.get_uris() return _link_tree(links, notebook, path) elif targetname in TEXT_TARGET_NAMES: # plain text parser should highlight urls etc. # FIXME some apps drop text/uri-list as a text/plain mimetype # try to catch this situation by a check here text = selectiondata.get_text() if text: if text_format in ('verbatim', 'verbatim-pre', 'verbatim-code'): if text_format == 'verbatim': tag_name = 'pre' if '\n' in text else 'code' else: tag_name = text_format[9:] builder = ParseTreeBuilder(partial=True) builder.start('zim-tree', {}) builder.start(tag_name, {}) builder.text(text) builder.end(tag_name) builder.end('zim-tree') return builder.get_parsetree() else: return get_format(text_format).Parser().parse(text, partial=True) else: return None elif targetname in IMAGE_TARGET_NAMES: # save image pixbuf = selectiondata.get_pixbuf() if not pixbuf: return None dir = notebook.get_attachments_dir(path) assert isinstance(dir, LocalFolder) or hasattr( dir, '_folder') and isinstance(dir._folder, LocalFolder) # XXX: assert we have local path - HACK to deal with FilesAttachmentFolder if not dir.exists(): logger.debug("Creating attachment dir: %s", dir) dir.touch() format, extension = _get_image_info(targetname) if format is None or format == 'bmp': # default to png format # special casing bmp since many window apps use it internally # but is quite large to store, so compress by using png format, extension = 'png', 'png' file = dir.new_file('pasted_image.%s' % extension) logger.debug("Saving image from clipboard to %s", file) pixbuf.savev(file.path, format, [], []) FS.emit('path-created', file) # notify version control links = [file.uri] return _link_tree(links, notebook, path) else: return None
def parsetree_from_selectiondata(selectiondata, notebook=None, path=None): '''Function to get a parsetree based on the selectiondata contents if at all possible. Used by both copy-paste and drag-and-drop methods. The 'notebook' and optional 'path' arguments are used to format links relative to the page which is the target for the pasting or drop operation. For image data, the parameters notebook and page are used to save the image to the correct attachment folder and return a parsetree with the correct image link. @param selectiondata: a C{gtk.SelectionData} object @param notebook: a L{Notebook} object @param path: a L{Path} object @returns: a L{ParseTree} or C{None} ''' # TODO: check relative linking for all parsetrees !!! targetname = str(selectiondata.target) if targetname == PARSETREE_TARGET_NAME: return ParseTree().fromstring(selectiondata.data) elif targetname in (INTERNAL_PAGELIST_TARGET_NAME, PAGELIST_TARGET_NAME) \ or targetname in URI_TARGET_NAMES: links = unpack_urilist(selectiondata.data) return _link_tree(links, notebook, path) elif targetname in TEXT_TARGET_NAMES: # plain text parser should highlight urls etc. # FIXME some apps drop text/uri-list as a text/plain mimetype # try to catch this situation by a check here text = selectiondata.get_text() if text: return get_format('plain').Parser().parse(text.decode('utf-8'), partial=True) else: return None elif targetname in IMAGE_TARGET_NAMES: # save image pixbuf = selectiondata.get_pixbuf() if not pixbuf: return None dir = notebook.get_attachments_dir(path) if not dir.exists(): logger.debug("Creating attachment dir: %s", dir) dir.touch() format, extension = _get_image_info(targetname) if format is None or format == 'bmp': # default to png format # special casing bmp since many window apps use it internally # but is quite large to store, so compress by using png format, extension = 'png', 'png' file = dir.new_file('pasted_image.%s' % extension) logger.debug("Saving image from clipboard to %s", file) pixbuf.save(file.path, format) FS.emit('path-created', file) # notify version control links = [file.uri] return _link_tree(links, notebook, path) else: return None
def get_exporter(self, page): from zim.fs import File, Dir from zim.export import \ build_mhtml_file_exporter, \ build_single_file_exporter, \ build_page_exporter, \ build_notebook_exporter format = self.opts.get('format', 'html') if not 'output' in self.opts: raise UsageError(_('Output location needed for export') ) # T: error in export command output = Dir(self.opts['output']) if not output.isdir(): output = File(self.opts.get('output')) template = self.opts.get('template', 'Default') if output.exists() and not self.opts.get('overwrite'): if output.isdir(): if len(output.list()) > 0: raise Error( _('Output folder exists and not empty, specify "--overwrite" to force export' )) # T: error message for export else: pass else: raise Error( _('Output file exists, specify "--overwrite" to force export' )) # T: error message for export if format == 'mhtml': self.ignore_options('index-page') if output.isdir(): raise UsageError(_('Need output file to export MHTML') ) # T: error message for export exporter = build_mhtml_file_exporter( output, template, document_root_url=self.opts.get('root-url'), ) elif self.opts.get('singlefile'): self.ignore_options('index-page') if output.exists() and output.isdir(): ext = get_format(format).info['extension'] output = output.file(page.basename) + '.' + ext exporter = build_single_file_exporter( output, format, template, namespace=page, document_root_url=self.opts.get('root-url'), ) elif page: self.ignore_options('index-page') if output.exists() and output.isdir(): ext = get_format(format).info['extension'] output = output.file(page.basename) + '.' + ext exporter = build_page_exporter( output, format, template, page, document_root_url=self.opts.get('root-url'), ) else: if not output.exists(): output = Dir(output.path) elif not output.isdir(): raise UsageError( _('Need output folder to export full notebook') ) # T: error message for export exporter = build_notebook_exporter( output, format, template, index_page=self.opts.get('index-page'), document_root_url=self.opts.get('root-url'), ) return exporter