Exemple #1
0
    def run(self):
        from zim.export.selections import AllPages, SinglePage, SubPages
        from zim.plugins import PluginManager
        from zim.config import ConfigManager

        notebook, page = self.build_notebook()

        # load plugins, needed so the the proper export functions would work from CLI
        config = ConfigManager(profile=notebook.profile)
        plugins = PluginManager(config)
        plugins.extend(notebook.index)
        plugins.extend(notebook)

        if page and self.opts.get('recursive'):
            selection = SubPages(notebook, page)
        elif page:
            selection = SinglePage(notebook, page)
        else:
            selection = AllPages(notebook)

        exporter = self.get_exporter(page)
        exporter.export(selection)
    def _run_new_window(self, notebook, page):
        from gi.repository import GObject

        from zim.gui.mainwindow import MainWindow
        from zim.config import ConfigManager
        from zim.plugins import PluginManager

        config = ConfigManager()
        preferences = config.preferences['General']
        preferences.setdefault('plugins', [
            'pageindex',
            'pathbar',
            'journal',
            'insertsymbol',
            'printtobrowser',
            'versioncontrol',
        ])

        # Upgrade plugin list
        preferences.setdefault('plugins_list_version', 'none')
        if preferences['plugins_list_version'] != '0.68':
            preferences['plugins'].extend(['pageindex', 'pathbar'])
            if 'calendar' in preferences['plugins']:
                preferences['plugins'].remove('calendar')
                preferences['plugins'].append('journal')
                config.preferences['JournalPlugin'] = config.preferences[
                    'CalendarPlugin']
            preferences['plugins_list_version'] = '0.68'

        pluginmanager = PluginManager(config)
        pluginmanager.extend(notebook)

        window = MainWindow(notebook,
                            config,
                            page=page,
                            **self.get_options('geometry', 'fullscreen'))
        pluginmanager.extend(window)
        pluginmanager.extend(window.pageview)
        window.__pluginmanager__ = pluginmanager  # HACK to allow dialogs to find it
        window.present()

        if not window.notebook.index.is_uptodate:
            window._uiactions.reload_index(update_only=True)  # XXX
        else:
            # Start a lightweight background check of the index
            # put a small delay to ensure window is shown before we start
            def start_background_check():
                notebook.index.start_background_check(notebook)
                return False  # only run once

            GObject.timeout_add(500, start_background_check)

        return window
Exemple #3
0
class WWWInterface(object):
    '''Class to handle the WWW interface for zim notebooks.

	Objects of this class are callable, so they can be used as application
	objects within a WSGI compatible framework. See PEP 333 for details
	(U{http://www.python.org/dev/peps/pep-0333/}).

	For basic handlers to run this interface see the "wsgiref" package
	in the standard library for python.
	'''
    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)

        #~ self.notebook.indexer.check_and_update()

    def __call__(self, environ, start_response):
        '''Main function for handling a single request. Follows the
		WSGI API.

		@param environ: dictionary with environment variables for the
		request and some special variables. See the PEP for expected
		variables.

		@param start_response: a function that can be called to set the
		http response and headers. For example::

			start_response(200, [('Content-Type', 'text/plain')])

		@returns: the html page content as a list of lines
		'''
        headerlist = []
        headers = Headers(headerlist)
        path = environ.get('PATH_INFO', '/')
        try:
            methods = ('GET', 'HEAD')
            if not environ['REQUEST_METHOD'] in methods:
                raise WWWError('405', headers=[('Allow', ', '.join(methods))])

            # cleanup path
            #~ print 'INPUT', path
            path = path.replace('\\', '/')  # make it windows save
            isdir = path.endswith('/')
            parts = [p for p in path.split('/') if p and not p == '.']
            if [p for p in parts if p.startswith('.')]:
                # exclude .. and all hidden files from possible paths
                raise WebPathNotValidError()
            path = '/' + '/'.join(parts)
            if isdir and not path == '/':
                path += '/'
            #~ print 'PATH', path

            if not path:
                path = '/'
            elif path == '/favicon.ico':
                path = '/+resources/favicon.ico'
            else:
                path = urllib.unquote(path)

            if path == '/':
                headers.add_header('Content-Type',
                                   'text/html',
                                   charset='utf-8')
                content = self.render_index()
            elif path.startswith('/+docs/'):
                dir = self.notebook.document_root
                if not dir:
                    raise WebPageNotFoundError(path)
                file = dir.file(path[7:])
                content = [file.raw()]
                # Will raise FileNotFound when file does not exist
                headers['Content-Type'] = file.get_mimetype()
            elif path.startswith('/+file/'):
                file = self.notebook.dir.file(path[7:])
                # TODO: need abstraction for getting file from top level dir ?
                content = [file.raw()]
                # Will raise FileNotFound when file does not exist
                headers['Content-Type'] = file.get_mimetype()
            elif path.startswith('/+resources/'):
                if self.template.resources_dir:
                    file = self.template.resources_dir.file(path[12:])
                    if not file.exists():
                        file = data_file('pixmaps/%s' % path[12:])
                else:
                    file = data_file('pixmaps/%s' % path[12:])

                if file:
                    content = [file.raw()]
                    # Will raise FileNotFound when file does not exist
                    headers['Content-Type'] = file.get_mimetype()
                else:
                    raise WebPageNotFoundError(path)
            else:
                # Must be a page or a namespace (html file or directory path)
                headers.add_header('Content-Type',
                                   'text/html',
                                   charset='utf-8')
                if path.endswith('.html'):
                    pagename = path[:-5].replace('/', ':')
                elif path.endswith('/'):
                    pagename = path[:-1].replace('/', ':')
                else:
                    raise WebPageNotFoundError(path)

                path = self.notebook.pages.lookup_from_user_input(pagename)
                try:
                    page = self.notebook.get_page(path)
                    if page.hascontent:
                        content = self.render_page(page)
                    elif page.haschildren:
                        content = self.render_index(page)
                    else:
                        raise WebPageNotFoundError(path)
                except PageNotFoundError:
                    raise WebPageNotFoundError(path)
        except Exception as error:
            headerlist = []
            headers = Headers(headerlist)
            headers.add_header('Content-Type', 'text/plain', charset='utf-8')
            if isinstance(error, (WWWError, FileNotFoundError)):
                logger.error(error.msg)
                if isinstance(error, FileNotFoundError):
                    error = WebPageNotFoundError(path)
                    # show url path instead of file path
                if error.headers:
                    for key, value in error.headers:
                        headers.add_header(key, value)
                start_response(error.status, headerlist)
                content = unicode(error).splitlines(True)
            # TODO also handle template errors as special here
            else:
                # Unexpected error - maybe a bug, do not expose output on bugs
                # to the outside world
                logger.exception('Unexpected error:')
                start_response('500 Internal Server Error', headerlist)
                content = ['Internal Server Error']
            if environ['REQUEST_METHOD'] == 'HEAD':
                return []
            else:
                return [string.encode('utf-8') for string in content]
        else:
            start_response('200 OK', headerlist)
            if environ['REQUEST_METHOD'] == 'HEAD':
                return []
            elif 'utf-8' in headers['Content-Type']:
                return [string.encode('utf-8') for string in content]
            else:
                return content

    def render_index(self, namespace=None):
        '''Render an index page
		@param namespace: the namespace L{Path}
		@returns: html as a list of lines
		'''
        path = namespace or Path(':')
        page = createIndexPage(self.notebook, path, namespace)
        return self.render_page(page)

    def render_page(self, page):
        '''Render a single page from the notebook
		@param page: a L{Page} object
		@returns: html as a list of lines
		'''
        lines = []

        context = ExportTemplateContext(
            self.notebook,
            self.linker_factory,
            self.dumper_factory,
            title=page.get_title(),
            content=[page],
            home=self.notebook.get_home_page(),
            up=page.parent if page.parent and not page.parent.isroot else None,
            prevpage=self.notebook.pages.get_previous(page)
            if not page.isroot else None,
            nextpage=self.notebook.pages.get_next(page)
            if not page.isroot else None,
            links={'index': '/'},
            index_generator=self.notebook.pages.walk,
            index_page=page,
        )
        self.template.process(lines, context)
        return lines
Exemple #4
0
Fichier : www.py Projet : gdw2/zim
class WWWInterface(object):
	'''Class to handle the WWW interface for zim notebooks.

	Objects of this class are callable, so they can be used as application
	objects within a WSGI compatible framework. See PEP 333 for details
	(U{http://www.python.org/dev/peps/pep-0333/}).

	For basic handlers to run this interface see the "wsgiref" package
	in the standard library for python.
	'''

	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 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 = WWWLinker(self.notebook)
		self.template.set_linker(self.linker)

		self.plugins = PluginManager(self.config)
		self.plugins.extend(notebook.index)
		self.plugins.extend(notebook)
		self.plugins.extend(self)

		#~ self.notebook.index.update()

	def __call__(self, environ, start_response):
		'''Main function for handling a single request. Follows the
		WSGI API.

		@param environ: dictionary with environment variables for the
		request and some special variables. See the PEP for expected
		variables.

		@param start_response: a function that can be called to set the
		http response and headers. For example::

			start_response(200, [('Content-Type', 'text/plain')])

		@returns: the html page content as a list of lines
		'''
		headerlist = []
		headers = Headers(headerlist)
		path = environ.get('PATH_INFO', '/')
		try:
			methods = ('GET', 'HEAD')
			if not environ['REQUEST_METHOD'] in methods:
				raise WWWError('405', headers=[('Allow', ', '.join(methods))])

			# cleanup path
			#~ print 'INPUT', path
			path = path.replace('\\', '/') # make it windows save
			isdir = path.endswith('/')
			parts = [p for p in path.split('/') if p and not p == '.']
			if [p for p in parts if p.startswith('.')]:
				# exclude .. and all hidden files from possible paths
				raise PathNotValidError()
			path = '/' + '/'.join(parts)
			if isdir and not path == '/': path += '/'
			#~ print 'PATH', path

			if not path:
				path = '/'
			elif path == '/favicon.ico':
				path = '/+resources/favicon.ico'
			else:
				path = urllib.unquote(path)

			if path == '/':
				headers.add_header('Content-Type', 'text/html', charset='utf-8')
				content = self.render_index()
			elif path.startswith('/+docs/'):
				dir = self.notebook.document_root
				if not dir:
					raise PageNotFoundError(path)
				file = dir.file(path[7:])
				content = [file.raw()]
					# Will raise FileNotFound when file does not exist
				headers['Content-Type'] = file.get_mimetype()
			elif path.startswith('/+file/'):
				file = self.notebook.dir.file(path[7:])
					# TODO: need abstraction for getting file from top level dir ?
				content = [file.raw()]
					# Will raise FileNotFound when file does not exist
				headers['Content-Type'] = file.get_mimetype()
 			elif path.startswith('/+resources/'):
				if self.template.resources_dir:
					file = self.template.resources_dir.file(path[12:])
					if not file.exists():
						file = data_file('pixmaps/%s' % path[12:])
				else:
					file = data_file('pixmaps/%s' % path[12:])

				if file:
					content = [file.raw()]
						# Will raise FileNotFound when file does not exist
					headers['Content-Type'] = file.get_mimetype()
	 			else:
					raise PageNotFoundError(path)
			else:
				# Must be a page or a namespace (html file or directory path)
				headers.add_header('Content-Type', 'text/html', charset='utf-8')
				if path.endswith('.html'):
					pagename = path[:-5].replace('/', ':')
				elif path.endswith('/'):
					pagename = path[:-1].replace('/', ':')
				else:
					raise PageNotFoundError(path)

				path = self.notebook.resolve_path(pagename)
				page = self.notebook.get_page(path)
				if page.hascontent:
					content = self.render_page(page)
				elif page.haschildren:
					content = self.render_index(page)
				else:
					raise PageNotFoundError(page)
		except Exception, error:
			headerlist = []
			headers = Headers(headerlist)
			headers.add_header('Content-Type', 'text/plain', charset='utf-8')
			if isinstance(error, (WWWError, FileNotFoundError)):
				logger.error(error.msg)
				if isinstance(error, FileNotFoundError):
					error = PageNotFoundError(path)
					# show url path instead of file path
				if error.headers:
					for key, value in error.headers:
						headers.add_header(key, value)
				start_response(error.status, headerlist)
				content = unicode(error).splitlines(True)
			# TODO also handle template errors as special here
			else:
				# Unexpected error - maybe a bug, do not expose output on bugs
				# to the outside world
				logger.exception('Unexpected error:')
				start_response('500 Internal Server Error', headerlist)
				content = ['Internal Server Error']
			if environ['REQUEST_METHOD'] == 'HEAD':
				return []
			else:
				return [string.encode('utf-8') for string in content]
		else: