def _dump(self): '''Returns the page source''' tree = self.get_parsetree() if tree is None: raise AssertionError, 'BUG: Can not store a page without content' #~ print 'STORE', tree.tostring() if tree.hascontent: new = False if self.properties is None: self.properties = HeadersDict() new = True self.properties['Content-Type'] = 'text/x-zim-wiki' self.properties['Wiki-Format'] = WIKI_FORMAT_VERSION if new: now = datetime.now() self.properties['Creation-Date'] = now.isoformat() # Note: No "Modification-Date" here because it causes conflicts # when merging branches with version control, use mtime from filesystem # If we see this header, remove it because it will not be updated. try: del self.properties['Modification-Date'] except: pass lines = self.properties.dump() lines.append('\n') lines.extend(self.format.Dumper().dump(tree)) return lines else: return []
def _store_parsetree(self): '''Save a parse tree to page source''' tree = self.get_parsetree() assert tree, 'BUG: Can not store a page without content' #~ print 'STORE', tree.tostring() if tree.hascontent: new = False if not self.properties: self.properties = HeadersDict() new = True self.properties['Content-Type'] = 'text/x-zim-wiki' self.properties['Wiki-Format'] = 'zim 0.26' if new: now = datetime.now() self.properties['Creation-Date'] = now.isoformat() # Note: No "Modification-Date" here because it causes conflicts # when merging branches with version control, use mtime from filesystem lines = self.properties.dump() lines.append('\n') lines.extend(self.format.Dumper().dump(tree)) self.source.writelines(lines) else: # Remove the file - this is not the same as remove_page() self.source.cleanup() self.modified = False
def _fetch_parsetree(self, lines=None): '''Fetch a parsetree from source or returns None''' #~ print '!! fetch tree', self ## Enable these lines to test error handling in the UI #~ import random #~ if random.random() > 0.5: #~ raise Exception, 'This is a test error' ### try: lines = lines or self.source.readlines() self.properties = HeadersDict() self.properties.read(lines) # TODO: detect other formats by the header as well if 'Wiki-Format' in self.properties: version = self.properties['Wiki-Format'] else: version = 'Unknown' parser = self.format.Parser(version) return parser.parse(lines) except FileNotFoundError: return None
def _fetch_parsetree(self, lines=None): '''Fetch a parsetree from source or returns None''' #~ print '!! fetch tree', self if lines or self.source.exists(): lines = lines or self.source.readlines() self.properties = HeadersDict() self.properties.read(lines) # TODO: detect other formats by the header as well if 'Wiki-Format' in self.properties: version = self.properties['Wiki-Format'] else: version = 'Unknown' parser = self.format.Parser(version) return parser.parse(lines) else: return None
class FileStorePage(Page): def __init__(self, path, haschildren=False, source=None, format=None): assert source and format Page.__init__(self, path, haschildren) self.source = source self.format = format self.source.checkoverwrite = True self.readonly = not self.source.iswritable() def _source_hascontent(self): return self.source.exists() def _fetch_parsetree(self, lines=None): '''Fetch a parsetree from source or returns None''' #~ print '!! fetch tree', self if lines or self.source.exists(): lines = lines or self.source.readlines() self.properties = HeadersDict() self.properties.read(lines) # TODO: detect other formats by the header as well if 'Wiki-Format' in self.properties: version = self.properties['Wiki-Format'] else: version = 'Unknown' parser = self.format.Parser(version) return parser.parse(lines) else: return None def _store_parsetree(self): '''Save a parse tree to page source''' tree = self.get_parsetree() assert tree, 'BUG: Can not store a page without content' #~ print 'STORE', tree.tostring() if tree.hascontent: new = False if not self.properties: self.properties = HeadersDict() new = True self.properties['Content-Type'] = 'text/x-zim-wiki' self.properties['Wiki-Format'] = 'zim 0.26' if new: now = datetime.now() self.properties['Creation-Date'] = now.isoformat() # Note: No "Modification-Date" here because it causes conflicts # when merging branches with version control, use mtime from filesystem lines = self.properties.dump() lines.append('\n') lines.extend(self.format.Dumper().dump(tree)) self.source.writelines(lines) else: # Remove the file - this is not the same as remove_page() self.source.cleanup() self.modified = False def get_links(self): # Optimised version of get_links, just check if we contain # links at all - if not don't bother parsing the content, # but if we do only trust the parse to get it right # (e.g. taking care of verbatim, escapes etc.) if not (self._parsetree or self._ui_object) \ and hasattr(self.format, 'contains_links'): #~ print '!! FileStorePage.get_links() Optimisation used' if self.source.exists(): lines = self.source.readlines() if self.format.contains_links(lines): self._parsetree = self._fetch_parsetree(lines) for link in Page.get_links(self): yield link else: for link in Page.get_links(self): yield link
class FileStorePage(Page): '''Implementation of L{Page} that has a file as source The source is expected to consist of an header section (which have the same format as email headers) and a body that is some dialect of wiki text. Parsing the source file is delayed till the first call to L{get_parsetree()} so creating an object instance does not have the overhead of file system access. @ivar source: the L{File} object for this page @ivar format: the L{zim.formats} sub-module used for parsing the file ''' def __init__(self, path, source=None, folder=None, format=None): assert source and format Page.__init__(self, path, haschildren=folder.exists()) self.source = source self.folder = folder self.format = format self.readonly = not self.source.iswritable() self.properties = None def isequal(self, other): print "IS EQUAL", self, other if not isinstance(other, FileStorePage): return False if self == other: # If object equal by definition they are the equal return True # If we have an existing source check it # If we have an existing folder check it # If either fails we are not equal # If both do not exist we are also not equal ok = False if self.source and self.source.exists(): ok = (other.source and self.source.isequal(other.source)) if not ok: return False if self.folder and self.folder.exists(): ok = (other.folder and self.folder.isequal(other.folder)) return ok def _source_hascontent(self): return self.source.exists() def _fetch_parsetree(self, lines=None): '''Fetch a parsetree from source or returns None''' #~ print '!! fetch tree', self ## Enable these lines to test error handling in the UI #~ import random #~ if random.random() > 0.5: #~ raise Exception, 'This is a test error' ### try: lines = lines or self.source.readlines() self.properties = HeadersDict() self.properties.read(lines) # TODO: detect other formats by the header as well if 'Wiki-Format' in self.properties: version = self.properties['Wiki-Format'] else: version = 'Unknown' parser = self.format.Parser(version) return parser.parse(lines) except FileNotFoundError: return None def _store(self): lines = self._dump() self._store_lines(lines) self.modified = False def _store_async(self): # Get lines before forking a new thread, otherwise the parsetree # could change in a non-atomic way in the GUI in the mean time lines = self._dump() self.modified = False #~ print '!! STORE PAGE ASYNC in files' func = FunctionThread(self._store_lines, (lines, )) func.start() return func def _store_lines(self, lines): ## Enable these lines to test error handling in the UI #~ import random #~ if random.random() > 0.5: #~ raise IOError, 'This is a test error' ### if lines: self.source.writelines(lines) else: # Remove the file - this is not the same as remove_page() self.source.cleanup() return True # Need to return True for async callback def _dump(self): '''Returns the page source''' tree = self.get_parsetree() if tree is None: raise AssertionError, 'BUG: Can not store a page without content' #~ print 'STORE', tree.tostring() if tree.hascontent: new = False if self.properties is None: self.properties = HeadersDict() new = True self.properties['Content-Type'] = 'text/x-zim-wiki' self.properties['Wiki-Format'] = WIKI_FORMAT_VERSION if new: now = datetime.now() self.properties['Creation-Date'] = now.isoformat() # Note: No "Modification-Date" here because it causes conflicts # when merging branches with version control, use mtime from filesystem # If we see this header, remove it because it will not be updated. try: del self.properties['Modification-Date'] except: pass lines = self.properties.dump() lines.append('\n') lines.extend(self.format.Dumper().dump(tree)) return lines else: return []