예제 #1
0
파일: quicknote.py 프로젝트: thejeshgn/Zim
	def __init__(self, ui, notebook=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None):
		self.config = get_config('quicknote.conf')
		self.uistate = self.config['QuickNoteDialog']

		Dialog.__init__(self, ui, _('Quick Note'))
		self._updating_title = False
		self._title_set_manually = not basename is None
		self.attachments = attachments

		if notebook and not isinstance(notebook, basestring):
			notebook = notebook.uri

		self.uistate.setdefault('lastnotebook', None, basestring)
		if self.uistate['lastnotebook']:
			notebook = notebook or self.uistate['lastnotebook']
			self.config['Namespaces'].setdefault(notebook, None, basestring)
			namespace = namespace or self.config['Namespaces'][notebook]

		self.form = InputForm()
		self.vbox.pack_start(self.form, False)

		# TODO dropdown could use an option "Other..."
		label = gtk.Label(_('Notebook')+': ')
		label.set_alignment(0.0, 0.5)
		self.form.attach(label, 0,1, 0,1, xoptions=gtk.FILL)
			# T: Field to select Notebook from drop down list
		self.notebookcombobox = NotebookComboBox(current=notebook)
		self.notebookcombobox.connect('changed', self.on_notebook_changed)
		self.form.attach(self.notebookcombobox, 1,2, 0,1)

		self._init_inputs(namespace, basename, append, text, template_options)

		self.uistate['lastnotebook'] = notebook
		self._set_autocomplete(notebook)
예제 #2
0
    def __init__(self,
                 window,
                 notebook=None,
                 page=None,
                 namespace=None,
                 basename=None,
                 append=None,
                 text=None,
                 template_options=None,
                 attachments=None):
        assert page is None, 'TODO'

        manager = ConfigManager()  # FIXME should be passed in
        self.config = manager.get_config_dict('quicknote.conf')
        self.uistate = self.config['QuickNoteDialog']

        Dialog.__init__(self, window, _('Quick Note'))
        self._updating_title = False
        self._title_set_manually = not basename is None
        self.attachments = attachments

        if notebook and not isinstance(notebook, str):
            notebook = notebook.uri

        self.uistate.setdefault('lastnotebook', None, str)
        if self.uistate['lastnotebook']:
            notebook = notebook or self.uistate['lastnotebook']
            self.config['Namespaces'].setdefault(notebook, None, str)
            namespace = namespace or self.config['Namespaces'][notebook]

        self.form = InputForm()
        self.vbox.pack_start(self.form, False, True, 0)

        # TODO dropdown could use an option "Other..."
        label = Gtk.Label(label=_('Notebook') + ': ')
        label.set_alignment(0.0, 0.5)
        self.form.attach(label, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL)
        # T: Field to select Notebook from drop down list
        self.notebookcombobox = NotebookComboBox(current=notebook)
        self.notebookcombobox.connect('changed', self.on_notebook_changed)
        self.form.attach(self.notebookcombobox, 1, 2, 0, 1)

        self._init_inputs(namespace, basename, append, text, template_options)

        self.uistate['lastnotebook'] = notebook
        self._set_autocomplete(notebook)
예제 #3
0
class QuickNoteDialog(Dialog):
    '''Dialog bound to a specific notebook'''
    def __init__(self,
                 window,
                 notebook=None,
                 page=None,
                 namespace=None,
                 basename=None,
                 append=None,
                 text=None,
                 template_options=None,
                 attachments=None):
        assert page is None, 'TODO'

        manager = ConfigManager()  # FIXME should be passed in
        self.config = manager.get_config_dict('quicknote.conf')
        self.uistate = self.config['QuickNoteDialog']

        Dialog.__init__(self, window, _('Quick Note'))
        self._updating_title = False
        self._title_set_manually = not basename is None
        self.attachments = attachments

        if notebook and not isinstance(notebook, str):
            notebook = notebook.uri

        self.uistate.setdefault('lastnotebook', None, str)
        if self.uistate['lastnotebook']:
            notebook = notebook or self.uistate['lastnotebook']
            self.config['Namespaces'].setdefault(notebook, None, str)
            namespace = namespace or self.config['Namespaces'][notebook]

        self.form = InputForm()
        self.vbox.pack_start(self.form, False, True, 0)

        # TODO dropdown could use an option "Other..."
        label = Gtk.Label(label=_('Notebook') + ': ')
        label.set_alignment(0.0, 0.5)
        self.form.attach(label, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL)
        # T: Field to select Notebook from drop down list
        self.notebookcombobox = NotebookComboBox(current=notebook)
        self.notebookcombobox.connect('changed', self.on_notebook_changed)
        self.form.attach(self.notebookcombobox, 1, 2, 0, 1)

        self._init_inputs(namespace, basename, append, text, template_options)

        self.uistate['lastnotebook'] = notebook
        self._set_autocomplete(notebook)

    def _init_inputs(self,
                     namespace,
                     basename,
                     append,
                     text,
                     template_options,
                     custom=None):
        if template_options is None:
            template_options = {}
        else:
            template_options = template_options.copy()

        if namespace is not None and basename is not None:
            page = namespace + ':' + basename
        else:
            page = namespace or basename

        self.form.add_inputs((
            ('page', 'page', _('Page')),
            ('namespace', 'namespace',
             _('Page section')),  # T: text entry field
            ('new_page', 'bool', _('Create a new page for each note')
             ),  # T: checkbox in Quick Note dialog
            ('basename', 'string', _('Title'))  # T: text entry field
        ))
        self.form.update({
            'page': page,
            'namespace': namespace,
            'new_page': True,
            'basename': basename,
        })

        self.uistate.setdefault('open_page', True)
        self.uistate.setdefault('new_page', True)

        if basename:
            self.uistate['new_page'] = True  # Be consistent with input

        # Set up the inputs and set page/ namespace to switch on
        # toggling the checkbox
        self.form.widgets['page'].set_no_show_all(True)
        self.form.widgets['namespace'].set_no_show_all(True)
        if append is None:
            self.form['new_page'] = bool(self.uistate['new_page'])
        else:
            self.form['new_page'] = not append

        def switch_input(*a):
            if self.form['new_page']:
                self.form.widgets['page'].hide()
                self.form.widgets['namespace'].show()
                self.form.widgets['basename'].set_sensitive(True)
            else:
                self.form.widgets['page'].show()
                self.form.widgets['namespace'].hide()
                self.form.widgets['basename'].set_sensitive(False)

        switch_input()
        self.form.widgets['new_page'].connect('toggled', switch_input)

        self.open_page_check = Gtk.CheckButton.new_with_mnemonic(
            _('Open _Page'))  # T: Option in quicknote dialog
        # Don't use "O" as accelerator here to avoid conflict with "Ok"
        self.open_page_check.set_active(self.uistate['open_page'])
        self.action_area.pack_start(self.open_page_check, False, True, 0)
        self.action_area.set_child_secondary(self.open_page_check, True)

        # Add the main textview and hook up the basename field to
        # sync with first line of the textview
        window, textview = ScrolledTextView()
        self.textview = textview
        self.textview.set_editable(True)
        self.vbox.pack_start(window, True, True, 0)

        self.form.widgets['basename'].connect('changed', self.on_title_changed)
        self.textview.get_buffer().connect('changed', self.on_text_changed)

        # Initialize text from template
        template = get_template('plugins', 'quicknote.txt')
        template_options['text'] = text or ''
        template_options.setdefault('url', '')

        lines = []
        template.process(lines, template_options)
        buffer = self.textview.get_buffer()
        buffer.set_text(''.join(lines))
        begin, end = buffer.get_bounds()
        buffer.place_cursor(begin)

        buffer.set_modified(False)

        self.connect('delete-event', self.do_delete_event)

    def on_notebook_changed(self, o):
        notebook = self.notebookcombobox.get_notebook()
        if not notebook or notebook == self.uistate['lastnotebook']:
            return

        self.uistate['lastnotebook'] = notebook
        self.config['Namespaces'].setdefault(notebook, None, str)
        namespace = self.config['Namespaces'][notebook]
        if namespace:
            self.form['namespace'] = namespace

        self._set_autocomplete(notebook)

    def _set_autocomplete(self, notebook):
        if notebook:
            try:
                if isinstance(notebook, str):
                    notebook = NotebookInfo(notebook)
                obj, x = build_notebook(notebook)
                self.form.widgets['namespace'].notebook = obj
                self.form.widgets['page'].notebook = obj
                logger.debug('Notebook for autocomplete: %s (%s)', obj,
                             notebook)
            except:
                logger.exception('Could not set notebook: %s', notebook)
        else:
            self.form.widgets['namespace'].notebook = None
            self.form.widgets['page'].notebook = None
            logger.debug('Notebook for autocomplete unset')

    def do_response(self, id):
        if id == Gtk.ResponseType.DELETE_EVENT:
            if self.textview.get_buffer().get_modified():
                ok = QuestionDialog(self, _('Discard note?')).run()
                # T: confirm closing quick note dialog
                if ok:
                    Dialog.do_response(self, id)
                # else pass
            else:
                Dialog.do_response(self, id)
        else:
            Dialog.do_response(self, id)

    def do_delete_event(self, *a):
        # Block deletion if do_response did not yet destroy the dialog
        return True

    def run(self):
        self.textview.grab_focus()
        Dialog.run(self)

    def show(self):
        self.textview.grab_focus()
        Dialog.show(self)

    def save_uistate(self):
        notebook = self.notebookcombobox.get_notebook()
        self.uistate['lastnotebook'] = notebook
        self.uistate['new_page'] = self.form['new_page']
        self.uistate['open_page'] = self.open_page_check.get_active()
        if notebook is not None:
            if self.uistate['new_page']:
                self.config['Namespaces'][notebook] = self.form['namespace']
            else:
                self.config['Namespaces'][notebook] = self.form['page']
        self.config.write()

    def on_title_changed(self, o):
        o.set_input_valid(True)
        if not self._updating_title:
            self._title_set_manually = True

    def on_text_changed(self, buffer):
        if not self._title_set_manually:
            # Automatically generate a (valid) page name
            self._updating_title = True
            start, end = buffer.get_bounds()
            title = start.get_text(end).strip()[:50]
            # Cut off at 50 characters to prevent using a whole paragraph
            title = title.replace(':', '')
            if '\n' in title:
                title, _ = title.split('\n', 1)
            try:
                title = Path.makeValidPageName(title.replace(':', ''))
                self.form['basename'] = title
            except ValueError:
                pass
            self._updating_title = False

    def do_response_ok(self):
        buffer = self.textview.get_buffer()
        start, end = buffer.get_bounds()
        text = start.get_text(end)

        # HACK: change "[]" at start of line into "[ ]" so checkboxes get inserted correctly
        text = re.sub(r'(?m)^(\s*)\[\](\s)', r'\1[ ]\2', text)
        # Specify "(?m)" instead of re.M since "flags" keyword is not
        # supported in python 2.6

        notebook = self._get_notebook()
        if notebook is None:
            return False

        if self.form['new_page']:
            if not self.form.widgets['namespace'].get_input_valid() \
            or not self.form['basename']:
                if not self.form['basename']:
                    entry = self.form.widgets['basename']
                    entry.set_input_valid(False, show_empty_invalid=True)
                return False

            path = self.form['namespace'] + self.form['basename']
            self.create_new_page(notebook, path, text)
        else:
            if not self.form.widgets['page'].get_input_valid() \
            or not self.form['page']:
                return False

            path = self.form['page']
            self.append_to_page(notebook, path, '\n------\n' + text)

        if self.attachments:
            self.import_attachments(notebook, path, self.attachments)

        if self.open_page_check.get_active():
            self.hide()
            ZIM_APPLICATION.present(notebook, path)

        return True

    def _get_notebook(self):
        uri = self.notebookcombobox.get_notebook()
        notebook, p = build_notebook(Dir(uri))
        return notebook

    def create_new_page(self, notebook, path, text):
        page = notebook.get_new_page(path)
        page.parse('wiki', text)  # FIXME format hard coded
        notebook.store_page(page)

    def append_to_page(self, notebook, path, text):
        page = notebook.get_page(path)
        page.parse('wiki', text, append=True)  # FIXME format hard coded
        notebook.store_page(page)

    def import_attachments(self, notebook, path, dir):
        attachments = notebook.get_attachments_dir(path)
        attachments = Dir(attachments.path)  # XXX
        for name in dir.list():
            # FIXME could use list objects, or list_files()
            file = dir.file(name)
            if not file.isdir():
                file.copyto(attachments)
예제 #4
0
class QuickNoteDialog(BoundQuickNoteDialog):
    '''Dialog which includes a notebook chooser'''
    def __init__(self,
                 window,
                 notebook=None,
                 page=None,
                 namespace=None,
                 basename=None,
                 append=None,
                 text=None,
                 template_options=None,
                 attachments=None):
        assert page is None, 'TODO'
        manager = ConfigManager()  # FIXME should be passed in
        self.config = manager.get_config_dict('quicknote.conf')
        self.uistate = self.config['QuickNoteDialog']

        Dialog.__init__(self, window, _('Quick Note'))
        self._updating_title = False
        self._title_set_manually = not basename is None
        self.attachments = attachments

        if notebook and not isinstance(notebook, basestring):
            notebook = notebook.uri

        self.uistate.setdefault('lastnotebook', None, basestring)
        if self.uistate['lastnotebook']:
            notebook = notebook or self.uistate['lastnotebook']
            self.config['Namespaces'].setdefault(notebook, None, basestring)
            namespace = namespace or self.config['Namespaces'][notebook]

        self.form = InputForm()
        self.vbox.pack_start(self.form, False)

        # TODO dropdown could use an option "Other..."
        label = gtk.Label(_('Notebook') + ': ')
        label.set_alignment(0.0, 0.5)
        self.form.attach(label, 0, 1, 0, 1, xoptions=gtk.FILL)
        # T: Field to select Notebook from drop down list
        self.notebookcombobox = NotebookComboBox(current=notebook)
        self.notebookcombobox.connect('changed', self.on_notebook_changed)
        self.form.attach(self.notebookcombobox, 1, 2, 0, 1)

        self._init_inputs(namespace, basename, append, text, template_options)

        self.uistate['lastnotebook'] = notebook
        self._set_autocomplete(notebook)

    def save_uistate(self):
        notebook = self.notebookcombobox.get_notebook()
        self.uistate['lastnotebook'] = notebook
        self.uistate['new_page'] = self.form['new_page']
        self.uistate['open_page'] = self.open_page.get_active()
        if notebook is not None:
            if self.uistate['new_page']:
                self.config['Namespaces'][notebook] = self.form['namespace']
            else:
                self.config['Namespaces'][notebook] = self.form['page']
        self.config.write()

    def on_notebook_changed(self, o):
        notebook = self.notebookcombobox.get_notebook()
        if not notebook or notebook == self.uistate['lastnotebook']:
            return

        self.uistate['lastnotebook'] = notebook
        self.config['Namespaces'].setdefault(notebook, None, basestring)
        namespace = self.config['Namespaces'][notebook]
        if namespace:
            self.form['namespace'] = namespace

        self._set_autocomplete(notebook)

    def _set_autocomplete(self, notebook):
        if notebook:
            if isinstance(notebook, basestring):
                notebook = NotebookInfo(notebook)
            obj, x = build_notebook(notebook)
            self.form.widgets['namespace'].notebook = obj
            self.form.widgets['page'].notebook = obj
            logger.debug('Notebook for autocomplete: %s (%s)', obj, notebook)
        else:
            self.form.widgets['namespace'].notebook = None
            self.form.widgets['page'].notebook = None
            logger.debug('Notebook for autocomplete unset')

    def _get_ui(self):
        start_server_if_not_running()
        notebook = self.notebookcombobox.get_notebook()
        if notebook:
            return ServerProxy().get_notebook(notebook)
        else:
            return None
예제 #5
0
    def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
        '''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
        gtk.Window.__init__(self)
        self.set_title('Zim - ' + _('Web Server'))  # T: Window title
        self.set_border_width(10)
        self.connect('destroy', lambda a: gtk.main_quit())
        self.interface_opts = opts
        self.httpd = None
        self._source_id = None

        # Widgets
        self.status_label = gtk.Label()
        self.status_label.set_markup('<i>' + _('Server not started') + '</i>')
        # T: Status in web server gui
        self.start_button = IconButton('gtk-media-play')
        self.start_button.connect('clicked', lambda o: self.start())
        self.stop_button = IconButton('gtk-media-stop')
        self.stop_button.connect('clicked', lambda o: self.stop())
        self.stop_button.set_sensitive(False)

        if gtk.gtk_version >= (2, 10):
            self.link_button = gtk.LinkButton('')
            self.link_button.set_sensitive(False)
            gtk.link_button_set_uri_hook(lambda o, url: webbrowser.open(url))
        else:
            self.link_button = None

        self.notebookcombobox = NotebookComboBox(current=notebookinfo)
        self.open_button = IconButton('gtk-index')
        self.open_button.connect('clicked',
                                 lambda *a: NotebookDialog(self).run())

        self.portentry = gtk.SpinButton()
        self.portentry.set_numeric(True)
        self.portentry.set_range(80, 10000)
        self.portentry.set_increments(1, 80)
        self.portentry.set_value(port)

        self.public_checkbox = gtk.CheckButton(label=_('Allow public access'))
        # T: Checkbox in web server gui
        self.public_checkbox.set_active(public)

        # Build the interface
        vbox = gtk.VBox()
        self.add(vbox)

        hbox = gtk.HBox(spacing=12)
        hbox.pack_start(self.start_button, False)
        hbox.pack_start(self.stop_button, False)
        hbox.pack_start(self.status_label, False)
        vbox.add(hbox)

        table = input_table_factory((
            (_('Notebook'), self.notebookcombobox, self.open_button),
            # T: Field in web server gui
            (_('Port'), self.portentry),
            # T: Field in web server gui for HTTP port (e.g. port 80)
            self.public_checkbox))
        vbox.add(table)

        if self.link_button:
            hbox = gtk.HBox()
            hbox.pack_end(self.link_button, False)
            vbox.add(hbox)
예제 #6
0
class ServerWindow(gtk.Window):
    def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
        '''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
        gtk.Window.__init__(self)
        self.set_title('Zim - ' + _('Web Server'))  # T: Window title
        self.set_border_width(10)
        self.connect('destroy', lambda a: gtk.main_quit())
        self.interface_opts = opts
        self.httpd = None
        self._source_id = None

        # Widgets
        self.status_label = gtk.Label()
        self.status_label.set_markup('<i>' + _('Server not started') + '</i>')
        # T: Status in web server gui
        self.start_button = IconButton('gtk-media-play')
        self.start_button.connect('clicked', lambda o: self.start())
        self.stop_button = IconButton('gtk-media-stop')
        self.stop_button.connect('clicked', lambda o: self.stop())
        self.stop_button.set_sensitive(False)

        if gtk.gtk_version >= (2, 10):
            self.link_button = gtk.LinkButton('')
            self.link_button.set_sensitive(False)
            gtk.link_button_set_uri_hook(lambda o, url: webbrowser.open(url))
        else:
            self.link_button = None

        self.notebookcombobox = NotebookComboBox(current=notebookinfo)
        self.open_button = IconButton('gtk-index')
        self.open_button.connect('clicked',
                                 lambda *a: NotebookDialog(self).run())

        self.portentry = gtk.SpinButton()
        self.portentry.set_numeric(True)
        self.portentry.set_range(80, 10000)
        self.portentry.set_increments(1, 80)
        self.portentry.set_value(port)

        self.public_checkbox = gtk.CheckButton(label=_('Allow public access'))
        # T: Checkbox in web server gui
        self.public_checkbox.set_active(public)

        # Build the interface
        vbox = gtk.VBox()
        self.add(vbox)

        hbox = gtk.HBox(spacing=12)
        hbox.pack_start(self.start_button, False)
        hbox.pack_start(self.stop_button, False)
        hbox.pack_start(self.status_label, False)
        vbox.add(hbox)

        table = input_table_factory((
            (_('Notebook'), self.notebookcombobox, self.open_button),
            # T: Field in web server gui
            (_('Port'), self.portentry),
            # T: Field in web server gui for HTTP port (e.g. port 80)
            self.public_checkbox))
        vbox.add(table)

        if self.link_button:
            hbox = gtk.HBox()
            hbox.pack_end(self.link_button, False)
            vbox.add(hbox)

    def open_notebook(self, notebook):
        '''Sets the notebook in the combobox

		This method is called by the NotebookDialog when a notebook is opened.
		'''
        self.notebookcombobox.set_notebook(notebook)

    def start(self):
        # Start server
        try:
            uri = self.notebookcombobox.get_notebook()
            if uri:
                notebook, x = build_notebook(NotebookInfo(uri))
                if not notebook:
                    return
            else:
                return

            port = int(self.portentry.get_value())
            public = self.public_checkbox.get_active()
            self.httpd = make_server(notebook, port, public,
                                     **self.interface_opts)
            if sys.platform == 'win32':
                # glib io watch conflicts with socket use on windows..
                # idle handler uses a bit to much CPU for my taste,
                # timeout every 0.5 sec is better
                self.httpd.timeout = 0.1  # 100 ms
                self._source_id = glib.timeout_add(500, self.do_serve_on_poll)
            else:
                self.httpd.timeout = 3  # if no response after 3 sec, drop it
                self._source_id = glib.io_add_watch(
                    self.httpd.fileno(),
                    glib.IO_IN | glib.IO_OUT | glib.IO_ERR | glib.IO_HUP
                    | glib.IO_PRI,  # any event..
                    self.do_serve_on_io)
            logger.info("Serving HTTP on %s port %i...",
                        self.httpd.server_name, self.httpd.server_port)
        except Exception, error:
            ErrorDialog(self, error).run()
            return

        # Update UI
        self.notebookcombobox.set_sensitive(False)
        self.portentry.set_sensitive(False)
        self.public_checkbox.set_sensitive(False)
        self.open_button.set_sensitive(False)
        self.start_button.set_sensitive(False)
        self.stop_button.set_sensitive(True)

        self.status_label.set_markup('<i>' + _('Server started') + '</i>')
        # T: Status in web server gui
        #if self.public_checkbox.get_active():
        #	url = 'http://%s:%i' % (self.httpd.server_name, self.httpd.server_port)
        #else:
        #	url = 'http://localhost:%i' % self.httpd.server_port
        url = 'http://localhost:%i' % self.httpd.server_port
        if self.link_button:
            self.link_button.set_uri(url)
            self.link_button.set_label(url)
            self.link_button.set_sensitive(True)
예제 #7
0
파일: server.py 프로젝트: gdw2/zim
	def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
		'''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
		gtk.Window.__init__(self)
		self.set_title('Zim - ' + _('Web Server')) # T: Window title
		self.set_border_width(10)
		self.connect('destroy', lambda a: gtk.main_quit())
		self.interface_opts = opts
		self.httpd = None
		self._source_id = None

		# Widgets
		self.status_label = gtk.Label()
		self.status_label.set_markup('<i>'+_('Server not started')+'</i>')
			# T: Status in web server gui
		self.start_button = IconButton('gtk-media-play')
		self.start_button.connect('clicked', lambda o: self.start())
		self.stop_button = IconButton('gtk-media-stop')
		self.stop_button.connect('clicked', lambda o: self.stop())
		self.stop_button.set_sensitive(False)

		if gtk.gtk_version >= (2, 10):
			self.link_button = gtk.LinkButton('')
			self.link_button.set_sensitive(False)
			gtk.link_button_set_uri_hook(lambda o, url: webbrowser.open(url))
		else:
			self.link_button = None

		self.notebookcombobox = NotebookComboBox(current=notebookinfo)
		self.open_button = IconButton('gtk-index')
		self.open_button.connect('clicked', lambda *a: NotebookDialog(self).run())

		self.portentry = gtk.SpinButton()
		self.portentry.set_numeric(True)
		self.portentry.set_range(80, 10000)
		self.portentry.set_increments(1, 80)
		self.portentry.set_value(port)

		self.public_checkbox = gtk.CheckButton(label=_('Allow public access'))
			# T: Checkbox in web server gui
		self.public_checkbox.set_active(public)


		# Build the interface
		vbox = gtk.VBox()
		self.add(vbox)

		hbox = gtk.HBox(spacing=12)
		hbox.pack_start(self.start_button, False)
		hbox.pack_start(self.stop_button, False)
		hbox.pack_start(self.status_label, False)
		vbox.add(hbox)

		table = input_table_factory((
			(_('Notebook'), self.notebookcombobox, self.open_button),
				# T: Field in web server gui
			(_('Port'), self.portentry),
				# T: Field in web server gui for HTTP port (e.g. port 80)
			self.public_checkbox
		))
		vbox.add(table)

		if self.link_button:
			hbox = gtk.HBox()
			hbox.pack_end(self.link_button, False)
			vbox.add(hbox)
예제 #8
0
파일: server.py 프로젝트: gdw2/zim
class ServerWindow(gtk.Window):

	def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
		'''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
		gtk.Window.__init__(self)
		self.set_title('Zim - ' + _('Web Server')) # T: Window title
		self.set_border_width(10)
		self.connect('destroy', lambda a: gtk.main_quit())
		self.interface_opts = opts
		self.httpd = None
		self._source_id = None

		# Widgets
		self.status_label = gtk.Label()
		self.status_label.set_markup('<i>'+_('Server not started')+'</i>')
			# T: Status in web server gui
		self.start_button = IconButton('gtk-media-play')
		self.start_button.connect('clicked', lambda o: self.start())
		self.stop_button = IconButton('gtk-media-stop')
		self.stop_button.connect('clicked', lambda o: self.stop())
		self.stop_button.set_sensitive(False)

		if gtk.gtk_version >= (2, 10):
			self.link_button = gtk.LinkButton('')
			self.link_button.set_sensitive(False)
			gtk.link_button_set_uri_hook(lambda o, url: webbrowser.open(url))
		else:
			self.link_button = None

		self.notebookcombobox = NotebookComboBox(current=notebookinfo)
		self.open_button = IconButton('gtk-index')
		self.open_button.connect('clicked', lambda *a: NotebookDialog(self).run())

		self.portentry = gtk.SpinButton()
		self.portentry.set_numeric(True)
		self.portentry.set_range(80, 10000)
		self.portentry.set_increments(1, 80)
		self.portentry.set_value(port)

		self.public_checkbox = gtk.CheckButton(label=_('Allow public access'))
			# T: Checkbox in web server gui
		self.public_checkbox.set_active(public)


		# Build the interface
		vbox = gtk.VBox()
		self.add(vbox)

		hbox = gtk.HBox(spacing=12)
		hbox.pack_start(self.start_button, False)
		hbox.pack_start(self.stop_button, False)
		hbox.pack_start(self.status_label, False)
		vbox.add(hbox)

		table = input_table_factory((
			(_('Notebook'), self.notebookcombobox, self.open_button),
				# T: Field in web server gui
			(_('Port'), self.portentry),
				# T: Field in web server gui for HTTP port (e.g. port 80)
			self.public_checkbox
		))
		vbox.add(table)

		if self.link_button:
			hbox = gtk.HBox()
			hbox.pack_end(self.link_button, False)
			vbox.add(hbox)


	def open_notebook(self, notebook):
		'''Sets the notebook in the combobox

		This method is called by the NotebookDialog when a notebook is opened.
		'''
		self.notebookcombobox.set_notebook(notebook)

	def start(self):
		# Start server
		try:
			uri = self.notebookcombobox.get_notebook()
			if uri:
				notebook, x = build_notebook(NotebookInfo(uri))
				if not notebook:
					return
			else:
				return

			port = int(self.portentry.get_value())
			public = self.public_checkbox.get_active()
			self.httpd = make_server(notebook, port, public, **self.interface_opts)
			if sys.platform == 'win32':
				# glib io watch conflicts with socket use on windows..
				# idle handler uses a bit to much CPU for my taste,
				# timeout every 0.5 sec is better
				self.httpd.timeout = 0.1 # 100 ms
				self._source_id = glib.timeout_add(500, self.do_serve_on_poll)
			else:
				self.httpd.timeout = 3 # if no response after 3 sec, drop it
				self._source_id = glib.io_add_watch(
					self.httpd.fileno(),
					glib.IO_IN | glib.IO_OUT | glib.IO_ERR | glib.IO_HUP | glib.IO_PRI, # any event..
					self.do_serve_on_io
				)
			logger.info("Serving HTTP on %s port %i...", self.httpd.server_name, self.httpd.server_port)
		except Exception, error:
			ErrorDialog(self, error).run()
			return

		# Update UI
		self.notebookcombobox.set_sensitive(False)
		self.portentry.set_sensitive(False)
		self.public_checkbox.set_sensitive(False)
		self.open_button.set_sensitive(False)
		self.start_button.set_sensitive(False)
		self.stop_button.set_sensitive(True)

		self.status_label.set_markup('<i>'+_('Server started')+'</i>')
			# T: Status in web server gui
		#if self.public_checkbox.get_active():
		#	url = 'http://%s:%i' % (self.httpd.server_name, self.httpd.server_port)
		#else:
		#	url = 'http://localhost:%i' % self.httpd.server_port
		url = 'http://localhost:%i' % self.httpd.server_port
		if self.link_button:
			self.link_button.set_uri(url)
			self.link_button.set_label(url)
			self.link_button.set_sensitive(True)
예제 #9
0
    def runTest(self):
        from zim.gui.notebookdialog import NotebookComboBox, NotebookTreeModel

        class MyList(list):
            pass

        notebooklist = MyList([
            NotebookInfo('file:///test/foo', name='Foo'),
            NotebookInfo('file:///test/bar', name='Bar')
        ])
        notebooklist.default = notebooklist[1]
        notebooklist.write = lambda: None

        model = NotebookTreeModel(notebooklist)

        combobox = NotebookComboBox(model)
        self.assertEqual(combobox.get_notebook(),
                         notebooklist[1].uri)  # default

        combobox.set_active(-1)
        self.assertEqual(combobox.get_notebook(), None)

        combobox.set_notebook(notebooklist[0].uri)
        self.assertEqual(combobox.get_notebook(), notebooklist[0].uri)

        combobox.set_notebook('file:///yet/another/notebook')
        self.assertEqual(combobox.get_notebook(), None)

        combobox.set_notebook('file:///yet/another/notebook', append=True)
        self.assertEqual(combobox.get_notebook(),
                         'file:///yet/another/notebook')
예제 #10
0
	def __init__(self, server):
		'''Constructor needs a Server object to control'''
		gtk.Window.__init__(self)
		self.set_icon_from_file(data_file('zim.png').path)
			# TODO new icon for WWW frontend
		self.set_border_width(10)
		self.connect('destroy', lambda a: gtk.main_quit())

		self.server = server
		self.server.connect_after('started', self.do_server_started)
		self.server.connect_after('stopped', self.do_server_stopped)

		def _start(*a):
			self.server.set_notebook(
				self.notebookcombobox.get_notebook() )
			self.server.start()

		def _stop(*a): self.server.stop()

		# Build the interface
		vbox = gtk.VBox()
		self.add(vbox)

		# first some art work
		#~ path = data_file('globe_banner_small.png').path
		#~ image = gtk.Image()
		#~ image.set_from_file(path) # new_from_file not in 2.6
		#~ align = gtk.Alignment(0,0.5, 0,0)
		#~ align.add(image)
		#~ vbox.add(align)

		# Table with status
		table = gtk.Table(4, 2, False)
		table.set_col_spacings(12)
		table.set_row_spacings(5)
		hbox = gtk.HBox()
		hbox.pack_start(table, False)
		vbox.pack_start(hbox, False)

		self.status_icon = gtk.image_new_from_stock(*stock_stopped)
		table.attach(self.status_icon, 0,2, 0,2)
		self.status_label = gtk.Label()
		self.status_label.set_markup('<i>'+_('Server not started')+'</i>')
			# T: Status in web server gui
		table.attach(self.status_label, 4,5, 0,1)
		self.link_button = gtk.LinkButton('') # FIXME since 2.10
		self.link_button.set_sensitive(False)
		gtk.link_button_set_uri_hook(lambda o, url: webbrowser.open(url))
		table.attach(self.link_button, 4,5, 1,2)

		start_button = IconButton('gtk-media-play')
		start_button.connect('clicked', _start)
		table.attach(start_button, 2,3, 0,1)
		stop_button = IconButton('gtk-media-stop')
		stop_button.connect('clicked', _stop)
		table.attach(stop_button, 3,4, 0,1)

		# Table with server properties
		table = gtk.Table(3, 3, False)
		table.set_col_spacings(12)
		table.set_row_spacings(5)
		vbox.add(table)

		table.attach(gtk.Label(_('Notebook')+': '), 0,1, 0,1)
			# T: Field in web server gui
		self.notebookcombobox = NotebookComboBox(current=server.interface.notebook)
		self.notebookcombobox.connect('changed', _stop)
		table.attach(self.notebookcombobox, 1,2, 0,1)

		open_button = IconButton('gtk-index')
		open_button.connect('clicked', lambda *a: NotebookDialog(self).run())
		table.attach(open_button, 2,3, 0,1)

		table.attach(gtk.Label(_('Port')+': '), 0,1, 1,2)
			# T: Field in web server gui for HTTLP port (e.g. port 80)
		self.portentry = gtk.SpinButton()
		self.portentry.set_numeric(True)
		self.portentry.set_range(80, 10000)
		self.portentry.set_increments(1, 80)
		self.portentry.set_value(self.server.port)
		self.portentry.connect('value-changed', _stop)
		self.portentry.connect('value-changed',
			lambda o: self.server.set_port(self.portentry.get_value_as_int()))
		table.attach(self.portentry, 1,2, 1,2)
예제 #11
0
    def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
        '''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
        GObject.GObject.__init__(self)
        self.set_title('Zim - ' + _('Web Server'))  # T: Window title
        self.set_border_width(10)
        self.interface_opts = opts
        self.httpd = None
        self._source_id = None

        # Widgets
        self.status_label = Gtk.Label()
        self.status_label.set_markup('<i>' + _('Server not started') + '</i>')
        # T: Status in web server gui
        self.start_button = IconButton('gtk-media-play')
        self.start_button.connect('clicked', lambda o: self.start())
        self.stop_button = IconButton('gtk-media-stop')
        self.stop_button.connect('clicked', lambda o: self.stop())
        self.stop_button.set_sensitive(False)

        self.link_button = Gtk.LinkButton('')
        self.link_button.set_sensitive(False)

        self.notebookcombobox = NotebookComboBox(current=notebookinfo)
        self.open_button = IconButton('gtk-index')
        self.open_button.connect('clicked',
                                 lambda *a: NotebookDialog(self).run())

        self.portentry = Gtk.SpinButton()
        self.portentry.set_numeric(True)
        self.portentry.set_range(80, 10000)
        self.portentry.set_increments(1, 80)
        self.portentry.set_value(port)

        self.public_checkbox = Gtk.CheckButton.new_with_mnemonic(
            _('Allow public access'))
        # T: Checkbox in web server gui
        self.public_checkbox.set_active(public)

        self.templatecombobox = Gtk.ComboBoxText.new()
        template_names = [name for name, _ in list_templates('html')]
        for name in template_names:
            self.templatecombobox.append_text(name)
        self.templatecombobox.set_active(template_names.index('Default'))

        self.auth_checkbox = Gtk.CheckButton.new_with_mnemonic(
            _('Require authentication'))
        # T: checkbox in dialog for starting webserver
        self.username_input = InputEntry()
        self.password_input = InputEntry()
        self.password_input.set_visibility(False)

        # Build the interface
        vbox = Gtk.VBox()
        self.add(vbox)

        hbox = Gtk.HBox(spacing=12)
        hbox.pack_start(self.start_button, False, True, 0)
        hbox.pack_start(self.stop_button, False, True, 0)
        hbox.pack_start(self.status_label, False, True, 0)
        vbox.pack_start(hbox, False, False, 0)

        table = input_table_factory((
            (_('Notebook'), self.notebookcombobox, self.open_button),
            # T: Field in web server gui
            (_('Port'), self.portentry),
            # T: Field in web server gui for HTTP port (e.g. port 80)
            (_('Template'), self.templatecombobox),
            # T: Field in web server gui for webpage template
            self.public_checkbox,
            self.auth_checkbox,
            (_('Username'), self.username_input),
            # T: Field in web server gui
            (_('Password'), self.password_input)
            # T: Field in web server gui
        ))
        vbox.pack_start(table, False, False, 0)

        if self.link_button:
            hbox = Gtk.HBox()
            hbox.pack_end(self.link_button, False, True, 0)
            vbox.pack_start(hbox, False, False, 0)
예제 #12
0
class ServerWindow(Gtk.Window):
    def __init__(self, notebookinfo=None, port=8080, public=True, **opts):
        '''Constructor
		@param notebookinfo: the notebook location
		@param port: the http port to serve on
		@param public: allow connections to the server from other
		computers - if C{False} can only connect from localhost
		@param opts: options for L{WWWInterface.__init__()}
		'''
        GObject.GObject.__init__(self)
        self.set_title('Zim - ' + _('Web Server'))  # T: Window title
        self.set_border_width(10)
        self.interface_opts = opts
        self.httpd = None
        self._source_id = None

        # Widgets
        self.status_label = Gtk.Label()
        self.status_label.set_markup('<i>' + _('Server not started') + '</i>')
        # T: Status in web server gui
        self.start_button = IconButton('gtk-media-play')
        self.start_button.connect('clicked', lambda o: self.start())
        self.stop_button = IconButton('gtk-media-stop')
        self.stop_button.connect('clicked', lambda o: self.stop())
        self.stop_button.set_sensitive(False)

        self.link_button = Gtk.LinkButton('')
        self.link_button.set_sensitive(False)

        self.notebookcombobox = NotebookComboBox(current=notebookinfo)
        self.open_button = IconButton('gtk-index')
        self.open_button.connect('clicked',
                                 lambda *a: NotebookDialog(self).run())

        self.portentry = Gtk.SpinButton()
        self.portentry.set_numeric(True)
        self.portentry.set_range(80, 10000)
        self.portentry.set_increments(1, 80)
        self.portentry.set_value(port)

        self.public_checkbox = Gtk.CheckButton.new_with_mnemonic(
            _('Allow public access'))
        # T: Checkbox in web server gui
        self.public_checkbox.set_active(public)

        self.templatecombobox = Gtk.ComboBoxText.new()
        template_names = [name for name, _ in list_templates('html')]
        for name in template_names:
            self.templatecombobox.append_text(name)
        self.templatecombobox.set_active(template_names.index('Default'))

        self.auth_checkbox = Gtk.CheckButton.new_with_mnemonic(
            _('Require authentication'))
        # T: checkbox in dialog for starting webserver
        self.username_input = InputEntry()
        self.password_input = InputEntry()
        self.password_input.set_visibility(False)

        # Build the interface
        vbox = Gtk.VBox()
        self.add(vbox)

        hbox = Gtk.HBox(spacing=12)
        hbox.pack_start(self.start_button, False, True, 0)
        hbox.pack_start(self.stop_button, False, True, 0)
        hbox.pack_start(self.status_label, False, True, 0)
        vbox.pack_start(hbox, False, False, 0)

        table = input_table_factory((
            (_('Notebook'), self.notebookcombobox, self.open_button),
            # T: Field in web server gui
            (_('Port'), self.portentry),
            # T: Field in web server gui for HTTP port (e.g. port 80)
            (_('Template'), self.templatecombobox),
            # T: Field in web server gui for webpage template
            self.public_checkbox,
            self.auth_checkbox,
            (_('Username'), self.username_input),
            # T: Field in web server gui
            (_('Password'), self.password_input)
            # T: Field in web server gui
        ))
        vbox.pack_start(table, False, False, 0)

        if self.link_button:
            hbox = Gtk.HBox()
            hbox.pack_end(self.link_button, False, True, 0)
            vbox.pack_start(hbox, False, False, 0)

    def open_notebook(self, notebook):
        '''Sets the notebook in the combobox

		This method is called by the NotebookDialog when a notebook is opened.
		'''
        self.notebookcombobox.set_notebook(notebook)

    def start(self):
        # Start server
        try:
            uri = self.notebookcombobox.get_notebook()
            if uri:
                notebook, x = build_notebook(NotebookInfo(uri))
                if not notebook:
                    return
            else:
                return

            if not notebook.index.is_uptodate:
                for info in notebook.index.update_iter():
                    #logger.info('Indexing %s', info)
                    pass  # TODO meaningful info for above message

            port = int(self.portentry.get_value())
            public = self.public_checkbox.get_active()
            self.interface_opts[
                'template'] = self.templatecombobox.get_active_text()

            require_auth = self.auth_checkbox.get_active()
            auth_creds = None
            if require_auth:
                auth_creds = (self.username_input.get_text(),
                              self.password_input.get_text())
            self.httpd = make_server(notebook,
                                     port,
                                     public,
                                     auth_creds=auth_creds,
                                     **self.interface_opts)

            if sys.platform == 'win32':
                # GObject io watch conflicts with socket use on windows..
                # idle handler uses a bit to much CPU for my taste,
                # timeout every 0.5 sec is better
                self.httpd.timeout = 0.1  # 100 ms
                self._source_id = GObject.timeout_add(500,
                                                      self.do_serve_on_poll)
            else:
                self.httpd.timeout = 3  # if no response after 3 sec, drop it
                self._source_id = GObject.io_add_watch(
                    self.httpd.fileno(),
                    GObject.IO_IN | GObject.IO_OUT | GObject.IO_ERR
                    | GObject.IO_HUP | GObject.IO_PRI,  # any event..
                    self.do_serve_on_io)
            logger.info("Serving HTTP on %s port %i...",
                        self.httpd.server_name, self.httpd.server_port)
        except Exception as error:
            ErrorDialog(self, error).run()
            return

        # Update UI
        self.notebookcombobox.set_sensitive(False)
        self.portentry.set_sensitive(False)
        self.public_checkbox.set_sensitive(False)
        self.templatecombobox.set_sensitive(False)
        self.open_button.set_sensitive(False)
        self.start_button.set_sensitive(False)
        self.stop_button.set_sensitive(True)
        self.auth_checkbox.set_sensitive(False)
        self.username_input.set_sensitive(False)
        self.password_input.set_sensitive(False)

        self.status_label.set_markup('<i>' + _('Server started') + '</i>')
        # T: Status in web server gui
        #if self.public_checkbox.get_active():
        #	url = 'http://%s:%i' % (self.httpd.server_name, self.httpd.server_port)
        #else:
        #	url = 'http://localhost:%i' % self.httpd.server_port
        url = 'http://localhost:%i' % self.httpd.server_port
        if self.link_button:
            self.link_button.set_uri(url)
            self.link_button.set_label(url)
            self.link_button.set_sensitive(True)

    def do_serve_on_io(self, fd, event):
        try:
            if event & GObject.IO_HUP:
                self.stop()
                raise Exception('Socket disconnected')
            else:
                self.httpd.handle_request()
        except:
            logger.exception('Exception while handling IO request:')

        return True  # keep event running

    def do_serve_on_poll(self):
        self.httpd.handle_request()
        return True  # keep event running

    def stop(self):
        # Stop server
        logger.debug('Stop server')
        if self._source_id is not None:
            GObject.source_remove(self._source_id)
            self._source_id = None

        if self.httpd:
            self.httpd.socket.close()
            # There is also a httpd.server_close(), but undocumented (!?)
            self.httpd = None

        # Update UI
        self.status_label.set_markup('<i>' + _('Server stopped') + '</i>')
        # T: Status in web server gui
        if self.link_button:
            self.link_button.set_sensitive(False)
        self.notebookcombobox.set_sensitive(True)
        self.portentry.set_sensitive(True)
        self.public_checkbox.set_sensitive(True)
        self.templatecombobox.set_sensitive(True)
        self.open_button.set_sensitive(True)
        self.stop_button.set_sensitive(False)
        self.start_button.set_sensitive(True)
        self.auth_checkbox.set_sensitive(True)
        self.username_input.set_sensitive(True)
        self.password_input.set_sensitive(True)
예제 #13
0
파일: quicknote.py 프로젝트: thejeshgn/Zim
class QuickNoteDialog(BoundQuickNoteDialog):
	'''Dialog which includes a notebook chooser'''

	def __init__(self, ui, notebook=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None):
		self.config = get_config('quicknote.conf')
		self.uistate = self.config['QuickNoteDialog']

		Dialog.__init__(self, ui, _('Quick Note'))
		self._updating_title = False
		self._title_set_manually = not basename is None
		self.attachments = attachments

		if notebook and not isinstance(notebook, basestring):
			notebook = notebook.uri

		self.uistate.setdefault('lastnotebook', None, basestring)
		if self.uistate['lastnotebook']:
			notebook = notebook or self.uistate['lastnotebook']
			self.config['Namespaces'].setdefault(notebook, None, basestring)
			namespace = namespace or self.config['Namespaces'][notebook]

		self.form = InputForm()
		self.vbox.pack_start(self.form, False)

		# TODO dropdown could use an option "Other..."
		label = gtk.Label(_('Notebook')+': ')
		label.set_alignment(0.0, 0.5)
		self.form.attach(label, 0,1, 0,1, xoptions=gtk.FILL)
			# T: Field to select Notebook from drop down list
		self.notebookcombobox = NotebookComboBox(current=notebook)
		self.notebookcombobox.connect('changed', self.on_notebook_changed)
		self.form.attach(self.notebookcombobox, 1,2, 0,1)

		self._init_inputs(namespace, basename, append, text, template_options)

		self.uistate['lastnotebook'] = notebook
		self._set_autocomplete(notebook)

	def save_uistate(self):
		notebook = self.notebookcombobox.get_notebook()
		self.uistate['lastnotebook'] = notebook
		self.uistate['new_page'] = self.form['new_page']
		self.uistate['open_page'] = self.open_page.get_active()
		if notebook is not None:
			if self.uistate['new_page']:
				self.config['Namespaces'][notebook] = self.form['namespace']
			else:
				self.config['Namespaces'][notebook] = self.form['page']
		self.config.write()

	def on_notebook_changed(self, o):
		notebook = self.notebookcombobox.get_notebook()
		if not notebook or notebook == self.uistate['lastnotebook']:
			return

		self.uistate['lastnotebook'] = notebook
		self.config['Namespaces'].setdefault(notebook, None, basestring)
		namespace = self.config['Namespaces'][notebook]
		if namespace:
			self.form['namespace'] = namespace

		self._set_autocomplete(notebook)

	def _set_autocomplete(self, notebook):
		if notebook:
			obj = get_notebook(notebook)
			self.form.widgets['namespace'].notebook = obj
			self.form.widgets['page'].notebook = obj
			# Could still be None, e.g. if the notebook folder is not mounted
			logger.debug('Notebook for autocomplete: %s (%s)', obj, notebook)
		else:
			self.form.widgets['namespace'].notebook = None
			self.form.widgets['page'].notebook = None
			logger.debug('Notebook for autocomplete unset')

	def do_response_ok(self):
		def get_ui():
			start_server_if_not_running()
			notebook = self.notebookcombobox.get_notebook()
			if notebook:
				return ServerProxy().get_notebook(notebook)
			else:
				return None

		return BoundQuickNoteDialog.do_response_ok(self, get_ui)