Exemple #1
0
    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 []
Exemple #2
0
	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
Exemple #3
0
 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
Exemple #4
0
	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
Exemple #5
0
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
Exemple #6
0
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 []