Beispiel #1
0
    def subscribe(self, pagename):
        """ Subscribe to a wiki page.

        To enable shared farm users, if the wiki has an interwiki name,
        page names are saved as interwiki names.

        @param pagename: name of the page to subscribe
        @type pagename: unicode
        @rtype: bool
        @return: if page was subscribed
        """
        if self._cfg.interwikiname:
            pagename = self._interWikiName(pagename)

        if pagename not in self.subscribed_pages:
            self.subscribed_pages.append(pagename)
            self.save()

            # Send a notification
            from MoinMoin.events import SubscribedToPageEvent, send_event
            e = SubscribedToPageEvent(self._request, pagename, self.name)
            send_event(e)
            return True

        return False
Beispiel #2
0
def add_attachment(request, pagename, target, filecontent, overwrite=0):
    """ save <filecontent> to an attachment <target> of page <pagename>

        filecontent can be either a str (in memory file content),
        or an open file object (file content in e.g. a tempfile).
    """
    # replace illegal chars
    target = wikiutil.taintfilename(target)

    # get directory, and possibly create it
    attach_dir = getAttachDir(request, pagename, create=1)
    fpath = os.path.join(attach_dir, target).encode(config.charset)

    exists = os.path.exists(fpath)
    if exists:
        if overwrite:
            remove_attachment(request, pagename, target)
        else:
            raise AttachmentAlreadyExists

    # save file
    stream = open(fpath, 'wb')
    try:
        _write_stream(filecontent, stream)
    finally:
        stream.close()

    _addLogEntry(request, 'ATTNEW', pagename, target)

    filesize = os.path.getsize(fpath)
    event = FileAttachedEvent(request, pagename, target, filesize)
    send_event(event)

    return target, filesize
Beispiel #3
0
    def subscribe(self, pagename):
        """ Subscribe to a wiki page.

        To enable shared farm users, if the wiki has an interwiki name,
        page names are saved as interwiki names.

        @param pagename: name of the page to subscribe
        @type pagename: unicode
        @rtype: bool
        @return: if page was subscribed
        """
        if self._cfg.interwikiname:
            pagename = self._interWikiName(pagename)

        if pagename not in self.subscribed_pages:
            self.subscribed_pages.append(pagename)
            self.save()

            # Send a notification
            from MoinMoin.events import SubscribedToPageEvent, send_event
            e = SubscribedToPageEvent(self._request, pagename, self.name)
            send_event(e)
            return True

        return False
Beispiel #4
0
def add_attachment(request, pagename, target, filecontent, overwrite=0):
    """ save <filecontent> to an attachment <target> of page <pagename>

        filecontent can be either a str (in memory file content),
        or an open file object (file content in e.g. a tempfile).
    """
    # replace illegal chars
    target = wikiutil.taintfilename(target)

    # get directory, and possibly create it
    attach_dir = getAttachDir(request, pagename, create=1)
    fpath = os.path.join(attach_dir, target).encode(config.charset)

    exists = os.path.exists(fpath)
    if exists:
        if overwrite:
            remove_attachment(request, pagename, target)
        else:
            raise AttachmentAlreadyExists

    # save file
    stream = open(fpath, 'wb')
    try:
        _write_stream(filecontent, stream)
    finally:
        stream.close()

    _addLogEntry(request, 'ATTNEW', pagename, target)

    filesize = os.path.getsize(fpath)
    event = FileAttachedEvent(request, pagename, target, filesize)
    send_event(event)

    return target, filesize
Beispiel #5
0
    def save(self):
        """ Save user account data to user account file on disk.

        This saves all member variables, except "id" and "valid" and
        those starting with an underscore.
        """
        if not self.id:
            return

        user_dir = self._cfg.user_dir
        if not os.path.exists(user_dir):
            os.makedirs(user_dir)

        self.last_saved = str(time.time())

        # !!! should write to a temp file here to avoid race conditions,
        # or even better, use locking

        data = codecs.open(self.__filename(), "w", config.charset)
        data.write("# Data saved '%s' for id '%s'\n" % (
            time.strftime(self._cfg.datetime_fmt, time.localtime(time.time())),
            self.id))
        attrs = self.persistent_items()
        attrs.sort()
        for key, value in attrs:
            # Encode list values
            if isinstance(value, list):
                key += '[]'
                value = encodeList(value)
            # Encode dict values
            elif isinstance(value, dict):
                key += '{}'
                value = encodeDict(value)
            line = u"%s=%s" % (key, unicode(value))
            line = line.replace('\n', ' ').replace('\r', ' ') # no lineseps
            data.write(line + '\n')
        data.close()

        arena = 'user'
        key = 'name2id'
        caching.CacheEntry(self._request, arena, key, scope='wiki').remove()
        try:
            del self._request.cfg.cache.name2id
        except:
            pass
        key = 'openid2id'
        caching.CacheEntry(self._request, arena, key, scope='wiki').remove()
        try:
            del self._request.cfg.cache.openid2id
        except:
            pass

        if not self.disabled:
            self.valid = 1

        if not self._stored:
            self._stored = True
            event = events.UserCreatedEvent(self._request, self)
            events.send_event(event)
Beispiel #6
0
    def save(self):
        """ Save user account data to user account file on disk.

        This saves all member variables, except "id" and "valid" and
        those starting with an underscore.
        """
        if not self.id:
            return

        user_dir = self._cfg.user_dir
        if not os.path.exists(user_dir):
            os.makedirs(user_dir)

        self.last_saved = str(time.time())

        # !!! should write to a temp file here to avoid race conditions,
        # or even better, use locking

        data = codecs.open(self.__filename(), "w", config.charset)
        data.write("# Data saved '%s' for id '%s'\n" % (time.strftime(
            self._cfg.datetime_fmt, time.localtime(time.time())), self.id))
        attrs = self.persistent_items()
        attrs.sort()
        for key, value in attrs:
            # Encode list values
            if isinstance(value, list):
                key += '[]'
                value = encodeList(value)
            # Encode dict values
            elif isinstance(value, dict):
                key += '{}'
                value = encodeDict(value)
            line = u"%s=%s" % (key, unicode(value))
            line = line.replace('\n', ' ').replace('\r', ' ')  # no lineseps
            data.write(line + '\n')
        data.close()

        arena = 'user'
        key = 'name2id'
        caching.CacheEntry(self._request, arena, key, scope='wiki').remove()
        try:
            del self._request.cfg.cache.name2id
        except:
            pass
        key = 'openid2id'
        caching.CacheEntry(self._request, arena, key, scope='wiki').remove()
        try:
            del self._request.cfg.cache.openid2id
        except:
            pass

        if not self.disabled:
            self.valid = 1

        if not self._stored:
            self._stored = True
            event = events.UserCreatedEvent(self._request, self)
            events.send_event(event)
Beispiel #7
0
def move_file(request, pagename, new_pagename, attachment, new_attachment):
    _ = request.getText

    newpage = Page(request, new_pagename)
    if newpage.exists(includeDeleted=1) and request.user.may.write(
            new_pagename) and request.user.may.delete(pagename):
        new_attachment_path = os.path.join(
            getAttachDir(request, new_pagename, create=1),
            new_attachment).encode(config.charset)
        attachment_path = os.path.join(getAttachDir(request, pagename),
                                       attachment).encode(config.charset)

        if os.path.exists(new_attachment_path):
            upload_form(
                pagename,
                request,
                msg=
                _("Attachment '%(new_pagename)s/%(new_filename)s' already exists."
                  ) % {
                      'new_pagename': new_pagename,
                      'new_filename': new_attachment
                  })
            return

        if new_attachment_path != attachment_path:
            filesize = os.path.getsize(attachment_path)
            filesys.rename(attachment_path, new_attachment_path)
            _addLogEntry(request, 'ATTDEL', pagename, attachment)
            event = FileRemovedEvent(request, pagename, attachment, filesize)
            send_event(event)
            _addLogEntry(request, 'ATTNEW', new_pagename, new_attachment)
            event = FileAttachedEvent(request, new_pagename, new_attachment,
                                      filesize)
            send_event(event)
            upload_form(
                pagename,
                request,
                msg=
                _("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'."
                  ) % {
                      'pagename': pagename,
                      'filename': attachment,
                      'new_pagename': new_pagename,
                      'new_filename': new_attachment
                  })
        else:
            upload_form(pagename, request, msg=_("Nothing changed"))
    else:
        upload_form(
            pagename,
            request,
            msg=
            _("Page '%(new_pagename)s' does not exist or you don't have enough rights."
              ) % {'new_pagename': new_pagename})
Beispiel #8
0
def move_file(request, pagename, new_pagename, attachment, new_attachment):
    """
    move a file attachment from pagename:attachment to new_pagename:new_attachment

    @param pagename: original pagename
    @param new_pagename: new pagename (may be same as original pagename)
    @param attachment: original attachment filename
                       note: attachment filename must not contain a path,
                             use wikiutil.taintfilename() before calling move_file
    @param new_attachment: new attachment filename (may be same as original filename)
                       note: attachment filename must not contain a path,
                             use wikiutil.taintfilename() before calling move_file
    """
    _ = request.getText

    newpage = Page(request, new_pagename)
    if newpage.exists(includeDeleted=1) and request.user.may.write(new_pagename) and request.user.may.delete(pagename):
        new_attachment_path = os.path.join(getAttachDir(request, new_pagename,
                              create=1), new_attachment).encode(config.charset)
        attachment_path = os.path.join(getAttachDir(request, pagename),
                          attachment).encode(config.charset)

        if os.path.exists(new_attachment_path):
            upload_form(pagename, request,
                msg=_("Attachment '%(new_pagename)s/%(new_filename)s' already exists.") % {
                    'new_pagename': new_pagename,
                    'new_filename': new_attachment})
            return

        if new_attachment_path != attachment_path:
            filesize = os.path.getsize(attachment_path)
            filesys.rename(attachment_path, new_attachment_path)
            _addLogEntry(request, 'ATTDEL', pagename, attachment)
            event = FileRemovedEvent(request, pagename, attachment, filesize)
            send_event(event)
            _addLogEntry(request, 'ATTNEW', new_pagename, new_attachment)
            event = FileAttachedEvent(request, new_pagename, new_attachment, filesize)
            send_event(event)
            upload_form(pagename, request,
                        msg=_("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'.") % {
                            'pagename': pagename,
                            'filename': attachment,
                            'new_pagename': new_pagename,
                            'new_filename': new_attachment})
        else:
            upload_form(pagename, request, msg=_("Nothing changed"))
    else:
        upload_form(pagename, request, msg=_("Page '%(new_pagename)s' does not exist or you don't have enough rights.") % {
            'new_pagename': new_pagename})
Beispiel #9
0
def remove_attachment(request, pagename, target):
    """ remove attachment <target> of page <pagename>
    """
    # replace illegal chars
    target = wikiutil.taintfilename(target)

    # get directory, do not create it
    attach_dir = getAttachDir(request, pagename, create=0)
    # remove file
    fpath = os.path.join(attach_dir, target).encode(config.charset)
    try:
        filesize = os.path.getsize(fpath)
        os.remove(fpath)
    except:
        # either it is gone already or we have no rights - not much we can do about it
        filesize = 0
    else:
        _addLogEntry(request, 'ATTDEL', pagename, target)

        event = FileRemovedEvent(request, pagename, target, filesize)
        send_event(event)

    return target, filesize
Beispiel #10
0
def remove_attachment(request, pagename, target):
    """ remove attachment <target> of page <pagename>
    """
    # replace illegal chars
    target = wikiutil.taintfilename(target)

    # get directory, do not create it
    attach_dir = getAttachDir(request, pagename, create=0)
    # remove file
    fpath = os.path.join(attach_dir, target).encode(config.charset)
    try:
        filesize = os.path.getsize(fpath)
        os.remove(fpath)
    except:
        # either it is gone already or we have no rights - not much we can do about it
        filesize = 0
    else:
        _addLogEntry(request, 'ATTDEL', pagename, target)

        event = FileRemovedEvent(request, pagename, target, filesize)
        send_event(event)

    return target, filesize
Beispiel #11
0
def move_file(request, pagename, new_pagename, attachment, new_attachment):
    _ = request.getText

    newpage = Page(request, new_pagename)
    if newpage.exists(includeDeleted=1) and request.user.may.write(new_pagename) and request.user.may.delete(pagename):
        new_attachment_path = os.path.join(getAttachDir(request, new_pagename,
                              create=1), new_attachment).encode(config.charset)
        attachment_path = os.path.join(getAttachDir(request, pagename),
                          attachment).encode(config.charset)

        if os.path.exists(new_attachment_path):
            upload_form(pagename, request,
                msg=_("Attachment '%(new_pagename)s/%(new_filename)s' already exists.") % {
                    'new_pagename': new_pagename,
                    'new_filename': new_attachment})
            return

        if new_attachment_path != attachment_path:
            filesize = os.path.getsize(attachment_path)
            filesys.rename(attachment_path, new_attachment_path)
            _addLogEntry(request, 'ATTDEL', pagename, attachment)
            event = FileRemovedEvent(request, pagename, attachment, filesize)
            send_event(event)
            _addLogEntry(request, 'ATTNEW', new_pagename, new_attachment)
            event = FileAttachedEvent(request, new_pagename, new_attachment, filesize)
            send_event(event)
            upload_form(pagename, request,
                        msg=_("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'.") % {
                            'pagename': pagename,
                            'filename': attachment,
                            'new_pagename': new_pagename,
                            'new_filename': new_attachment})
        else:
            upload_form(pagename, request, msg=_("Nothing changed"))
    else:
        upload_form(pagename, request, msg=_("Page '%(new_pagename)s' does not exist or you don't have enough rights.") % {
            'new_pagename': new_pagename})
Beispiel #12
0
def test_send_event(request):
    """Test if event handlers are called and if proper messages are returned"""

    py.test.skip('broken test - global state is changed somehow that test_GetVal looks broken')
    return_string = u"test_send_event"

    def event_handler(event):
        return notification.Failure("Just a test")

    request.cfg.event_handlers = [event_handler]
    event = events.Event(request)

    print "A proper event handler must be called and an 1-element list of results returned"
    results = events.send_event(event)
    assert issubclass(results[0].__class__, events.EventResult)
Beispiel #13
0
def test_send_event(request):
    """Test if event handlers are called and if proper messages are returned"""

    py.test.skip(
        'broken test - global state is changed somehow that test_GetVal looks broken'
    )
    return_string = u"test_send_event"

    def event_handler(event):
        return notification.Failure("Just a test")

    request.cfg.event_handlers = [event_handler]
    event = events.Event(request)

    print "A proper event handler must be called and an 1-element list of results returned"
    results = events.send_event(event)
    assert issubclass(results[0].__class__, events.EventResult)
Beispiel #14
0
    def _save_user_prefs(self):
        _ = self._
        form = self.request.form
        request = self.request

        if request.request_method != 'POST':
            return

        if not 'name' in request.user.auth_attribs:
            # Require non-empty name
            new_name = form.get('name', [request.user.name])[0]

            # Don't allow changing the name to an invalid one
            if not user.isValidName(request, new_name):
                return 'error', _("""Invalid user name {{{'%s'}}}.
Name may contain any Unicode alpha numeric character, with optional one
space between words. Group page name is not allowed.""", wiki=True) % wikiutil.escape(new_name)

            # Is this an existing user trying to change information or a new user?
            # Name required to be unique. Check if name belong to another user.
            existing_id = user.getUserId(request, new_name)
            if existing_id is not None and existing_id != request.user.id:
                return 'error', _("This user name already belongs to somebody else.")

            if not new_name:
                return 'error', _("Empty user name. Please enter a user name.")

            # done sanity checking the name, set it
            request.user.name = new_name


        if not 'email' in request.user.auth_attribs:
            # try to get the email
            new_email = wikiutil.clean_input(form.get('email', [request.user.email])[0])
            new_email = new_email.strip()

            # Require email
            if not new_email and 'email' not in request.cfg.user_form_remove:
                return 'error', _("Please provide your email address. If you lose your"
                                  " login information, you can get it by email.")

            # Email should be unique - see also MoinMoin/script/accounts/moin_usercheck.py
            if new_email and request.cfg.user_email_unique:
                other = user.get_by_email_address(request, new_email)
                if other is not None and other.id != request.user.id:
                    return 'error', _("This email already belongs to somebody else.")

            # done checking the email, set it
            request.user.email = new_email


        if not 'jid' in request.user.auth_attribs:
            # try to get the jid
            new_jid = wikiutil.clean_input(form.get('jid', [''])[0]).strip()

            jid_changed = request.user.jid != new_jid
            previous_jid = request.user.jid

            if new_jid and request.cfg.user_jid_unique:
                other = user.get_by_jabber_id(request, new_jid)
                if other is not None and other.id != request.user.id:
                    return 'error', _("This jabber id already belongs to somebody else.")

            if jid_changed:
                set_event = events.JabberIDSetEvent(request, new_jid)
                unset_event = events.JabberIDUnsetEvent(request, previous_jid)
                events.send_event(unset_event)
                events.send_event(set_event)

            # done checking the JID, set it
            request.user.jid = new_jid


        if not 'aliasname' in request.user.auth_attribs:
            # aliasname
            request.user.aliasname = wikiutil.clean_input(form.get('aliasname', [''])[0])

        # editor size
        request.user.edit_rows = util.web.getIntegerInput(request, 'edit_rows',
                                                          request.user.edit_rows, 10, 60)

        # try to get the editor
        request.user.editor_default = form.get('editor_default', [self.cfg.editor_default])[0]
        request.user.editor_ui = form.get('editor_ui', [self.cfg.editor_ui])[0]

        # time zone
        request.user.tz_offset = util.web.getIntegerInput(request, 'tz_offset',
                                                          request.user.tz_offset, -84600, 84600)

        # datetime format
        try:
            dt_d_combined = Settings._date_formats.get(form['datetime_fmt'][0], '')
            request.user.datetime_fmt, request.user.date_fmt = dt_d_combined.split(' & ')
        except (KeyError, ValueError):
            request.user.datetime_fmt = '' # default
            request.user.date_fmt = '' # default

        # try to get the (optional) theme
        theme_name = form.get('theme_name', [self.cfg.theme_default])[0]
        if theme_name != request.user.theme_name:
            # if the theme has changed, load the new theme
            # so the user has a direct feedback
            # WARNING: this should be refactored (i.e. theme load
            # after userform handling), cause currently the
            # already loaded theme is just replaced (works cause
            # nothing has been emitted yet)
            request.user.theme_name = theme_name
            if request.loadTheme(theme_name) > 0:
                theme_name = wikiutil.escape(theme_name)
                return 'error', _("The theme '%(theme_name)s' could not be loaded!") % locals()

        # try to get the (optional) preferred language
        request.user.language = form.get('language', [''])[0]
        if request.user.language == u'': # For language-statistics
            from MoinMoin import i18n
            request.user.real_language = i18n.get_browser_language(request)
        else:
            request.user.real_language = ''

        # I want to handle all inputs from user_form_fields, but
        # don't want to handle the cases that have already been coded
        # above.
        # This is a horribly fragile kludge that's begging to break.
        # Something that might work better would be to define a
        # handler for each form field, instead of stuffing them all in
        # one long and inextensible method.  That would allow for
        # plugins to provide methods to validate their fields as well.
        already_handled = ['name', 'email',
                           'aliasname', 'edit_rows', 'editor_default',
                           'editor_ui', 'tz_offset', 'datetime_fmt',
                           'theme_name', 'language', 'real_language', 'jid']
        for field in self.cfg.user_form_fields:
            key = field[0]
            if ((key in self.cfg.user_form_disable)
                or (key in already_handled)):
                continue
            default = self.cfg.user_form_defaults[key]
            value = form.get(key, [default])[0]
            setattr(request.user, key, value)

        # checkbox options
        for key, label in self.cfg.user_checkbox_fields:
            if key not in self.cfg.user_checkbox_disable and key not in self.cfg.user_checkbox_remove:
                value = form.get(key, ["0"])[0]
                try:
                    value = int(value)
                except ValueError:
                    pass
                else:
                    setattr(request.user, key, value)

        # quicklinks for navibar
        request.user.quicklinks = self._decode_pagelist('quicklinks')

        # save data
        request.user.save()
        if request.user.disabled:
            # set valid to false so the current request won't
            # show the user as logged-in any more
            request.user.valid = False

        result = _("User preferences saved!")
        if _debug:
            result = result + util.dumpFormData(form)
        return result
Beispiel #15
0
    def _save_user_prefs(self):
        _ = self._
        form = self.request.form
        request = self.request

        if not 'name' in request.user.auth_attribs:
            # Require non-empty name
            new_name = wikiutil.clean_input(form.get('name', request.user.name)).strip()

            # Don't allow changing the name to an invalid one
            if not user.isValidName(request, new_name):
                return 'error', _("""Invalid user name {{{'%s'}}}.
Name may contain any Unicode alpha numeric character, with optional one
space between words. Group page name is not allowed.""", wiki=True) % wikiutil.escape(new_name)

            # Is this an existing user trying to change information or a new user?
            # Name required to be unique. Check if name belong to another user.
            existing_id = user.getUserId(request, new_name)
            if existing_id is not None and existing_id != request.user.id:
                return 'error', _("This user name already belongs to somebody else.")

            if not new_name:
                return 'error', _("Empty user name. Please enter a user name.")

            # done sanity checking the name, set it
            request.user.name = new_name


        if not 'email' in request.user.auth_attribs:
            # try to get the email
            new_email = wikiutil.clean_input(form.get('email', request.user.email)).strip()

            # Require email
            if not new_email and 'email' not in request.cfg.user_form_remove:
                return 'error', _("Please provide your email address. If you lose your"
                                  " login information, you can get it by email.")

            # Email should be unique - see also MoinMoin/script/accounts/moin_usercheck.py
            if new_email and request.cfg.user_email_unique:
                other = user.get_by_email_address(request, new_email)
                if other is not None and other.id != request.user.id:
                    return 'error', _("This email already belongs to somebody else.")

            # done checking the email, set it
            request.user.email = new_email


        if not 'jid' in request.user.auth_attribs:
            # try to get the jid
            new_jid = wikiutil.clean_input(form.get('jid', '')).strip()

            jid_changed = request.user.jid != new_jid
            previous_jid = request.user.jid

            if new_jid and request.cfg.user_jid_unique:
                other = user.get_by_jabber_id(request, new_jid)
                if other is not None and other.id != request.user.id:
                    return 'error', _("This jabber id already belongs to somebody else.")

            if jid_changed:
                set_event = events.JabberIDSetEvent(request, new_jid)
                unset_event = events.JabberIDUnsetEvent(request, previous_jid)
                events.send_event(unset_event)
                events.send_event(set_event)

            # done checking the JID, set it
            request.user.jid = new_jid


        if not 'aliasname' in request.user.auth_attribs:
            # aliasname
            request.user.aliasname = wikiutil.clean_input(form.get('aliasname', '')).strip()

        # editor size
        request.user.edit_rows = util.web.getIntegerInput(request, 'edit_rows',
                                                          request.user.edit_rows, 0, 999)

        # try to get the editor
        request.user.editor_default = wikiutil.clean_input(form.get('editor_default', self.cfg.editor_default))
        request.user.editor_ui = wikiutil.clean_input(form.get('editor_ui', self.cfg.editor_ui))

        # time zone
        request.user.tz_offset = util.web.getIntegerInput(request, 'tz_offset',
                                                          request.user.tz_offset, -84600, 84600)

        # datetime format
        try:
            dt_d_combined = Settings._date_formats.get(form['datetime_fmt'], '')
            request.user.datetime_fmt, request.user.date_fmt = dt_d_combined.split(' & ')
        except (KeyError, ValueError):
            request.user.datetime_fmt = '' # default
            request.user.date_fmt = '' # default

        # try to get the (optional) theme
        theme_name = wikiutil.clean_input(form.get('theme_name', self.cfg.theme_default))
        if theme_name != request.user.theme_name:
            # if the theme has changed, load the new theme
            # so the user has a direct feedback
            # WARNING: this should be refactored (i.e. theme load
            # after userform handling), cause currently the
            # already loaded theme is just replaced (works cause
            # nothing has been emitted yet)
            request.user.theme_name = theme_name
            if load_theme_fallback(request, theme_name) > 0:
                theme_name = wikiutil.escape(theme_name)
                return 'error', _("The theme '%(theme_name)s' could not be loaded!") % locals()

        # try to get the (optional) preferred language
        request.user.language = wikiutil.clean_input(form.get('language', ''))
        if request.user.language == u'': # For language-statistics
            from MoinMoin import i18n
            request.user.real_language = i18n.get_browser_language(request)
        else:
            request.user.real_language = ''

        # I want to handle all inputs from user_form_fields, but
        # don't want to handle the cases that have already been coded
        # above.
        # This is a horribly fragile kludge that's begging to break.
        # Something that might work better would be to define a
        # handler for each form field, instead of stuffing them all in
        # one long and inextensible method.  That would allow for
        # plugins to provide methods to validate their fields as well.
        already_handled = ['name', 'email',
                           'aliasname', 'edit_rows', 'editor_default',
                           'editor_ui', 'tz_offset', 'datetime_fmt',
                           'theme_name', 'language', 'real_language', 'jid']
        for field in self.cfg.user_form_fields:
            key = field[0]
            if ((key in self.cfg.user_form_disable)
                or (key in already_handled)):
                continue
            default = self.cfg.user_form_defaults[key]
            value = form.get(key, default)
            value = wikiutil.clean_input(value)
            setattr(request.user, key, value)

        # checkbox options
        for key, label in self.cfg.user_checkbox_fields:
            if key not in self.cfg.user_checkbox_disable and key not in self.cfg.user_checkbox_remove:
                value = form.get(key, "0")
                try:
                    value = int(value)
                except ValueError:
                    # value we got is crap, do not setattr this value, just pass
                    pass
                else:
                    setattr(request.user, key, value)

        # quicklinks for navibar
        request.user.quicklinks = self._decode_pagelist('quicklinks')

        # save data
        request.user.save()
        if request.user.disabled:
            # set valid to false so the current request won't
            # show the user as logged-in any more
            request.user.valid = False

        result = _("User preferences saved!")
        return result
Beispiel #16
0
    def save(self):
        """ Save user account data to user account file on disk.

        This saves all member variables, except "id" and "valid" and
        those starting with an underscore.
        """
        if not self.id:
            return

        user_dir = self._cfg.user_dir
        if not os.path.exists(user_dir):
            os.makedirs(user_dir)

        self.last_saved = str(time.time())

        # !!! should write to a temp file here to avoid race conditions,
        # or even better, use locking

        temp = file(os.path.join(user_dir, 'temp-' + uuid.uuid4().get_hex()), 'w')
        try:
            data = codecs.getwriter(config.charset)(temp)
            data.write("# Data saved '%s' for id '%s'\n" % (
                time.strftime(self._cfg.datetime_fmt,
                              time.localtime(time.time())),
                self.id))
            attrs = self.persistent_items()
            attrs.sort()
            for key, value in attrs:
                # Encode list values
                if isinstance(value, list):
                    key += '[]'
                    value = encodeList(value)
                # Encode dict values
                elif isinstance(value, dict):
                    key += '{}'
                    value = encodeDict(value)
                line = u"%s=%s" % (key, unicode(value))
                line = line.replace('\n', ' ').replace('\r', ' ') # no lineseps
                data.write(line + '\n')

            # atomically put it in place (except on windows)
            filesys.rename(temp.name, self.__filename())
        except IOError as err:
            _ = self._request.getText
            # throw a nicer exception
            if err.errno == errno.ENOSPC:
                raise SaveError(
                    _("Cannot save user %s, no storage space left.") % 
                    self.name)
            else:
                raise SaveError(
                    _("An I/O error occurred while saving user %s (errno=%d)")\
                        % (self.name, err.errno))
        finally:
            try:
                os.remove(temp.name)
            except:
                pass # we don't care for errors in the os.remove
            finally:
                temp.close()

        if not self.disabled:
            self.valid = 1

        self.updateLookupCaches()

        if not self._stored:
            self._stored = True
            event = events.UserCreatedEvent(self._request, self)
            events.send_event(event)

        # update page subscriber's cache after saving user preferences
        self.updatePageSubCache()