示例#1
0
文件: forms.py 项目: mgc/reviewboard
class RepositoryForm(forms.ModelForm):
    """
    A specialized form for RepositoryAdmin that makes the "password"
    field use a PasswordInput widget.
    """

    # NOTE: The list of fields must match that of the corresponding
    #       bug tracker (not including the hosting_ and bug_tracker_
    #       prefixes), for hosting services matching bug trackers.
    HOSTING_SERVICE_INFO = SortedDict([
        ('bitbucket', {
            'label': _('Bitbucket'),
            'fields': ['hosting_project_name', 'hosting_owner'],
            'tools': {
                'Mercurial': {
                    'path': 'http://bitbucket.org/%(hosting_owner)s/'
                            '%(hosting_project_name)s/',
                    'mirror_path': 'ssh://[email protected]/'
                                   '%(hosting_owner)s/'
                                   '%(hosting_project_name)s/'
                },
            },
        }),
        ('github', {
            'label': _('GitHub'),
            'fields': ['hosting_project_name', 'hosting_owner'],
            'hidden_fields': ['raw_file_url'],
            'tools': {
                'Git': {
                    'path': 'git://github.com/%(hosting_owner)s/'
                            '%(hosting_project_name)s.git',
                    'mirror_path': '[email protected]:%(hosting_owner)s/'
                                   '%(hosting_project_name)s.git',
                    'raw_file_url': 'http://github.com/api/v2/yaml/blob/show/'
                                    '%(hosting_owner)s/'
                                    '%(hosting_project_name)s/'
                                    '<revision>'
                },
            },
        }),
        ('github-private', {
            'label': _('GitHub (Private)'),
            'fields': ['hosting_project_name', 'hosting_owner', 'api_token', 'username'],
            'hidden_fields': ['raw_file_url'],
            'tools': {
                'Git': {
                    'path': '[email protected]:%(hosting_owner)s/'
                            '%(hosting_project_name)s.git',
                    'mirror_path': '',
                    'raw_file_url': 'http://github.com/api/v2/yaml/blob/show/'
                                    '%(hosting_owner)s/'
                                    '%(hosting_project_name)s/'
                                    '<revision>'
                                    '?login=%(username)s'
                                    '&token=%(api_token)s'
                },
            },
        }),
        ('googlecode', {
            'label': _('Google Code'),
            'fields': ['hosting_project_name'],
            'tools': {
                'Mercurial': {
                    'path': 'http://%(hosting_project_name)s'
                            '.googlecode.com/hg',
                    'mirror_path': 'https://%(hosting_project_name)s'
                                   '.googlecode.com/hg',
                },
                'Subversion': {
                    'path': 'http://%(hosting_project_name)s'
                            '.googlecode.com/svn',
                    'mirror_path': 'https://%(hosting_project_name)s'
                                   '.googlecode.com/svn',
                },
            },
        }),
        ('sourceforge', {
            'label': _('SourceForge'),
            'fields': ['hosting_project_name'],
            'tools': {
                'Bazaar': {
                    'path': 'bzr://%(hosting_project_name)s'
                            '.bzr.sourceforge.net/bzrroot/'
                            '%(hosting_project_name)s',
                    'mirror_path': 'bzr+ssh://%(hosting_project_name)s'
                                   '.bzr.sourceforge.net/bzrroot/'
                                   '%(hosting_project_name)s',
                },
                'CVS': {
                    'path': ':pserver:anonymous@%(hosting_project_name)s'
                            '.cvs.sourceforge.net:/cvsroot/'
                            '%(hosting_project_name)s',
                    'mirror_path': '%(hosting_project_name)s'
                                   '.cvs.sourceforge.net/cvsroot/'
                                   '%(hosting_project_name)s',
                },
                'Mercurial': {
                    'path': 'http://%(hosting_project_name)s'
                            '.hg.sourceforge.net:8000/hgroot/'
                            '%(hosting_project_name)s',
                    'mirror_path': 'ssh://%(hosting_project_name)s'
                                   '.hg.sourceforge.net/hgroot/'
                                   '%(hosting_project_name)s',
                },
                'Subversion': {
                    'path': 'http://%(hosting_project_name)s'
                            '.svn.sourceforge.net/svnroot/'
                            '%(hosting_project_name)s',
                    'mirror_path': 'https://%(hosting_project_name)s'
                                   '.svn.sourceforge.net/svnroot/'
                                   '%(hosting_project_name)s',
                },
                # TODO: Support Git
            },
        }),
        ('custom', {
            'label': _('Custom'),
            'fields': ['path', 'mirror_path'],
        }),
    ])

    BUG_TRACKER_INFO = SortedDict([
        ('none', {
            'label': _('None'),
            'fields': [],
            'format': '',
        }),
        ('bitbucket', {
            'label': 'Bitbucket',
            'fields': ['bug_tracker_project_name', 'bug_tracker_owner'],
            'format': 'http://bitbucket.org/%(bug_tracker_owner)s/'
                      '%(bug_tracker_project_name)s/issue/%%s/',
        }),
        ('bugzilla', {
            'label': 'Bugzilla',
            'fields': ['bug_tracker_base_url'],
            'format': '%(bug_tracker_base_url)s/show_bug.cgi?id=%%s',
        }),
        ('github', {
            'label': 'GitHub',
            'fields': ['bug_tracker_project_name', 'bug_tracker_owner'],
            'format': 'http://github.com/%(bug_tracker_owner)s/'
                      '%(bug_tracker_project_name)s/issues#issue/%%s',
        }),
        ('github-private', {
            'label': 'GitHub (Private)',
            'fields': ['bug_tracker_project_name', 'bug_tracker_owner'],
            'format': 'http://github.com/%(bug_tracker_owner)s/'
                      '%(bug_tracker_project_name)s/issues#issue/%%s',
        }),
        ('googlecode', {
            'label': 'Google Code',
            'fields': ['bug_tracker_project_name'],
            'format': 'http://code.google.com/p/%(bug_tracker_project_name)s/'
                      'issues/detail?id=%%s',
        }),
        ('redmine', {
            'label': 'Redmine',
            'fields': ['bug_tracker_base_url'],
            'format': '%(bug_tracker_base_url)s/issues/%%s',
        }),
        ('sourceforge', {
            'label': 'SourceForge',
            'fields': [],
            'format': 'http://sourceforge.net/support/tracker.php?aid=%%s',
        }),
        ('trac', {
            'label': 'Trac',
            'fields': ['bug_tracker_base_url'],
            'format': '%(bug_tracker_base_url)s/ticket/%%s',
        }),
        ('custom', {
            'label': _('Custom'),
            'fields': ['bug_tracker'],
            'format': '%(bug_tracker)s',
        }),
    ])

    HOSTING_FIELDS = [
        "path", "mirror_path", "hosting_owner", "hosting_project_name",
        "api_token",
    ]

    BUG_TRACKER_FIELDS = [
        "bug_tracker_base_url", "bug_tracker_owner",
        "bug_tracker_project_name", "bug_tracker",
    ]

    FORMAT_STR_RE = re.compile(r'%\(([A-Za-z0-9_-]+)\)s')


    # Host trust state
    reedit_repository = forms.BooleanField(
        label=_("Re-edit repository"),
        required=False)

    trust_host = forms.BooleanField(
        label=_("I trust this host"),
        required=False)

    # Fields
    hosting_type = forms.ChoiceField(
        label=_("Hosting service"),
        required=True,
        choices=[(service_id, info['label'])
                 for service_id, info in HOSTING_SERVICE_INFO.iteritems()],
        initial="custom")

    hosting_owner = forms.CharField(
        label=_("Project's owner"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '30'}))

    hosting_project_name = forms.CharField(
        label=_("Project name"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '30'}))

    api_token = forms.CharField(
        label=_("API token"),
        max_length=128,
        required=False,
        widget=forms.TextInput(attrs={'size': '60'}),
        help_text=_('The API token provided by the hosting service. This is '
                    'needed in order to access files on this repository. '
                    'On GitHub, you can find this on your '
                    '<a href="http://github.com/account">Account</a> page '
                    'under "Account Admin."'))

    tool = forms.ModelChoiceField(
        label=_("Repository type"),
        required=True,
        empty_label=None,
        queryset=Tool.objects.all())

    bug_tracker_use_hosting = forms.BooleanField(
        label=_("Use hosting service's bug tracker"),
        required=False)

    bug_tracker_type = forms.ChoiceField(
        label=_("Type"),
        required=True,
        choices=[(tracker_id, info['label'])
                 for tracker_id, info in BUG_TRACKER_INFO.iteritems()],
        initial="none")

    bug_tracker_owner = forms.CharField(
        label=_("Bug Tracker's owner"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '30'}))

    bug_tracker_project_name = forms.CharField(
        label=_("Project name"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '30'}))

    bug_tracker_base_url = forms.CharField(
        label=_("Bug tracker URL"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '60'}),
        help_text=_("This should be the path to the bug tracker for this "
                    "repository."))

    def __init__(self, *args, **kwargs):
        super(RepositoryForm, self).__init__(*args, **kwargs)

        self.hostkeyerror = None
        self.certerror = None
        self.userkeyerror = None

        self.public_key = sshutils.get_public_key(sshutils.get_user_key())

        self._populate_hosting_service_fields()
        self._populate_bug_tracker_fields()

    def _populate_hosting_service_fields(self):
        if (not self.instance or
            not self.instance.path):
            return

        tool_name = self.instance.tool.name

        for service_id, info in self.HOSTING_SERVICE_INFO.iteritems():
            if (service_id == 'custom' or tool_name not in info['tools']):
                continue

            field_info = info['tools'][tool_name]

            is_path_match, field_data = \
                self._match_url(self.instance.path,
                                field_info['path'],
                                info['fields'])

            if not is_path_match:
                continue

            if not self._match_url(self.instance.mirror_path,
                                   field_info['mirror_path'], [])[0]:
                continue

            if 'raw_file_url' in field_info:
                is_raw_match, raw_field_data = \
                    self._match_url(self.instance.raw_file_url,
                                    field_info['raw_file_url'],
                                    info['fields'])

                if not is_raw_match:
                    continue

                field_data.update(raw_field_data)

            # It all matched.
            self.fields['hosting_type'].initial = service_id

            for key, value in field_data.iteritems():
                self.fields[key].initial = value

            break

    def _populate_bug_tracker_fields(self):
        if not self.instance or not self.instance.bug_tracker:
            return

        for tracker_id, info in self.BUG_TRACKER_INFO.iteritems():
            if tracker_id == 'none':
                continue

            is_match, field_data = \
                self._match_url(self.instance.bug_tracker,
                                info['format'], info['fields'])

            if is_match:
                self.fields['bug_tracker_type'].initial = tracker_id

                for key, value in field_data.iteritems():
                    self.fields[key].initial = value

                # Figure out whether this matches the hosting service.
                if tracker_id == self.fields['hosting_type'].initial:
                    is_match = True

                    for field in info['fields']:
                        hosting_field = field.replace("bug_tracker_",
                                                      "hosting_")

                        if (self.fields[hosting_field].initial !=
                               self.fields[field].initial):
                            is_match = False
                            break

                    if is_match:
                        self.fields['bug_tracker_use_hosting'].initial = True

                break

    def _clean_hosting_info(self):
        hosting_type = self.cleaned_data['hosting_type']

        if hosting_type == 'custom':
            return

        # Should be caught during validation.
        assert hosting_type in self.HOSTING_SERVICE_INFO
        info = self.HOSTING_SERVICE_INFO[hosting_type]

        tool_name = self.cleaned_data['tool'].name
        assert tool_name in info['tools']

        field_data = {}

        for field in info['fields']:
            field_data[field] = self.cleaned_data[field]

        for field, value in info['tools'][tool_name].iteritems():
            self.cleaned_data[field] = value % field_data
            self.data[field] = value % field_data

    def _clean_bug_tracker_info(self):
        use_hosting = self.cleaned_data['bug_tracker_use_hosting']
        bug_tracker_type = self.cleaned_data['bug_tracker_type']

        if bug_tracker_type == 'none' and not use_hosting:
            self.instance.bug_tracker = ""
            return

        if use_hosting:
            match_type = self.cleaned_data['hosting_type']
        else:
            match_type = bug_tracker_type

        assert match_type in self.BUG_TRACKER_INFO
        info = self.BUG_TRACKER_INFO[match_type]

        field_data = {}

        for field in info['fields']:
            src_field = field

            if use_hosting:
                src_field = src_field.replace("bug_tracker_", "hosting_")

            field_data[field] = self.cleaned_data[src_field]

        bug_tracker_url = info['format'] % field_data
        self.cleaned_data['bug_tracker'] = bug_tracker_url
        self.data['bug_tracker'] = bug_tracker_url

    def full_clean(self):
        if self.data:
            hosting_type = (self['hosting_type'].data or
                            self.fields['hosting_type'].initial)
            use_hosting = (self['bug_tracker_use_hosting'].data or
                           self.fields['bug_tracker_use_hosting'].initial)

            self.fields['path'].required = (hosting_type == "custom")
            self.fields['bug_tracker_type'].required = not use_hosting

        return super(RepositoryForm, self).full_clean()

    def clean(self):
        """
        Performs validation on the form.

        This will check the form fields for errors, calling out to the
        various clean_* methods.

        It will check the repository path to see if it represents
        a valid repository and if an SSH key or HTTPS certificate needs
        to be verified.

        This will also build repository and bug tracker URLs based on other
        fields set in the form.
        """
        self._clean_hosting_info()
        self._clean_bug_tracker_info()

        validate_review_groups(self)
        validate_users(self)

        if not self.cleaned_data['reedit_repository']:
            self._verify_repository_path()

        return super(RepositoryForm, self).clean()

    def clean_path(self):
        return self.cleaned_data['path'].strip()

    def clean_mirror_path(self):
        return self.cleaned_data['mirror_path'].strip()

    def clean_bug_tracker_base_url(self):
        data = self.cleaned_data['bug_tracker_base_url']
        return data.rstrip("/")

    def clean_tool(self):
        """
        Checks the SCMTool used for this repository for dependencies.

        If one or more dependencies aren't found, they will be presented
        as validation errors.
        """
        tool = self.cleaned_data['tool']
        scmtool_class = tool.get_scmtool_class()

        errors = []

        for dep in scmtool_class.dependencies.get('modules', []):
            try:
                imp.find_module(dep)
            except ImportError:
                errors.append('The Python module "%s" is not installed.'
                              'You may need to restart the server '
                              'after installing it.' % dep)

        for dep in scmtool_class.dependencies.get('executables', []):
            if not is_exe_in_path(dep):
                if sys.platform == 'win32':
                    exe_name = '%s.exe' % dep
                else:
                    exe_name = dep

                errors.append('The executable "%s" is not in the path.' %
                              exe_name)

        if errors:
            raise forms.ValidationError(errors)

        return tool

    def is_valid(self):
        """
        Returns whether or not the form is valid.

        This will return True if the form fields are all valid, if there's
        no certificate error, host key error, and if the form isn't
        being re-displayed after canceling an SSH key or HTTPS certificate
        verification.
        """
        return (super(RepositoryForm, self).is_valid() and
                not self.hostkeyerror and
                not self.certerror and
                not self.userkeyerror and
                not self.cleaned_data['reedit_repository'])

    def _match_url(self, url, format, fields):
        """
        Matches a URL against a format string.

        This will determine if the URL can be represented by the format
        string. If so, the URL will parsed for the list of fields and
        returned.

        The result is in the form of (bool, field_dict).
        """
        def replace_match_group(m):
            name = m.group(1)

            if name in found_groups:
                return r'(?P=%s)' % name
            else:
                found_groups[name] = True
                return r'(?P<%s>[A-Za-z0-9:/._-]+)' % name

        # First, transform our Python format-style pattern to a regex.
        pattern = format.replace("%%s", "%s")
        pattern = pattern.replace("?", "\?")
        pattern = pattern.replace("+", "\+")

        # A list of match groups to replace that we've already found.
        # re.sub will get angry if it sees two with the same name.
        found_groups = {}

        pattern = self.FORMAT_STR_RE.sub(replace_match_group, pattern)

        m = re.match(pattern, url)

        if not m:
            return False, {}

        field_data = {}

        for field in fields:
            try:
                field_data[field] = m.group(field)
            except IndexError:
                pass

        return True, field_data

    def _verify_repository_path(self):
        """
        Verifies the repository path to check if it's valid.

        This will check if the repository exists and if an SSH key or
        HTTPS certificate needs to be verified.
        """
        tool = self.cleaned_data.get('tool', None)

        if not tool:
            # This failed validation earlier, so bail.
            return

        scmtool_class = tool.get_scmtool_class()

        path = self.cleaned_data['path']
        username = self.cleaned_data['username']
        password = self.cleaned_data['password']

        while 1:
            # Keep doing this until we have an error we don't want
            # to ignore, or it's successful.
            try:
                scmtool_class.check_repository(path, username, password)

                # Success.
                break
            except BadHostKeyError, e:
                if self.cleaned_data['trust_host']:
                    try:
                        sshutils.replace_host_key(e.hostname,
                                                  e.raw_expected_key,
                                                  e.raw_key)
                    except IOError, e:
                        raise forms.ValidationError(e)
                else:
                    self.hostkeyerror = e
                    break
            except UnknownHostKeyError, e:
                if self.cleaned_data['trust_host']:
                    try:
                        sshutils.add_host_key(e.hostname, e.raw_key)
                    except IOError, e:
                        raise forms.ValidationError(e)
示例#2
0
    def get_updated_questions_for_user(self, user):
        """
        retreive relevant question updates for the user
        according to their subscriptions and recorded question
        views
        """

        user_feeds = EmailFeedSetting.objects.filter(subscriber=user).exclude(
            frequency__in=('n', 'i'))

        should_proceed = False
        for feed in user_feeds:
            if feed.should_send_now() == True:
                should_proceed = True
                break

        #shortcircuit - if there is no ripe feed to work on for this user
        if should_proceed == False:
            return {}

        #these are placeholders for separate query sets per question group
        #there are four groups - one for each EmailFeedSetting.feed_type
        #and each group has subtypes A and B
        #that's because of the strange thing commented below
        #see note on Q and F objects marked with todo tag
        q_sel_A = None
        q_sel_B = None

        q_ask_A = None
        q_ask_B = None

        q_ans_A = None
        q_ans_B = None

        q_all_A = None
        q_all_B = None

        #base question query set for this user
        #basic things - not deleted, not closed, not too old
        #not last edited by the same user
        base_qs = Post.objects.get_questions(
        ).exclude(thread__last_activity_by=user).exclude(
            thread__last_activity_at__lt=user.date_joined  #exclude old stuff
        ).exclude(deleted=True).exclude(
            thread__closed=True).order_by('-thread__last_activity_at')

        if askbot_settings.ENABLE_CONTENT_MODERATION:
            base_qs = base_qs.filter(approved=True)
        #todo: for some reason filter on did not work as expected ~Q(viewed__who=user) |
        #      Q(viewed__who=user,viewed__when__lt=F('thread__last_activity_at'))
        #returns way more questions than you might think it should
        #so because of that I've created separate query sets Q_set2 and Q_set3
        #plus two separate queries run faster!

        #build two two queries based

        #questions that are not seen by the user at all
        not_seen_qs = base_qs.filter(~Q(viewed__who=user))
        #questions that were seen, but before last modification
        seen_before_last_mod_qs = base_qs.filter(
            Q(viewed__who=user,
              viewed__when__lt=F('thread__last_activity_at')))

        #shorten variables for convenience
        Q_set_A = not_seen_qs
        Q_set_B = seen_before_last_mod_qs

        for feed in user_feeds:
            if feed.feed_type == 'm_and_c':
                #alerts on mentions and comments are processed separately
                #because comments to questions do not trigger change of last_updated
                #this may be changed in the future though, see
                #http://askbot.org/en/question/96/
                continue

            #each group of updates represented by the corresponding
            #query set has it's own cutoff time
            #that cutoff time is computed for each user individually
            #and stored as a parameter "cutoff_time"

            #we won't send email for a given question if an email has been
            #sent after that cutoff_time
            if feed.should_send_now():
                if DEBUG_THIS_COMMAND == False:
                    feed.mark_reported_now()
                cutoff_time = feed.get_previous_report_cutoff_time()

                if feed.feed_type == 'q_sel':
                    q_sel_A = Q_set_A.filter(thread__followed_by=user)
                    q_sel_A.cutoff_time = cutoff_time  #store cutoff time per query set
                    q_sel_B = Q_set_B.filter(thread__followed_by=user)
                    q_sel_B.cutoff_time = cutoff_time  #store cutoff time per query set

                elif feed.feed_type == 'q_ask':
                    q_ask_A = Q_set_A.filter(author=user)
                    q_ask_A.cutoff_time = cutoff_time
                    q_ask_B = Q_set_B.filter(author=user)
                    q_ask_B.cutoff_time = cutoff_time

                elif feed.feed_type == 'q_ans':
                    q_ans_A = Q_set_A.filter(thread__posts__author=user,
                                             thread__posts__post_type='answer')
                    q_ans_A = q_ans_A[:askbot_settings.MAX_ALERTS_PER_EMAIL]
                    q_ans_A.cutoff_time = cutoff_time

                    q_ans_B = Q_set_B.filter(thread__posts__author=user,
                                             thread__posts__post_type='answer')
                    q_ans_B = q_ans_B[:askbot_settings.MAX_ALERTS_PER_EMAIL]
                    q_ans_B.cutoff_time = cutoff_time

                elif feed.feed_type == 'q_all':
                    q_all_A = user.get_tag_filtered_questions(Q_set_A)
                    q_all_B = user.get_tag_filtered_questions(Q_set_B)

                    q_all_A = q_all_A[:askbot_settings.MAX_ALERTS_PER_EMAIL]
                    q_all_B = q_all_B[:askbot_settings.MAX_ALERTS_PER_EMAIL]
                    q_all_A.cutoff_time = cutoff_time
                    q_all_B.cutoff_time = cutoff_time

        #build ordered list questions for the email report
        q_list = SortedDict()

        #todo: refactor q_list into a separate class?
        extend_question_list(q_sel_A, q_list)
        extend_question_list(q_sel_B, q_list)

        #build list of comment and mention responses here
        #it is separate because posts are not marked as changed
        #when people add comments
        #mention responses could be collected in the loop above, but
        #it is inconvenient, because feed_type m_and_c bundles the two
        #also we collect metadata for these here
        try:
            feed = user_feeds.get(feed_type='m_and_c')
            if feed.should_send_now():
                cutoff_time = feed.get_previous_report_cutoff_time()
                comments = Post.objects.get_comments().filter(
                    added_at__lt=cutoff_time, ).exclude(author=user)
                q_commented = list()
                for c in comments:
                    post = c.parent
                    if post.author != user:
                        continue

                    #skip is post was seen by the user after
                    #the comment posting time
                    q_commented.append(post.get_origin_post())

                extend_question_list(q_commented,
                                     q_list,
                                     cutoff_time=cutoff_time,
                                     add_comment=True)

                mentions = Activity.objects.get_mentions(
                    mentioned_at__lt=cutoff_time, mentioned_whom=user)

                #print 'have %d mentions' % len(mentions)
                #MM = Activity.objects.filter(activity_type = const.TYPE_ACTIVITY_MENTION)
                #print 'have %d total mentions' % len(MM)
                #for m in MM:
                #    print m

                mention_posts = get_all_origin_posts(mentions)
                q_mentions_id = [q.id for q in mention_posts]

                q_mentions_A = Q_set_A.filter(id__in=q_mentions_id)
                q_mentions_A.cutoff_time = cutoff_time
                extend_question_list(q_mentions_A, q_list, add_mention=True)

                q_mentions_B = Q_set_B.filter(id__in=q_mentions_id)
                q_mentions_B.cutoff_time = cutoff_time
                extend_question_list(q_mentions_B, q_list, add_mention=True)
        except EmailFeedSetting.DoesNotExist:
            pass

        if user.email_tag_filter_strategy == const.INCLUDE_INTERESTING:
            extend_question_list(q_all_A, q_list)
            extend_question_list(q_all_B, q_list)

        extend_question_list(q_ask_A, q_list, limit=True)
        extend_question_list(q_ask_B, q_list, limit=True)

        extend_question_list(q_ans_A, q_list, limit=True)
        extend_question_list(q_ans_B, q_list, limit=True)

        if user.email_tag_filter_strategy == const.EXCLUDE_IGNORED:
            extend_question_list(q_all_A, q_list, limit=True)
            extend_question_list(q_all_B, q_list, limit=True)

        ctype = ContentType.objects.get_for_model(Post)
        EMAIL_UPDATE_ACTIVITY = const.TYPE_ACTIVITY_EMAIL_UPDATE_SENT

        #up to this point we still don't know if emails about
        #collected questions were sent recently
        #the next loop examines activity record and decides
        #for each question, whether it needs to be included or not
        #into the report

        for q, meta_data in q_list.items():
            #this loop edits meta_data for each question
            #so that user will receive counts on new edits new answers, etc
            #and marks questions that need to be skipped
            #because an email about them was sent recently enough

            #also it keeps a record of latest email activity per question per user
            try:
                #todo: is it possible to use content_object here, instead of
                #content type and object_id pair?
                update_info = Activity.objects.get(
                    user=user,
                    content_type=ctype,
                    object_id=q.id,
                    activity_type=EMAIL_UPDATE_ACTIVITY)
                emailed_at = update_info.active_at
            except Activity.DoesNotExist:
                update_info = Activity(user=user,
                                       content_object=q,
                                       activity_type=EMAIL_UPDATE_ACTIVITY)
                emailed_at = datetime.datetime(1970, 1, 1)  #long time ago
            except Activity.MultipleObjectsReturned:
                raise Exception(
                    'server error - multiple question email activities '
                    'found per user-question pair')

            cutoff_time = meta_data[
                'cutoff_time']  #cutoff time for the question

            #skip question if we need to wait longer because
            #the delay before the next email has not yet elapsed
            #or if last email was sent after the most recent modification
            if emailed_at > cutoff_time or emailed_at > q.thread.last_activity_at:
                meta_data['skip'] = True
                continue

            #collect info on all sorts of news that happened after
            #the most recent emailing to the user about this question
            q_rev = PostRevision.objects.question_revisions().filter(
                post=q, revised_at__gt=emailed_at)

            q_rev = q_rev.exclude(author=user)

            #now update all sorts of metadata per question
            meta_data['q_rev'] = len(q_rev)
            if len(q_rev) > 0 and q.added_at == q_rev[0].revised_at:
                meta_data['q_rev'] = 0
                meta_data['new_q'] = True
            else:
                meta_data['new_q'] = False

            new_ans = Post.objects.get_answers().filter(
                thread=q.thread,
                added_at__gt=emailed_at,
                deleted=False,
            )

            new_ans = new_ans.exclude(author=user)
            meta_data['new_ans'] = len(new_ans)
            ans_rev = PostRevision.objects.answer_revisions().filter(
                # answer__question = q
                post__thread=q.thread,
                post__deleted=False,
                revised_at__gt=emailed_at).distinct()
            ans_rev = ans_rev.exclude(author=user)
            meta_data['ans_rev'] = len(ans_rev)

            comments = meta_data.get('comments', 0)
            mentions = meta_data.get('mentions', 0)

            #print meta_data
            #finally skip question if there are no news indeed
            if len(q_rev) + len(new_ans) + len(
                    ans_rev) + comments + mentions == 0:
                meta_data['skip'] = True
                #print 'skipping'
            else:
                meta_data['skip'] = False
                #print 'not skipping'
                update_info.active_at = datetime.datetime.now()
                if DEBUG_THIS_COMMAND == False:
                    update_info.save()  #save question email update activity
        #q_list is actually an ordered dictionary
        #print 'user %s gets %d' % (user.username, len(q_list.keys()))
        #todo: sort question list by update time
        return q_list
示例#3
0
        else:
            count += 1
    return count


def index_decorator(func):
    def inner(*args, **kwargs):
        templateresponse = func(*args, **kwargs)
        for app in templateresponse.context_data['app_list']:
            app['models'].sort(key=lambda x: find_model_index(x['name']))
        return templateresponse

    return inner


registry = SortedDict()
registry.update(admin.site._registry)
admin.site._registry = registry
admin.site.index = index_decorator(admin.site.index)
admin.site.app_index = index_decorator(admin.site.app_index)
#####END app 顺序显示

from django.db import models
from django.utils.html import format_html  #设置字段颜色

# Create your models here.


class Cis(models.Model):
    class Meta:
        db_table = 'cis'
示例#4
0
    def get_nav_menu(self):
        site_menu = list(self.get_site_menu() or [])
        had_urls = []

        def get_url(menu, had_urls):
            if 'url' in menu:
                had_urls.append(menu['url'])
            if 'menus' in menu:
                for m in menu['menus']:
                    get_url(m, had_urls)
        get_url({'menus': site_menu}, had_urls)

        nav_menu = SortedDict()

        for model, model_admin in self.admin_site._registry.items():
            if getattr(model_admin, 'hidden_menu', False):
                continue
            app_label = model._meta.app_label
            model_dict = {
                'title': unicode(capfirst(model._meta.verbose_name_plural)),
                'url': self.get_model_url(model, "changelist"),
                'icon': self.get_model_icon(model),
                'perm': self.get_model_perm(model, 'view'),
                'order': model_admin.order,
            }
            if model_dict['url'] in had_urls:
                continue

            app_key = "app:%s" % app_label
            if app_key in nav_menu:
                nav_menu[app_key]['menus'].append(model_dict)
            else:
                # Find app title
                app_title = unicode(app_label.title())
                if app_label.lower() in self.apps_label_title:
                    app_title = self.apps_label_title[app_label.lower()]
                else:
                    mods = model.__module__.split('.')
                    if len(mods) > 1:
                        mod = '.'.join(mods[0:-1])
                        if mod in sys.modules:
                            mod = sys.modules[mod]
                            if 'verbose_name' in dir(mod):
                                app_title = getattr(mod, 'verbose_name')
                            elif 'app_title' in dir(mod):
                                app_title = getattr(mod, 'app_title')

                nav_menu[app_key] = {
                    'title': app_title,
                    'menus': [model_dict],
                }

            app_menu = nav_menu[app_key]
            if ('first_icon' not in app_menu or
                    app_menu['first_icon'] == self.default_model_icon) and model_dict.get('icon'):
                app_menu['first_icon'] = model_dict['icon']
            if 'first_url' not in app_menu and model_dict.get('url'):
                app_menu['first_url'] = model_dict['url']

        for menu in nav_menu.values():
            menu['menus'].sort(key=sortkeypicker(['order', 'title']))

        nav_menu = nav_menu.values()
        nav_menu.sort(key=lambda x: x['title'])

        site_menu.extend(nav_menu)

        return site_menu
示例#5
0
文件: hashers.py 项目: tail/django
 def safe_summary(self, encoded):
     return SortedDict([
         (_('algorithm'), self.algorithm),
         (_('hash'), mask_hash(encoded, show=3)),
     ])
示例#6
0
文件: syncdb.py 项目: DaveLepp/wmr
class Command(NoArgsCommand):
    option_list = syncdb.Command.option_list + (
        make_option(
            '--migrate',
            action='store_true',
            dest='migrate',
            default=False,
            help=
            'Tells South to also perform migrations after the sync. Default for during testing, and other internal calls.'
        ),
        make_option(
            '--all',
            action='store_true',
            dest='migrate_all',
            default=False,
            help=
            'Makes syncdb work on all apps, even migrated ones. Be careful!'),
    )
    if '--verbosity' not in [
            opt.get_opt_string() for opt in syncdb.Command.option_list
    ]:
        option_list += (make_option(
            '--verbosity',
            action='store',
            dest='verbosity',
            default='1',
            type='choice',
            choices=['0', '1', '2'],
            help=
            'Verbosity level; 0=minimal output, 1=normal output, 2=all output'
        ), )
    help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created, except those which use migrations."

    def handle_noargs(self, migrate_all=False, **options):

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        # This is copied from Django, to fix bug #511.
        try:
            from django.utils.importlib import import_module
        except ImportError:
            pass  # TODO: Remove, only for Django1.0
        else:
            for app_name in settings.INSTALLED_APPS:
                try:
                    import_module('.management', app_name)
                except ImportError, exc:
                    msg = exc.args[0]
                    if not msg.startswith(
                            'No module named') or 'management' not in msg:
                        raise

        # Work out what uses migrations and so doesn't need syncing
        apps_needing_sync = []
        apps_migrated = []
        for app in models.get_apps():
            app_label = get_app_label(app)
            if migrate_all:
                apps_needing_sync.append(app_label)
            else:
                try:
                    migrations = migration.Migrations(app_label)
                except NoMigrations:
                    # It needs syncing
                    apps_needing_sync.append(app_label)
                else:
                    # This is a migrated app, leave it
                    apps_migrated.append(app_label)
        verbosity = int(options.get('verbosity', 0))

        # Run syncdb on only the ones needed
        if verbosity:
            print "Syncing..."

        old_installed, settings.INSTALLED_APPS = settings.INSTALLED_APPS, apps_needing_sync
        old_app_store, cache.app_store = cache.app_store, SortedDict([
            (k, v) for (k, v) in cache.app_store.items()
            if get_app_label(k) in apps_needing_sync
        ])

        # This will allow the setting of the MySQL storage engine, for example.
        for db in dbs.values():
            db.connection_init()

        # OK, run the actual syncdb
        syncdb.Command().execute(**options)

        settings.INSTALLED_APPS = old_installed
        cache.app_store = old_app_store

        # Migrate if needed
        if options.get('migrate', True):
            if verbosity:
                print "Migrating..."
            management.call_command('migrate', **options)

        # Be obvious about what we did
        if verbosity:
            print "\nSynced:\n > %s" % "\n > ".join(apps_needing_sync)

        if options.get('migrate', True):
            if verbosity:
                print "\nMigrated:\n - %s" % "\n - ".join(apps_migrated)
        else:
            if verbosity:
                print "\nNot synced (use migrations):\n - %s" % "\n - ".join(
                    apps_migrated)
                print "(use ./manage.py migrate to migrate these)"
示例#7
0
 def get_visible_fields_dict(self, bound_fields):
     return SortedDict(
         (field_name, bound_field)
         for (field_name, bound_field) in six.iteritems(bound_fields) if not bound_field.is_hidden
     )
示例#8
0
    def as_dict(self):
        """
        Returns a form as a dictionary that looks like the following:

        form = {
            'non_field_errors': [],
            'label_suffix': ':',
            'is_bound': False,
            'prefix': 'text'.
            'fields': {
                'name': {
                    'type': 'type',
                    'errors': {},
                    'help_text': 'text',
                    'label': 'text',
                    'initial': 'data',
                    'max_length': 'number',
                    'min_length: 'number',
                    'required': False,
                    'bound_data': 'data'
                    'widget': {
                        'attr': 'value'
                    }
                }
            }
        }
        """
        form_dict = SortedDict()
        form_dict['title'] = self.form.__class__.__name__
        form_dict['non_field_errors'] = self.form.non_field_errors()
        form_dict['label_suffix'] = self.form.label_suffix
        form_dict['is_bound'] = self.form.is_bound
        form_dict['prefix'] = self.form.prefix
        form_dict['fields'] = SortedDict()
        form_dict['errors'] = self.form.errors
        form_dict['fieldsets'] = getattr(self.form, 'fieldsets', [])

        # If there are no fieldsets, specify order
        form_dict['ordered_fields'] = self.fields

        initial_data = {}

        for name, field in [(x, self.form.fields[x]) for x in self.fields]:
            # Retrieve the initial data from the form itself if it exists so
            # that we properly handle which initial data should be returned in
            # the dictionary.

            # Please refer to the Django Form API documentation for details on
            # why this is necessary:
            # https://docs.djangoproject.com/en/dev/ref/forms/api/#dynamic-initial-values
            form_initial_field_data = self.form.initial.get(name)

            # Instantiate the Remote Forms equivalent of the field if possible
            # in order to retrieve the field contents as a dictionary.
            remote_field_class_name = 'Remote%s' % field.__class__.__name__
            try:
                remote_field_class = getattr(fields, remote_field_class_name)
                remote_field = remote_field_class(field,
                                                  form_initial_field_data,
                                                  field_name=name)
            except Exception, e:
                logger.warning('Error serializing field %s: %s',
                               remote_field_class_name, str(e))
                field_dict = {}
            else:
                field_dict = remote_field.as_dict()

            if name in self.readonly_fields:
                field_dict['readonly'] = True

            form_dict['fields'][name] = field_dict

            # Load the initial data, which is a conglomerate of form initial and field initial
            if 'initial' not in form_dict['fields'][name]:
                form_dict['fields'][name]['initial'] = None

            initial_data[name] = form_dict['fields'][name]['initial']
示例#9
0
文件: views.py 项目: verali/horizon
    def get_data(self):
        instances = []
        marker = self.request.GET.get(
            project_tables.AdminInstancesTable._meta.pagination_param, None)
        search_opts = self.get_filters({'marker': marker, 'paginate': True})
        # Gather our tenants to correlate against IDs
        try:
            tenants, has_more = api.keystone.tenant_list(self.request)
        except Exception:
            tenants = []
            msg = _('Unable to retrieve instance project information.')
            exceptions.handle(self.request, msg)

        if 'project' in search_opts:
            ten_filter_ids = [
                t.id for t in tenants if t.name == search_opts['project']
            ]
            del search_opts['project']
            if len(ten_filter_ids) > 0:
                search_opts['tenant_id'] = ten_filter_ids[0]
            else:
                self._more = False
                return []

        try:
            instances, self._more = api.nova.server_list(
                self.request, search_opts=search_opts, all_tenants=True)
        except Exception:
            self._more = False
            exceptions.handle(self.request,
                              _('Unable to retrieve instance list.'))
        if instances:
            try:
                api.network.servers_update_addresses(self.request,
                                                     instances,
                                                     all_tenants=True)
            except Exception:
                exceptions.handle(
                    self.request,
                    message=_('Unable to retrieve IP addresses from Neutron.'),
                    ignore=True)

            # Gather our flavors to correlate against IDs
            try:
                flavors = api.nova.flavor_list(self.request)
            except Exception:
                # If fails to retrieve flavor list, creates an empty list.
                flavors = []

            full_flavors = SortedDict([(f.id, f) for f in flavors])
            tenant_dict = SortedDict([(t.id, t) for t in tenants])
            # Loop through instances to get flavor and tenant info.
            for inst in instances:
                flavor_id = inst.flavor["id"]
                try:
                    if flavor_id in full_flavors:
                        inst.full_flavor = full_flavors[flavor_id]
                    else:
                        # If the flavor_id is not in full_flavors list,
                        # gets it via nova api.
                        inst.full_flavor = api.nova.flavor_get(
                            self.request, flavor_id)
                except Exception:
                    msg = _('Unable to retrieve instance size information.')
                    exceptions.handle(self.request, msg)
                tenant = tenant_dict.get(inst.tenant_id, None)
                inst.tenant_name = getattr(tenant, "name", None)
        return instances
示例#10
0
 def handle(self, *args, **options):
     from django.conf import settings
     from accounts.choices import COUNTRY_CHOICES
     from rent.models import Booking
     log.info('Starting daily insurance subscriptions batch')
     csv_file = TemporaryFile()
     latin1csv_file = codecs.EncodedFile(csv_file, 'utf-8', 'latin1', 'ignore')
     writer = csv.writer(latin1csv_file, delimiter='|')
     period = (date.today() - timedelta(days=100))
     for booking in Booking.objects.pending().filter(created_at__year=period.year, created_at__month=period.month, created_at__day=period.day):
         row = SortedDict()
         row['Numéro locataire'] = booking.borrower.pk
         row['Login locataire'] = booking.borrower.username
         row['Adresse email'] = booking.borrower.email
         phones = tuple(booking.borrower.phones.all()[:1])
         phone = phones[0] if phones else None
         row['Téléphone locataire'] = phone
         row['Portable locataire'] = phone
         row['Nom'] = smart_str(booking.borrower.last_name.replace("\n", " ").replace("\r", " "))
         row[u'Prénom'] = smart_str(booking.borrower.first_name.replace("\n", " ").replace("\r", " "))
         for address in booking.borrower.addresses.all()[:1]:
             row['Adresse 1'] = smart_str(address.address1.replace("\n", " ").replace("\r", " "))
             row['Adresse 2'] = smart_str(address.address2.replace("\n", " ").replace("\r", " ")) if address.address2 else None
             row['Code postal'] = address.zipcode.replace("\n", " ").replace("\r", " ")
             row['Ville'] = smart_str(address.city.replace("\n", " ").replace("\r", " "))
             row['Pays'] = COUNTRY_CHOICES[address.country]
             break
         else:
             row['Adresse 1'] = \
             row['Adresse 2'] = \
             row['Code postal'] = \
             row['Ville'] = \
             row['Pays'] = \
         row['Numéro propriétaire'] = smart_str(booking.owner.pk)
         row['Login propriétaire'] = smart_str(booking.owner.username)
         row['Adresse email propriétaire'] = booking.owner.email
         phones = tuple(booking.owner.phones.all()[:1])
         phone = phones[0] if phones else None
         row['Téléphone propriétaire'] = phone
         row['Portable propriétaire'] = phone
         row['Nom propriétaire'] = smart_str(booking.owner.last_name.replace("\n", " ").replace("\r", " "))
         row[u'Prénom propriétaire'] = smart_str(booking.owner.first_name.replace("\n", " ").replace("\r", " "))
         for address in booking.owner.addresses.all()[:1]:
             row['Adresse 1 propriétaire'] = smart_str(address.address1.replace("\n", " ").replace("\r", " "))
             row['Adresse 2 propriétaire'] = smart_str(address.address2.replace("\n", " ").replace("\r", " ") if address.address2 else None)
             row['Code postal propriétaire'] = address.zipcode.replace("\n", " ").replace("\r", " ")
             row['Ville propriétaire'] = smart_str(address.city.replace("\n", " ").replace("\r", " "))
             row['Pays propriétaire'] = COUNTRY_CHOICES[address.country]
             break
         else:
             row['Adresse 1 propriétaire'] = \
             row['Adresse 2 propriétaire'] = \
             row['Code postal propriétaire'] = \
             row['Ville propriétaire'] = \
             row['Pays propriétaire'] = None
         row['Numéro police'] = settings.POLICY_NUMBER
         row['Numéro partenaire'] = settings.PARTNER_NUMBER
         row['Numéro contrat'] = 500000 + booking.contract_id
         row['Date d\'effet de la location'] = booking.started_at.strftime("%Y%m%d")
         row[u'Numéro de commande'] = booking.uuid
         try:
             product = booking.product
             row['Type de produit'] = smart_str(product._get_category().name)
             row[u'Désignation'] = smart_str(product.description.replace("\n", " ").replace("\r", " "))
             row['Informations complémentaires produit'] = smart_str(product.summary.replace("\n", " ").replace("\r", " "))
         except ObjectDoesNotExist:
             row['Type de produit'] = \
             row[u'Désignation'] = \
             row['Informations complémentaires produit'] = None
         row['Prix de la location TTC'] = comma_separated(booking.total_amount)
         row['Montant de la Caution'] = comma_separated(booking.deposit_amount)
         row[u'Durée de garantie'] = (booking.ended_at - booking.started_at).days
         try:
             row[u'Prix de cession de l\'assurance HT'] = comma_separated(round(booking.insurance_fee, 2))
             row['Com. du partenaire'] = comma_separated(round(booking.insurance_commission, 2))
             row['Taxes assurance à 9%'] = comma_separated(round(booking.insurance_taxes, 2))
         except ObjectDoesNotExist:
             row[u'Prix de cession de l\'assurance HT'] = \
             row['Com. du partenaire'] = \
             row['Taxes assurance à 9%'] = None
         row['Cotisation TTC'] = comma_separated(round(booking.insurance_amount, 2))
         writer.writerow(row.values())
     latin1csv_file.seek(0)
     log.info('Uploading daily insurance subscriptions')
     ftp = FTP(settings.INSURANCE_FTP_HOST)
     ftp.login(settings.INSURANCE_FTP_USER, settings.INSURANCE_FTP_PASSWORD)
     # set FTP PASSIVE mode; disabled by default
     ftp.set_pasv(getattr(settings, 'INSURANCE_FTP_PASSIVE_MODE', 0))
     if settings.INSURANCE_FTP_CWD:
         ftp.cwd(settings.INSURANCE_FTP_CWD)
     ftp.storlines("STOR subscriptions-eloue-%s-%s-%s.csv" % (period.year, period.month, period.day), latin1csv_file)
     ftp.quit()
     log.info('Finished daily insurance subscriptions batch')
示例#11
0
		SortedDict([
			('fss_no', {
					't':	forms.IntegerField,
					'a':	{
						'label':	'Филиал ФСС №',
						'help_text':	'пример: Общество с ограниченной ответственностью «Торговый дом Ромашко»',
					}
			}),
			('opening', {
					't':	forms.BooleanField,
					'a':	{
						'label':	'Открытие',
						'required':	False,
					}
			}),
			('oname', {
					't':	forms.CharField,
					'a':	{
						'label':	'Наименование фирмы (полное)',
						'help_text':	'пример: Общество с ограниченной ответственностью «Торговый дом Ромашко»',
					}
			}),
			('oinn', {
					't':	forms.CharField,
					'a':	{
						'label':	'ИНН фирмы',
						'min_length':	10,
						'max_length':	12,
					}
			}),
			('okpp', {
					't':	forms.CharField,
					'a':	{
						'label':	'КПП фирмы',
						'min_length':	9,
						'max_length':	9,
					}
			}),
			('ookato', {
					't':	forms.CharField,
					'a':	{
						'label':	'ОКАТО фирмы',
						'min_length':	8,
						'max_length':	11,
					}
			}),
			('oogrn', {
					't':	forms.CharField,
					'a':	{
						'label':	'Рег. №',
						'help_text':	'ОГРН, штоле?',
						'min_length':	10,
						'max_length':	16,
					}
			}),
			('bname', {
					't':	forms.CharField,
					'a':	{
						'label':	'Полное наименование банка',
						'help_text':	'пример: Открытое акционерное общество «Санкт-Петербургский Индустриальный Акционерный Банк»',
					}
			}),
			('binn', {
					't':	forms.CharField,
					'a':	{
						'label':	'ИНН банка',
						'min_length':	10,
						'max_length':	12,
					}
			}),
			('bkpp', {
					't':	forms.CharField,
					'a':	{
						'label':	'КПП банка',
						'min_length':	9,
						'max_length':	9,
					}
			}),
			('bogrn', {
					't':	forms.CharField,
					'a':	{
						'label':	'ОГРН банка',
						'min_length':	10,
						'max_length':	16,
					}
			}),
			('bik', {
					't':	forms.CharField,
					'a':	{
						'label':	'БИК',
						'min_length':	9,
						'max_length':	9,
					}
			}),
			('rs', {
					't':	forms.CharField,
					'a':	{
						'label':	'Р/с',
						'min_length':	20,
						'max_length':	20,
					}
			}),
			('jobrole', {
					't':	forms.CharField,
					'a':	{
						'label':	'Руководитель.Должность',
						'help_text':	'пример: Ген. директор',
						'min_length':	4,
						'max_length':	20,
					}
			}),
			('boss_fio', {
					't':	forms.CharField,
					'a':	{
						'label':	'Руководитель.Фамилия И. О.',
						'help_text':	'пример: Ген. директор',
						'min_length':	4,
						'max_length':	20,
					}
			}),
			('date0', {
					't':	forms.DateField,
					'a':	{
						'label':	'Дата закрытия/открытия',
						'help_text':	'пример: 27.09.2011',
					}
			}),
			('date1', {
					't':	forms.DateField,
					'a':	{
						'label':	'Дата документа',
					}
			}),
		]),
示例#12
0
文件: forms.py 项目: xspager/django
    old_password = forms.CharField(label=_("Old password"),
                                   widget=forms.PasswordInput)

    def clean_old_password(self):
        """
        Validates that the old_password field is correct.
        """
        old_password = self.cleaned_data["old_password"]
        if not self.user.check_password(old_password):
            raise forms.ValidationError(
                self.error_messages['password_incorrect'])
        return old_password


PasswordChangeForm.base_fields = SortedDict([
    (k, PasswordChangeForm.base_fields[k])
    for k in ['old_password', 'new_password1', 'new_password2']
])


class AdminPasswordChangeForm(forms.Form):
    """
    A form used to change the password of a user in the admin interface.
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(label=_("Password"),
                                widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password (again)"),
                                widget=forms.PasswordInput)
示例#13
0
def get_language_from_request(request, check_path=False):
    """
    Analyzes the request to find what language the user wants the system to
    show. Only languages listed in settings.LANGUAGES are taken into account.
    If the user requests a sublanguage where we have a main language, we send
    out the main language.

    If check_path is True, the URL path prefix will be checked for a language
    code, otherwise this is skipped for backwards compatibility.
    """
    global _accepted
    from django.conf import settings
    supported = SortedDict(settings.LANGUAGES)

    if check_path:
        lang_code = get_language_from_path(request.path_info, supported)
        if lang_code is not None:
            return lang_code

    if hasattr(request, 'session'):
        lang_code = request.session.get('django_language', None)
        if lang_code in supported and lang_code is not None and check_for_language(
                lang_code):
            return lang_code

    lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)

    try:
        return get_supported_language_variant(lang_code, supported)
    except LookupError:
        pass

    accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
    for accept_lang, unused in parse_accept_lang_header(accept):
        if accept_lang == '*':
            break

        # 'normalized' is the root name of the locale in POSIX format (which is
        # the format used for the directories holding the MO files).
        normalized = locale.locale_alias.get(to_locale(accept_lang, True))
        if not normalized:
            continue
        # Remove the default encoding from locale_alias.
        normalized = normalized.split('.')[0]

        if normalized in _accepted:
            # We've seen this locale before and have an MO file for it, so no
            # need to check again.
            return _accepted[normalized]

        try:
            accept_lang = get_supported_language_variant(
                accept_lang, supported)
        except LookupError:
            continue
        else:
            _accepted[normalized] = accept_lang
            return accept_lang

    try:
        return get_supported_language_variant(settings.LANGUAGE_CODE,
                                              supported)
    except LookupError:
        return settings.LANGUAGE_CODE
示例#14
0
def make_missing_data_form(instance, required_fields=[]):
    fields = SortedDict({
        'is_professional':
        forms.BooleanField(
            label=_(u"Professionnel"),
            required=False,
            initial=False,
            widget=CommentedCheckboxInput(info_text='Je suis professionnel')),
        'company_name':
        forms.CharField(label=_(u"Nom de la société"),
                        required=False,
                        max_length=255,
                        widget=forms.TextInput(attrs={'class': 'inm'})),
        'username':
        forms.RegexField(
            label=_(u"Pseudo"),
            max_length=30,
            regex=r'^[\w.@+-]+$',
            help_text=
            _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."
              ),
            error_messages={
                'invalid':
                _("This value may contain only letters, numbers and @/./+/-/_ characters."
                  )
            },
            widget=forms.TextInput(attrs={'class': 'inm'})),
        'password1':
        forms.CharField(label=_(u"Mot de passe"),
                        max_length=128,
                        required=True,
                        widget=forms.PasswordInput(attrs={'class': 'inm'})),
        'password2':
        forms.CharField(label=_(u"Mot de passe à nouveau"),
                        max_length=128,
                        required=True,
                        widget=forms.PasswordInput(attrs={'class': 'inm'})),
        'first_name':
        forms.CharField(label=_(u"Prénom"),
                        max_length=30,
                        required=True,
                        widget=forms.TextInput(attrs={'class': 'inm'})),
        'last_name':
        forms.CharField(label=_(u"Nom"),
                        max_length=30,
                        required=True,
                        widget=forms.TextInput(attrs={'class': 'inm'})),
        'addresses__address1':
        forms.CharField(label=_(u"Rue"),
                        max_length=255,
                        widget=forms.Textarea(attrs={'class': 'inm street'})),
        'addresses__zipcode':
        forms.CharField(
            label=_(u"Code postal"),
            required=True,
            max_length=9,
            widget=forms.TextInput(attrs={'class': 'inm zipcode'})),
        'addresses__city':
        forms.CharField(label=_(u"Ville"),
                        required=True,
                        max_length=255,
                        widget=forms.TextInput(attrs={'class': 'inm town'})),
        'addresses__country':
        forms.ChoiceField(label=_(u"Pays"),
                          choices=COUNTRY_CHOICES,
                          required=True,
                          widget=forms.Select(attrs={'class': 'selm'})),
        'avatar':
        forms.ImageField(required=False, label=_(u"Photo de profil")),
        'phones__phone':
        PhoneNumberField(label=_(u"Téléphone"),
                         required=True,
                         widget=forms.TextInput(attrs={'class': 'inm'})),
        'drivers_license_number':
        forms.CharField(label=_(u'Numéro de permis'), max_length=32),
        'drivers_license_date':
        DateSelectField(label=_(u'Date de délivraisance')),
        'date_of_birth':
        DateSelectField(label=_(u'Date de naissance')),
        'place_of_birth':
        forms.CharField(label=_(u'Lieu de naissance'), max_length=255),
        'cvv':
        forms.CharField(
            max_length=4,
            label=_(u'Cryptogramme de sécurité'),
            help_text=_(u'Les 3 derniers chiffres au dos de la carte.')),
        'expires':
        ExpirationField(label=_(u'Date d\'expiration')),
        'holder_name':
        forms.CharField(label=_(u'Titulaire de la carte')),
        'card_number':
        CreditCardField(label=_(u'Numéro de carte de crédit')),
        'godfather_email':
        forms.EmailField(
            label=_(u'Email de votre parrain'),
            required=False,
            help_text=
            _(u'Commissions offertes pendant 3 mois si vous êtes parrainé par membre e-loue. Offre valable entre le 18 avril et le 30 avril 2013.'
              )),
    })

    # Are we in presence of a pro ?
    if fields.has_key('is_professional'):
        if instance and getattr(instance, 'is_professional', None) != None:
            del fields['is_professional']
            del fields['company_name']

    # Do we have an address ?
    if instance and instance.addresses.exists():
        fields['addresses'] = forms.ModelChoiceField(
            label=_(u"Adresse"),
            required=False,
            queryset=instance.addresses.all(),
            initial=instance.default_address
            if instance.default_address else instance.addresses.all()[0],
            widget=forms.Select(attrs={'class': 'selm'}),
            help_text=_(u"Selectionnez une adresse enregistrée précédemment"))
        for f in fields.keys():
            if "addresses" in f:
                fields[f].required = False

    # Do we have a phone number ?
    if instance and instance.phones.exists():
        fields['phones'] = forms.ModelChoiceField(
            label=_(u"Téléphone"),
            required=False,
            queryset=instance.phones.all(),
            initial=instance.phones.all()[0],
            widget=forms.Select(attrs={'class': 'selm'}),
            help_text=_(
                u"Selectionnez un numéro de téléphone enregistré précédemment")
        )
        if fields.has_key('phones__phone'):
            fields['phones__phone'].required = False

    # Do we have a password ?
    if fields.has_key('password1'):
        if instance and getattr(instance, 'password', None):
            del fields['password1']
            del fields['password2']

    if instance and instance.username and "first_name" not in required_fields:
        del fields['avatar']

    if instance:
        try:
            if instance.creditcard:
                del fields['cvv']
                del fields['expires']
                del fields['holder_name']
                del fields['card_number']
        except CreditCard.DoesNotExist:
            pass

    for f in fields.keys():
        if required_fields and f not in required_fields:
            del fields[f]
            continue
        if "__" in f or f in ["addresses", "phones", "password"]:
            continue
        if hasattr(instance, f) and getattr(instance, f):
            del fields[f]

    def save(self):
        for attr, value in self.cleaned_data.iteritems():
            if attr == "password1":
                self.instance.set_password(value)
            if "addresses" not in attr and "phones" not in attr:  # wtf is this checking?
                setattr(self.instance, attr, value)
        if 'addresses' in self.cleaned_data and self.cleaned_data['addresses']:
            address = self.cleaned_data['addresses']
        elif 'addresses__address1' in self.cleaned_data:
            address = self.instance.addresses.create(
                address1=self.cleaned_data['addresses__address1'],
                zipcode=self.cleaned_data['addresses__zipcode'],
                city=self.cleaned_data['addresses__city'],
                country=self.cleaned_data['addresses__country'])
            self.instance.default_address = address
        else:
            address = None
        if 'phones' in self.cleaned_data and self.cleaned_data['phones']:
            phone = self.cleaned_data['phones']
        elif 'phones__phone' in self.cleaned_data:
            phone = self.instance.phones.create(
                number=self.cleaned_data['phones__phone'])
        else:
            phone = None
        if self.cleaned_data.get('card_number'):
            pm = PayboxManager()
            subscriber_reference = uuid.uuid4().hex
            self.cleaned_data['card_number'] = pm.subscribe(
                subscriber_reference, self.cleaned_data['card_number'],
                self.cleaned_data['expires'], self.cleaned_data['cvv'])
            credit_card = CreditCard.objects.create(
                subscriber_reference=subscriber_reference,
                masked_number=self.cleaned_data['masked_number'],
                card_number=self.cleaned_data['card_number'],
                holder_name=self.cleaned_data['holder_name'],
                expires=self.cleaned_data['expires'],
                holder=self.instance,
                keep=True)
        else:
            credit_card = None

        self.instance.save()
        return self.instance, address, phone, credit_card

    def clean_username(self):
        if Patron.objects.filter(
                username=self.cleaned_data['username']).exists():
            raise forms.ValidationError(
                _(u"Ce nom d'utilisateur est déjà pris."))
        if Patron.objects.filter(
                slug=slugify(self.cleaned_data['username'])).exists():
            raise forms.ValidationError(
                _(u"Ce nom d'utilisateur est déjà pris."))
        return self.cleaned_data['username']

    def clean_addresses(self):
        addresses = self.cleaned_data['addresses']
        address1 = self.cleaned_data['addresses__address1']
        zipcode = self.cleaned_data['addresses__zipcode']
        city = self.cleaned_data['addresses__city']
        country = self.cleaned_data['addresses__country']

        if not addresses and not (address1 and zipcode and city and country):
            raise forms.ValidationError(_(u"Vous devez spécifiez une adresse"))
        return self.cleaned_data['addresses']

    def clean_company_name(self):
        is_professional = self.cleaned_data.get('is_professional')
        company_name = self.cleaned_data.get('company_name', None)
        if is_professional and not company_name:
            raise forms.ValidationError(
                _(u"Vous devez entrer le nom de votre société"))
        return company_name

    def clean_phones(self):
        phones = self.cleaned_data['phones']
        phone = self.cleaned_data['phones__phone']

        if not phones and not phone:
            raise forms.ValidationError(
                _(u"Vous devez spécifiez un numéro de téléphone"))
        return phones

    def clean(self):
        if self.errors:
            return self.cleaned_data

        if self.cleaned_data.get('card_number'):
            try:
                pm = PayboxManager()
                self.cleaned_data['masked_number'] = mask_card_number(
                    self.cleaned_data['card_number'])
                pm.authorize(self.cleaned_data['card_number'],
                             self.cleaned_data['expires'],
                             self.cleaned_data['cvv'], 1, 'verification')
            except PayboxException:
                raise forms.ValidationError(
                    _(u'La validation de votre carte a échoué.'))

        # testing passwords against each other:
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 != password2:
            msg = _(u"Vos mots de passe ne correspondent pas")
            self._errors['password1'] = [msg]
            self._errors['password2'] = [msg]
            del self.cleaned_data['password1']
            del self.cleaned_data['password2']

        return self.cleaned_data

    class Meta:
        fieldsets = [
            ('member', {
                'fields': [
                    'is_professional', 'company_name', 'username', 'password1',
                    'password2', 'first_name', 'last_name', 'avatar',
                    'godfather_email', 'date_of_birth', 'place_of_birth'
                ],
                'legend':
                'Vous'
            }),
            ('driver_info', {
                'fields': ['drivers_license_number', 'drivers_license_date'],
                'legend': _(u'Permis de conduire')
            }),
            ('contacts', {
                'fields': [
                    'addresses', 'addresses__address1', 'addresses__zipcode',
                    'addresses__city', 'addresses__country', 'phones',
                    'phones__phone'
                ],
                'legend':
                'Vos coordonnées'
            }),
            ('payment', {
                'fields': [
                    'cvv',
                    'expires',
                    'holder_name',
                    'card_number',
                ],
                'legend': 'Vos coordonnées bancaires'
            }),
        ]

    class_dict = fields.copy()
    class_dict.update({'instance': instance, 'Meta': Meta})
    form_class = type('MissingInformationForm', (BetterForm, ), class_dict)
    form_class.save = types.MethodType(save, None, form_class)
    form_class.clean = types.MethodType(clean, None, form_class)
    form_class.clean_username = types.MethodType(clean_username, None,
                                                 form_class)
    form_class.clean_phones = types.MethodType(clean_phones, None, form_class)
    form_class.clean_addresses = types.MethodType(clean_addresses, None,
                                                  form_class)
    form_class.clean_company_name = types.MethodType(clean_company_name, None,
                                                     form_class)
    return fields != {}, form_class
示例#15
0
    def get_default_fields(self):
        """
        Return all the fields that should be serialized for the model.
        """

        cls = self.opts.model
        assert cls is not None, \
                "Serializer class '%s' is missing 'model' Meta option" % self.__class__.__name__
        opts = get_concrete_model(cls)._meta
        ret = SortedDict()
        nested = bool(self.opts.depth)

        # Deal with adding the primary key field
        pk_field = opts.pk
        while pk_field.rel and pk_field.rel.parent_link:
            # If model is a child via multitable inheritance, use parent's pk
            pk_field = pk_field.rel.to._meta.pk

        field = self.get_pk_field(pk_field)
        if field:
            ret[pk_field.name] = field

        # Deal with forward relationships
        forward_rels = [field for field in opts.fields if field.serialize]
        forward_rels += [
            field for field in opts.many_to_many if field.serialize
        ]

        for model_field in forward_rels:
            has_through_model = False

            if model_field.rel:
                to_many = isinstance(model_field,
                                     models.fields.related.ManyToManyField)
                related_model = _resolve_model(model_field.rel.to)

                if to_many and not model_field.rel.through._meta.auto_created:
                    has_through_model = True

            if model_field.rel and nested:
                if len(inspect.getargspec(self.get_nested_field).args) == 2:
                    warnings.warn(
                        'The `get_nested_field(model_field)` call signature '
                        'is due to be deprecated. '
                        'Use `get_nested_field(model_field, related_model, '
                        'to_many) instead', PendingDeprecationWarning)
                    field = self.get_nested_field(model_field)
                else:
                    field = self.get_nested_field(model_field, related_model,
                                                  to_many)
            elif model_field.rel:
                if len(inspect.getargspec(self.get_nested_field).args) == 3:
                    warnings.warn(
                        'The `get_related_field(model_field, to_many)` call '
                        'signature is due to be deprecated. '
                        'Use `get_related_field(model_field, related_model, '
                        'to_many) instead', PendingDeprecationWarning)
                    field = self.get_related_field(model_field,
                                                   to_many=to_many)
                else:
                    field = self.get_related_field(model_field, related_model,
                                                   to_many)
            else:
                field = self.get_field(model_field)

            if field:
                if has_through_model:
                    field.read_only = True

                ret[model_field.name] = field

        # Deal with reverse relationships
        if not self.opts.fields:
            reverse_rels = []
        else:
            # Reverse relationships are only included if they are explicitly
            # present in the `fields` option on the serializer
            reverse_rels = opts.get_all_related_objects()
            reverse_rels += opts.get_all_related_many_to_many_objects()

        for relation in reverse_rels:
            accessor_name = relation.get_accessor_name()
            if not self.opts.fields or accessor_name not in self.opts.fields:
                continue
            related_model = relation.model
            to_many = relation.field.rel.multiple
            has_through_model = False
            is_m2m = isinstance(relation.field,
                                models.fields.related.ManyToManyField)

            if (is_m2m and hasattr(relation.field.rel, 'through')
                    and not relation.field.rel.through._meta.auto_created):
                has_through_model = True

            if nested:
                field = self.get_nested_field(None, related_model, to_many)
            else:
                field = self.get_related_field(None, related_model, to_many)

            if field:
                if has_through_model:
                    field.read_only = True

                ret[accessor_name] = field

        # Ensure that 'read_only_fields' is an iterable
        assert isinstance(
            self.opts.read_only_fields,
            (list, tuple)), '`read_only_fields` must be a list or tuple'

        # Add the `read_only` flag to any fields that have been specified
        # in the `read_only_fields` option
        for field_name in self.opts.read_only_fields:
            assert field_name not in self.base_fields.keys(), (
                "field '%s' on serializer '%s' specified in "
                "`read_only_fields`, but also added "
                "as an explicit field.  Remove it from `read_only_fields`." %
                (field_name, self.__class__.__name__))
            assert field_name in ret, (
                "Non-existant field '%s' specified in `read_only_fields` "
                "on serializer '%s'." % (field_name, self.__class__.__name__))
            ret[field_name].read_only = True

        # Ensure that 'write_only_fields' is an iterable
        assert isinstance(
            self.opts.write_only_fields,
            (list, tuple)), '`write_only_fields` must be a list or tuple'

        for field_name in self.opts.write_only_fields:
            assert field_name not in self.base_fields.keys(), (
                "field '%s' on serializer '%s' specified in "
                "`write_only_fields`, but also added "
                "as an explicit field.  Remove it from `write_only_fields`." %
                (field_name, self.__class__.__name__))
            assert field_name in ret, (
                "Non-existant field '%s' specified in `write_only_fields` "
                "on serializer '%s'." % (field_name, self.__class__.__name__))
            ret[field_name].write_only = True

        return ret
示例#16
0
    def __new__(mcs, name, bases, attrs):
        attrs["_meta"] = opts = TableOptions(attrs.get("Meta", None))
        # extract declared columns
        cols, remainder = [], {}
        for attr_name, attr in attrs.items():
            if isinstance(attr, columns.Column):
                cols.append((attr_name, attr))
            else:
                remainder[attr_name] = attr
        attrs = remainder

        cols.sort(key=lambda x: x[1].creation_counter)

        # If this class is subclassing other tables, add their fields as
        # well. Note that we loop over the bases in *reverse* - this is
        # necessary to preserve the correct order of columns.
        parent_columns = []
        for base in bases[::-1]:
            if hasattr(base, "base_columns"):
                parent_columns = list(
                    base.base_columns.items()) + parent_columns
        # Start with the parent columns
        attrs["base_columns"] = SortedDict(parent_columns)
        # Possibly add some generated columns based on a model
        if opts.model:
            extra = SortedDict()
            # honor Table.Meta.fields, fallback to model._meta.fields
            if opts.fields:
                # Each item in opts.fields is the name of a model field or a
                # normal attribute on the model
                for name in opts.fields:
                    try:
                        field = opts.model._meta.get_field(name)
                    except FieldDoesNotExist:
                        # if there's no such field in the model and
                        # it's a checkcolumn, don't create a plain column
                        column = attrs['base_columns'].get(name, None)
                        if column is None or not isinstance(
                                column, columns.CheckBoxColumn):
                            extra[name] = columns.Column()
                    else:
                        extra[name] = columns.library.column_for_field(field)

            else:
                for field in opts.model._meta.fields:
                    extra[field.name] = columns.library.column_for_field(field)
            attrs["base_columns"].update(extra)

        # Explicit columns override both parent and generated columns
        attrs["base_columns"].update(SortedDict(cols))
        # Apply any explicit exclude setting
        for exclusion in opts.exclude:
            if exclusion in attrs["base_columns"]:
                attrs["base_columns"].pop(exclusion)
        # Now reorder the columns based on explicit sequence
        if opts.sequence:
            opts.sequence.expand(attrs["base_columns"].keys())
            # Table's sequence defaults to sequence declared in Meta
            #attrs['_sequence'] = opts.sequence
            attrs["base_columns"] = SortedDict(
                ((x, attrs["base_columns"][x]) for x in opts.sequence))

        # set localize on columns
        for col_name in attrs["base_columns"].keys():
            localize_column = None
            if col_name in opts.localize:
                localize_column = True
            # unlocalize gets higher precedence
            if col_name in opts.unlocalize:
                localize_column = False

            if localize_column is not None:
                attrs["base_columns"][col_name].localize = localize_column

        return super(DeclarativeColumnsMetaclass,
                     mcs).__new__(mcs, name, bases, attrs)
示例#17
0
 def render_dictionary(self):
     return self.render_data(
         SortedDict([
             ('a', 'foo'),
             ('b', EgObject('bar')),
         ]))
示例#18
0
文件: models.py 项目: nanuxbe/feincms
        def register_templates(cls, *templates):
            """
            Register templates and add a ``template_key`` field to the model
            for saving the selected template::

                Page.register_templates({
                    'key': 'base',
                    'title': _('Standard template'),
                    'path': 'feincms_base.html',
                    'regions': (
                        ('main', _('Main content area')),
                        ('sidebar', _('Sidebar'), 'inherited'),
                        ),
                    }, {
                    'key': '2col',
                    'title': _('Template with two columns'),
                    'path': 'feincms_2col.html',
                    'regions': (
                        ('col1', _('Column one')),
                        ('col2', _('Column two')),
                        ('sidebar', _('Sidebar'), 'inherited'),
                        ),
                    })
            """

            if not hasattr(cls, '_feincms_templates'):
                cls._feincms_templates = SortedDict()
                cls.TEMPLATES_CHOICES = []

            instances = cls._feincms_templates

            for template in templates:
                if not isinstance(template, Template):
                    template = Template(**template)

                instances[template.key] = template

            try:
                field = next(
                    iter(field for field in cls._meta.local_fields
                         if field.name == 'template_key'))
            except (StopIteration, ):
                cls.add_to_class(
                    'template_key',
                    models.CharField(_('template'), max_length=255,
                                     choices=()))
                field = next(
                    iter(field for field in cls._meta.local_fields
                         if field.name == 'template_key'))

                def _template(self):
                    ensure_completely_loaded()

                    try:
                        return self._feincms_templates[self.template_key]
                    except KeyError:
                        # return first template as a fallback if the template
                        # has changed in-between
                        return self._feincms_templates[list(
                            self._feincms_templates.keys())[0]]

                cls.template = property(_template)

            cls.TEMPLATE_CHOICES = field._choices = [(
                template_.key,
                template_.title,
            ) for template_ in cls._feincms_templates.values()]
            field.default = field.choices[0][0]

            # Build a set of all regions used anywhere
            cls._feincms_all_regions = set()
            for template in cls._feincms_templates.values():
                cls._feincms_all_regions.update(template.regions)
示例#19
0
 def _create_bound_field_dict(self):
     return SortedDict(
         (field_name, BoundField(self, field, field_name))
         for (field_name, field) in self.fields.items()
     )
 def bound_columns(self):
     if not getattr(self, '_bound_columns', None):
         self._bound_columns = SortedDict([
             (name, BoundColumn(self, column, name)) \
             for name, column in self.columns.items()])
     return self._bound_columns
示例#21
0
文件: config.py 项目: ESA-MInv/minv
 def get_section_dict(self, section, ordered=False):
     try:
         items = self._config.items(section)
         return SortedDict(items) if ordered else dict(items)
     except NoSectionError:
         return {}
 def __init__(self, data=None, name=''):
     self.columns = SortedDict(
         self.base_columns.items())  #deepcopy(self.base_columns)
示例#23
0
    def get_data(self):
        marker = self.request.GET.get(
            project_tables.InstancesTable._meta.pagination_param, None)
        # Gather our instances
        try:
            instances, self._more = api.nova.server_list(
                self.request,
                search_opts={'marker': marker,
                             'paginate': True})
        except Exception:
            self._more = False
            instances = []
            exceptions.handle(self.request,
                              _('Unable to retrieve instances.'))

        if instances:
            try:
                api.network.servers_update_addresses(self.request, instances)
            except Exception:
                exceptions.handle(
                    self.request,
                    message=_('Unable to retrieve IP addresses from Neutron.'),
                    ignore=True)

            # Gather our flavors and images and correlate our instances to them
            try:
                flavors = api.nova.flavor_list(self.request)
            except Exception:
                flavors = []
                exceptions.handle(self.request, ignore=True)

            try:
                # TODO(gabriel): Handle pagination.
                images, more = api.glance.image_list_detailed(self.request)
            except Exception:
                images = []
                exceptions.handle(self.request, ignore=True)

            full_flavors = SortedDict([(str(flavor.id), flavor)
                                       for flavor in flavors])
            image_map = SortedDict([(str(image.id), image)
                                    for image in images])

            # Loop through instances to get flavor info.
            for instance in instances:
                if hasattr(instance, 'image'):
                    # Instance from image returns dict
                    if isinstance(instance.image, dict):
                        if instance.image.get('id') in image_map:
                            instance.image = image_map[instance.image['id']]
                    else:
                        # Instance from volume returns a string
                        instance.image = {'name':
                                instance.image if instance.image else _("-")}

                try:
                    flavor_id = instance.flavor["id"]
                    if flavor_id in full_flavors:
                        instance.full_flavor = full_flavors[flavor_id]
                    else:
                        # If the flavor_id is not in full_flavors list,
                        # get it via nova api.
                        instance.full_flavor = api.nova.flavor_get(
                            self.request, flavor_id)
                except Exception:
                    msg = _('Unable to retrieve instance size information.')
                    exceptions.handle(self.request, msg)
        return instances
示例#24
0
    def handle(self, *app_labels, **options):
        from django.db.models import get_app, get_apps, get_models, get_model

        format = options.get('format', 'json')
        indent = options.get('indent', None)
        using = options.get('database', DEFAULT_DB_ALIAS)
        connection = connections[using]
        excludes = options.get('exclude', [])
        show_traceback = options.get('traceback', False)
        use_natural_keys = options.get('use_natural_keys', False)
        use_base_manager = options.get('use_base_manager', False)

        excluded_apps = set()
        excluded_models = set()
        for exclude in excludes:
            if '.' in exclude:
                app_label, model_name = exclude.split('.', 1)
                model_obj = get_model(app_label, model_name)
                if not model_obj:
                    raise CommandError('Unknown model in excludes: %s' %
                                       exclude)
                excluded_models.add(model_obj)
            else:
                try:
                    app_obj = get_app(exclude)
                    excluded_apps.add(app_obj)
                except ImproperlyConfigured:
                    raise CommandError('Unknown app in excludes: %s' % exclude)

        if len(app_labels) == 0:
            app_list = SortedDict(
                (app, None) for app in get_apps() if app not in excluded_apps)
        else:
            app_list = SortedDict()
            for label in app_labels:
                try:
                    app_label, model_label = label.split('.')
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" %
                                           app_label)
                    if app in excluded_apps:
                        continue
                    model = get_model(app_label, model_label)
                    if model is None:
                        raise CommandError("Unknown model: %s.%s" %
                                           (app_label, model_label))

                    if app in app_list.keys():
                        if app_list[app] and model not in app_list[app]:
                            app_list[app].append(model)
                    else:
                        app_list[app] = [model]
                except ValueError:
                    # This is just an app - no model qualifier
                    app_label = label
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" %
                                           app_label)
                    if app in excluded_apps:
                        continue
                    app_list[app] = None

        # Check that the serialization format exists; this is a shortcut to
        # avoid collating all the objects and _then_ failing.
        if format not in serializers.get_public_serializer_formats():
            raise CommandError("Unknown serialization format: %s" % format)

        try:
            serializers.get_serializer(format)
        except KeyError:
            raise CommandError("Unknown serialization format: %s" % format)

        # Now collate the objects to be serialized.
        objects = []
        for model in sort_dependencies(app_list.items()):
            if model in excluded_models:
                continue
            if not model._meta.proxy and router.allow_syncdb(using, model):
                if use_base_manager:
                    objects.extend(model._base_manager.using(using).all())
                else:
                    objects.extend(model._default_manager.using(using).all())

        try:
            return serializers.serialize(format,
                                         objects,
                                         indent=indent,
                                         use_natural_keys=use_natural_keys)
        except Exception, e:
            if show_traceback:
                raise
            raise CommandError("Unable to serialize database: %s" % e)
示例#25
0
def get_model_fields(model, m2m=False):
    """
    Given a model class, will return the dict of name: field_constructor
    mappings.
    """
    tree = get_model_tree(model)
    if tree is None:
        return None
    possible_field_defs = tree.find(
        "^ > classdef > suite > stmt > simple_stmt > small_stmt > expr_stmt")
    field_defs = {}

    # Get aliases, ready for alias fixing (#134)
    try:
        aliases = aliased_models(models.get_app(model._meta.app_label))
    except ImproperlyConfigured:
        aliases = {}

    # Go through all the found defns, and try to parse them
    for pfd in possible_field_defs:
        field = extract_field(pfd)
        if field:
            field_defs[field[0]] = field[1:]

    inherited_fields = {}
    # Go through all bases (that are themselves models, but not Model)
    for base in model.__bases__:
        if base != models.Model and issubclass(base, models.Model):
            inherited_fields.update(get_model_fields(base, m2m))

    # Now, go through all the fields and try to get their definition
    source = model._meta.local_fields[:]
    if m2m:
        source += model._meta.local_many_to_many
    fields = SortedDict()
    for field in source:
        # Get its name
        fieldname = field.name
        if isinstance(field,
                      (models.related.RelatedObject, generic.GenericRel)):
            continue
        # Now, try to get the defn
        if fieldname in field_defs:
            fields[fieldname] = field_defs[fieldname]
        # Try the South definition workaround?
        elif hasattr(field, 'south_field_triple'):
            fields[fieldname] = field.south_field_triple()
        elif hasattr(field, 'south_field_definition'):
            print "Your custom field %s provides the outdated south_field_definition method.\nPlease consider implementing south_field_triple too; it's more reliably evaluated." % field
            fields[fieldname] = field.south_field_definition()
        # Try a parent?
        elif fieldname in inherited_fields:
            fields[fieldname] = inherited_fields[fieldname]
        # Is it a _ptr?
        elif fieldname.endswith("_ptr"):
            fields[fieldname] = ("models.OneToOneField", [
                "orm['%s.%s']" %
                (field.rel.to._meta.app_label, field.rel.to._meta.object_name)
            ], {})
        # Try a default for 'id'.
        elif fieldname == "id":
            fields[fieldname] = ("models.AutoField", [], {
                "primary_key": "True"
            })
        else:
            fields[fieldname] = None

    # Now, try seeing if we can resolve the values of defaults, and fix aliases.
    for field, defn in fields.items():

        if not isinstance(defn, (list, tuple)):
            continue  # We don't have a defn for this one, or it's a string

        # Fix aliases if we can (#134)
        for i, arg in enumerate(defn[1]):
            if arg in aliases:
                defn[1][i] = aliases[arg]

        # Fix defaults if we can
        for arg, val in defn[2].items():
            if arg in ['default']:
                try:
                    # Evaluate it in a close-to-real fake model context
                    real_val = eval(
                        val,
                        __import__(model.__module__, {}, {}, ['']).__dict__,
                        model.__dict__)
                # If we can't resolve it, stick it in verbatim
                except:
                    pass  # TODO: Raise nice error here?
                # Hm, OK, we got a value. Callables are not frozen (see #132, #135)
                else:
                    if callable(real_val):
                        # HACK
                        # However, if it's datetime.now, etc., that's special
                        for datetime_key in datetime.datetime.__dict__.keys():
                            # No, you can't use __dict__.values. It's different.
                            dtm = getattr(datetime.datetime, datetime_key)
                            if real_val == dtm:
                                if not val.startswith("datetime.datetime"):
                                    defn[2][arg] = "datetime." + val
                                break
                    else:
                        defn[2][arg] = repr(real_val)

    return fields
示例#26
0
def get_enabled_major_login_providers():
    """returns a dictionary with data about login providers
    whose icons are to be shown in large format

    disabled providers are excluded
    
    items of the dictionary are dictionaries with keys:

    * name
    * display_name
    * icon_media_path (relative to /media directory)
    * type (oauth|openid-direct|openid-generic|openid-username|password)

    Fields dependent on type of the login provider type
    ---------------------------------------------------

    Password (type = password) - login provider using login name and password:

    * extra_token_name - a phrase describing what the login name and the
      password are from
    * create_password_prompt - a phrase prompting to create an account
    * change_password_prompt - a phrase prompting to change password

    OpenID (type = openid) - Provider of login using the OpenID protocol

    * openid_endpoint (required for type=openid|openid-username)
      for type openid-username - the string must have %(username)s
      format variable, plain string url otherwise
    * extra_token_name - required for type=openid-username
      describes name of required extra token - e.g. "XYZ user name"

    OAuth2 (type = oauth)

    * request_token_url - url to initiate OAuth2 protocol with the resource
    * access_token_url - url to access users data on the resource via OAuth2
    * authorize_url - url at which user can authorize the app to access a resource
    * authenticate_url - url to authenticate user (lower privilege than authorize)
    * get_user_id_function - a function that returns user id from data dictionary
      containing: response to the access token url & consumer_key
      and consumer secret. The purpose of this function is to hide the differences
      between the ways user id is accessed from the different OAuth providers
    """
    data = SortedDict()

    if use_password_login():
        site_name = askbot_settings.APP_SHORT_NAME
        prompt = _('%(site)s user name and password') % {'site': site_name}
        data['local'] = {
            'name': 'local',
            'display_name': site_name,
            'extra_token_name': prompt,
            'type': 'password',
            'create_password_prompt': _('Create a password-protected account'),
            'change_password_prompt': _('Change your password'),
            'icon_media_path': askbot_settings.LOCAL_LOGIN_ICON,
            'password_changeable': True
        }

    if askbot_settings.SIGNIN_CUSTOM_OPENID_ENABLED:
        context_dict = {'login_name': askbot_settings.SIGNIN_CUSTOM_OPENID_NAME}
        data['custom_openid'] = {
            'name': 'custom_openid',
            'display_name': askbot_settings.SIGNIN_CUSTOM_OPENID_NAME,
            'type': askbot_settings.SIGNIN_CUSTOM_OPENID_MODE,
            'icon_media_path': askbot_settings.SIGNIN_CUSTOM_OPENID_LOGIN_BUTTON,
            'tooltip_text': _('Login with %(login_name)s') % context_dict,
            'openid_endpoint': askbot_settings.SIGNIN_CUSTOM_OPENID_ENDPOINT,
            'extra_token_name': _('%(login_name)s username') % context_dict
        }

    def get_facebook_user_id(client):
        """returns facebook user id given the access token"""
        profile = client.request('me')
        return profile['id']

    if askbot_settings.FACEBOOK_KEY and askbot_settings.FACEBOOK_SECRET:
        data['facebook'] = {
            'name': 'facebook',
            'display_name': 'Facebook',
            'type': 'oauth2',
            'auth_endpoint': 'https://www.facebook.com/dialog/oauth/',
            'token_endpoint': 'https://graph.facebook.com/oauth/access_token',
            'resource_endpoint': 'https://graph.facebook.com/',
            'icon_media_path': '/jquery-openid/images/facebook.gif',
            'get_user_id_function': get_facebook_user_id,
            'response_parser': lambda data: dict(urlparse.parse_qsl(data)),
            'scope': ['email',],

        }
    if askbot_settings.TWITTER_KEY and askbot_settings.TWITTER_SECRET:
        data['twitter'] = {
            'name': 'twitter',
            'display_name': 'Twitter',
            'type': 'oauth',
            'request_token_url': 'https://api.twitter.com/oauth/request_token',
            'access_token_url': 'https://api.twitter.com/oauth/access_token',
            'authorize_url': 'https://api.twitter.com/oauth/authorize',
            'authenticate_url': 'https://api.twitter.com/oauth/authenticate',
            'get_user_id_url': 'https://twitter.com/account/verify_credentials.json',
            'icon_media_path': '/jquery-openid/images/twitter.gif',
            'get_user_id_function': lambda data: data['user_id'],
        }
    def get_identica_user_id(data):
        consumer = oauth.Consumer(data['consumer_key'], data['consumer_secret'])
        token = oauth.Token(data['oauth_token'], data['oauth_token_secret'])
        client = oauth.Client(consumer, token=token)
        url = 'https://identi.ca/api/account/verify_credentials.json'
        response, content = client.request(url, 'GET')
        json = simplejson.loads(content)
        return json['id']
    if askbot_settings.IDENTICA_KEY and askbot_settings.IDENTICA_SECRET:
        data['identi.ca'] = {
            'name': 'identi.ca',
            'display_name': 'identi.ca',
            'type': 'oauth',
            'request_token_url': 'https://identi.ca/api/oauth/request_token',
            'access_token_url': 'https://identi.ca/api/oauth/access_token',
            'authorize_url': 'https://identi.ca/api/oauth/authorize',
            'authenticate_url': 'https://identi.ca/api/oauth/authorize',
            'icon_media_path': '/jquery-openid/images/identica.png',
            'get_user_id_function': get_identica_user_id,
        }
    def get_linked_in_user_id(data):
        consumer = oauth.Consumer(data['consumer_key'], data['consumer_secret'])
        token = oauth.Token(data['oauth_token'], data['oauth_token_secret'])
        client = oauth.Client(consumer, token=token)
        url = 'https://api.linkedin.com/v1/people/~:(first-name,last-name,id)'
        response, content = client.request(url, 'GET')
        if response['status'] == '200':
            id_re = re.compile(r'<id>([^<]+)</id>')
            matches = id_re.search(content)
            if matches:
                return matches.group(1)
        raise OAuthError()

    if askbot_settings.SIGNIN_WORDPRESS_SITE_ENABLED and askbot_settings.WORDPRESS_SITE_URL:
        data['wordpress_site'] = {
            'name': 'wordpress_site',
            'display_name': 'Self hosted wordpress blog', #need to be added as setting.
            'icon_media_path': askbot_settings.WORDPRESS_SITE_ICON,
            'type': 'wordpress_site',
        }
    if askbot_settings.LINKEDIN_KEY and askbot_settings.LINKEDIN_SECRET:
        data['linkedin'] = {
            'name': 'linkedin',
            'display_name': 'LinkedIn',
            'type': 'oauth',
            'request_token_url': 'https://api.linkedin.com/uas/oauth/requestToken',
            'access_token_url': 'https://api.linkedin.com/uas/oauth/accessToken',
            'authorize_url': 'https://www.linkedin.com/uas/oauth/authorize',
            'authenticate_url': 'https://www.linkedin.com/uas/oauth/authenticate',
            'icon_media_path': '/jquery-openid/images/linkedin.gif',
            'get_user_id_function': get_linked_in_user_id
        }
    data['google'] = {
        'name': 'google',
        'display_name': 'Google',
        'type': 'openid-direct',
        'icon_media_path': '/jquery-openid/images/google.gif',
        'openid_endpoint': 'https://www.google.com/accounts/o8/id',
    }
    data['mozilla-persona'] = {
        'name': 'mozilla-persona',
        'display_name': 'Mozilla Persona',
        'type': 'mozilla-persona',
        'icon_media_path': '/jquery-openid/images/mozilla-persona.gif',
    }
    data['yahoo'] = {
        'name': 'yahoo',
        'display_name': 'Yahoo',
        'type': 'openid-direct',
        'icon_media_path': '/jquery-openid/images/yahoo.gif',
        'tooltip_text': _('Sign in with Yahoo'),
        'openid_endpoint': 'http://yahoo.com',
    }
    data['aol'] = {
        'name': 'aol',
        'display_name': 'AOL',
        'type': 'openid-username',
        'extra_token_name': _('AOL screen name'),
        'icon_media_path': '/jquery-openid/images/aol.gif',
        'openid_endpoint': 'http://openid.aol.com/%(username)s'
    }
    data['launchpad'] = {
        'name': 'launchpad',
        'display_name': 'LaunchPad',
        'type': 'openid-direct',
        'icon_media_path': '/jquery-openid/images/launchpad.gif',
        'tooltip_text': _('Sign in with LaunchPad'),
        'openid_endpoint': 'https://login.launchpad.net/'
    }
    data['openid'] = {
        'name': 'openid',
        'display_name': 'OpenID',
        'type': 'openid-generic',
        'extra_token_name': _('OpenID url'),
        'icon_media_path': '/jquery-openid/images/openid.gif',
        'openid_endpoint': None,
    }
    return filter_enabled_providers(data)
示例#27
0
    def handle(self, *app_labels, **options):
        from django.db.models import get_app, get_apps, get_model

        output_folder = options.get('output_folder')
        print "Output folder:", output_folder
        print "NOTE: See --output-folder option"
        max_records_per_chunk = options.get('max_records_per_chunk')
        format = options.get('format')
        indent = options.get('indent')
        using = options.get('database')
        excludes = options.get('exclude')
        show_traceback = options.get('traceback')
        use_natural_keys = options.get('use_natural_keys')
        use_base_manager = options.get('use_base_manager')

        excluded_apps = set()
        excluded_models = set()
        for exclude in excludes:
            if '.' in exclude:
                app_label, model_name = exclude.split('.', 1)
                model_obj = get_model(app_label, model_name)
                if not model_obj:
                    raise CommandError('Unknown model in excludes: %s' % exclude)
                excluded_models.add(model_obj)
            else:
                try:
                    app_obj = get_app(exclude)
                    excluded_apps.add(app_obj)
                except ImproperlyConfigured:
                    raise CommandError('Unknown app in excludes: %s' % exclude)

        if len(app_labels) == 0:
            app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
        else:
            app_list = SortedDict()
            for label in app_labels:
                try:
                    app_label, model_label = label.split('.')
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app in excluded_apps:
                        continue
                    model = get_model(app_label, model_label)
                    if model is None:
                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))

                    if app in app_list.keys():
                        if app_list[app] and model not in app_list[app]:
                            app_list[app].append(model)
                    else:
                        app_list[app] = [model]
                except ValueError:
                    # This is just an app - no model qualifier
                    app_label = label
                    try:
                        app = get_app(app_label)
                    except ImproperlyConfigured:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app in excluded_apps:
                        continue
                    app_list[app] = None

        # Check that the serialization format exists; this is a shortcut to
        # avoid collating all the objects and _then_ failing.
        if format not in serializers.get_public_serializer_formats():
            raise CommandError("Unknown serialization format: %s" % format)

        try:
            serializers.get_serializer(format)
        except KeyError:
            raise CommandError("Unknown serialization format: %s" % format)

        # Now collate the objects to be serialized.
        objects = []
        model_count = 1000
        chunk_count = 1000
        for model in sort_dependencies(app_list.items()):
            model_count += 1
            if model in excluded_models:
                continue
            if not model._meta.proxy and router.allow_migrate(using, model):
                if use_base_manager:
                    objects.extend(model._base_manager.using(using).all())
                else:
                    items_total = model._default_manager.using(using).count()
                    chunks_total = (items_total / max_records_per_chunk) +1
                    for chunk_num in range(0, chunks_total):
                        output_objects = model._default_manager.using(using).all().order_by('id')[chunk_num*max_records_per_chunk:(chunk_num+1)*max_records_per_chunk]
                        if output_objects:
                            chunk_count += 1
                            dump_file_name = output_folder + "/%d_%d.json" % (model_count, chunk_count)
                            print "Dumping file: %s [%d]" % (dump_file_name, chunks_total)
                            output = serializers.serialize(format, output_objects, indent=indent,
                                        use_natural_keys=use_natural_keys)
                            with open(dump_file_name, "w") as dumpfile:
                                dumpfile.write(output)
        return ''
示例#28
0
def get_enabled_minor_login_providers():
    """same as get_enabled_major_login_providers
    but those that are to be displayed with small buttons

    disabled providers are excluded

    structure of dictionary values is the same as in get_enabled_major_login_providers
    """
    data = SortedDict()
    #data['myopenid'] = {
    #    'name': 'myopenid',
    #    'display_name': 'MyOpenid',
    #    'type': 'openid-username',
    #    'extra_token_name': _('MyOpenid user name'),
    #    'icon_media_path': '/jquery-openid/images/myopenid-2.png',
    #    'openid_endpoint': 'http://%(username)s.myopenid.com'
    #}
    data['flickr'] = {
        'name': 'flickr',
        'display_name': 'Flickr',
        'type': 'openid-username',
        'extra_token_name': _('Flickr user name'),
        'icon_media_path': '/jquery-openid/images/flickr.png',
        'openid_endpoint': 'http://flickr.com/%(username)s/'
    }
    data['technorati'] = {
        'name': 'technorati',
        'display_name': 'Technorati',
        'type': 'openid-username',
        'extra_token_name': _('Technorati user name'),
        'icon_media_path': '/jquery-openid/images/technorati-1.png',
        'openid_endpoint': 'http://technorati.com/people/technorati/%(username)s/'
    }
    data['wordpress'] = {
        'name': 'wordpress',
        'display_name': 'WordPress',
        'type': 'openid-username',
        'extra_token_name': _('WordPress blog name'),
        'icon_media_path': '/jquery-openid/images/wordpress.png',
        'openid_endpoint': 'http://%(username)s.wordpress.com'
    }
    data['blogger'] = {
        'name': 'blogger',
        'display_name': 'Blogger',
        'type': 'openid-username',
        'extra_token_name': _('Blogger blog name'),
        'icon_media_path': '/jquery-openid/images/blogger-1.png',
        'openid_endpoint': 'http://%(username)s.blogspot.com'
    }
    data['livejournal'] = {
        'name': 'livejournal',
        'display_name': 'LiveJournal',
        'type': 'openid-username',
        'extra_token_name': _('LiveJournal blog name'),
        'icon_media_path': '/jquery-openid/images/livejournal-1.png',
        'openid_endpoint': 'http://%(username)s.livejournal.com'
    }
    data['claimid'] = {
        'name': 'claimid',
        'display_name': 'ClaimID',
        'type': 'openid-username',
        'extra_token_name': _('ClaimID user name'),
        'icon_media_path': '/jquery-openid/images/claimid-0.png',
        'openid_endpoint': 'http://claimid.com/%(username)s/'
    }
    data['vidoop'] = {
        'name': 'vidoop',
        'display_name': 'Vidoop',
        'type': 'openid-username',
        'extra_token_name': _('Vidoop user name'),
        'icon_media_path': '/jquery-openid/images/vidoop.png',
        'openid_endpoint': 'http://%(username)s.myvidoop.com/'
    }
    data['verisign'] = {
        'name': 'verisign',
        'display_name': 'Verisign',
        'type': 'openid-username',
        'extra_token_name': _('Verisign user name'),
        'icon_media_path': '/jquery-openid/images/verisign-2.png',
        'openid_endpoint': 'http://%(username)s.pip.verisignlabs.com/'
    }
    return filter_enabled_providers(data)
示例#29
0
                 '    engdoc.id=engvisits.document_id '
                 '    AND engvisits.period=%s ' + extra_joins +
                 'WHERE engdoc.category = %s '
                 '    AND engdoc.locale = %s '
                 '    AND NOT engdoc.is_archived '
                 'ORDER BY engvisits.visits DESC ' + self._limit_clause(max))

        return query, params

    def _format_row(self, row):
        return _format_row_with_out_of_dateness(self.locale, *row)


# L10n Dashboard tables that have their own whole-page views:
L10N_READOUTS = SortedDict((t.slug, t) for t in [
    MostVisitedTranslationsReadout, TemplateTranslationsReadout,
    UnreviewedReadout
])

# Contributors ones:
CONTRIBUTOR_READOUTS = SortedDict((t.slug, t) for t in [
    MostVisitedDefaultLanguageReadout, TemplateReadout, HowToContributeReadout,
    AdministrationReadout, UnreviewedReadout, NeedsChangesReadout,
    UnreadyForLocalizationReadout, UnhelpfulReadout
])

# All:
READOUTS = L10N_READOUTS.copy()
READOUTS.update(CONTRIBUTOR_READOUTS)

GROUP_L10N_READOUTS = SortedDict(
    (t.slug, t) for t in [MostVisitedTranslationsReadout, UnreviewedReadout])
示例#30
0
from django.utils import six
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
from djblets.configforms.pages import ConfigPage

from reviewboard.accounts.forms.pages import (AccountSettingsForm,
                                              APITokensForm,
                                              ChangePasswordForm,
                                              ProfileForm,
                                              GroupsForm)


_populated = False
_registered_form_classes = {}
_registered_page_classes = SortedDict()


class AccountPage(ConfigPage):
    """Base class for a page of forms in the My Account page.

    Each AccountPage is represented in the My Account page by an entry
    in the navigation sidebar. When the user has navigated to that page,
    any forms shown on the page will be displayed.

    Extensions can provide custom pages in order to offer per-user
    customization.
    """

    @classmethod
    def add_form(cls, form_cls):