コード例 #1
0
ファイル: models.py プロジェクト: sunlightlabs/tcamp
class Session(models.Model):
    title = models.CharField(max_length=102)
    slug = models.SlugField(db_index=True)
    description = MarkupField(blank=True, markup_type='markdown', help_text="Markdown is supported.")
    speakers = JSONField(help_text='An array of objects. Each must contain a "name" attribute', blank=True, default='[]', db_index=True)
    extra_data = JSONField(blank=True, default='{}')
    tags = TaggableManager(blank=True, help_text="Help us schedule your session so that it doesn't conflict with other sessions around the same topics. Some example tags: Open data, International, Federal, State, Parliamentary Monitoring, Social Media, Design, Lobbying.")
    auto_tags = TaggableManager(blank=True, through=AutoTags)
    auto_tags.rel.related_name = '+'
    user_notes = models.TextField(blank=True, default='', help_text='Note in this space if you need to request a specific timeslot, or make sure you have a projector, etc. We can\'t make guarantees about anything, but we\'ll do our best.')
    hashtag = models.CharField(max_length=140, blank=True, null=True, help_text="Help others find and share info about your session! Include the '#'.")

    is_public = models.BooleanField(default=False, db_index=True)
    has_notes = models.BooleanField(default=True)
    notes_slug = models.SlugField(blank=True, help_text="Set this to override the default slug (i.e., If you want more than one session to have the same pad.")

    event = models.ForeignKey(Event, related_name='sessions')
    location = models.ForeignKey(Location, blank=True, null=True, related_name='sessions')
    start_time = models.DateTimeField(blank=True, null=True, db_index=True)
    end_time = models.DateTimeField(blank=True, null=True, db_index=True)

    admin_notes = models.TextField(blank=True, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_by = models.ForeignKey(User, blank=True, null=True, related_name="approved_sked_sessions")

    objects = SessionManager()

    class Meta:
        unique_together = (('event', 'slug'), )
        ordering = ('-event__start_date', 'start_time', )

    def __unicode__(self):
        return u"%s at %s" % (self.title, self.event)

    def get_absolute_url(self):
        url = reverse('sked:session_detail', kwargs={
            'event_slug': self.event.slug,
            'slug': self.slug,
        })

        return url

    def get_edit_url(self):
        url = reverse('sked:edit_session', kwargs={
            'event_slug': self.event.slug,
            'slug': self.slug,
        })

        return url

    def save(self, *args, **kwargs):
        # get the old instance for dirty tracking
        try:
            old = Session.objects.get(pk=self.id)
        except Session.DoesNotExist, AttributeError:
            old = None

        # create a slug if doesn't exist
        if not self.slug:
            self.slug = slugify(self.title)[:50].rstrip('-')
            normalized_slug = re.sub(r'[\d]+$', '', self.slug)
            count = 0
            while Session.objects.filter(slug=self.slug,
                                         event=self.event).count():
                count += 1
                self.slug = '%s%s' % (normalized_slug, count)

        # set the right end time if it should be set
        if self.start_time and (not self.end_time or
                                (old.start_time != self.start_time and
                                 old.end_time == self.end_time)):
            self.end_time = self.start_time + self.event.session_length

        super(Session, self).save(*args, **kwargs)
コード例 #2
0
class Profile(TimeStampedModel):
    """
    Stores extra information about a user or DDL member.
    """

    user = models.OneToOneField('auth.User', editable=False)
    email_hash = models.CharField(max_length=32, editable=False)
    organization = models.CharField(max_length=255, **nullable)
    location = models.CharField(max_length=255, **nullable)
    biography = MarkupField(markup_type='markdown',
                            help_text='Edit in Markdown',
                            **nullable)
    twitter = models.CharField(max_length=100, **nullable)
    linkedin = models.URLField(**nullable)

    class Meta:
        db_table = 'member_profiles'

    @property
    def full_name(self):
        return self.user.get_full_name()

    @property
    def full_email(self):
        email = u"{} <{}>".format(self.full_name, self.user.email)
        return email.strip()

    @property
    def gravatar(self):
        return self.get_gravatar_url()

    @property
    def gravatar_icon(self):
        return self.get_gravatar_url(size=settings.GRAVATAR_ICON_SIZE)

    @property
    def gravatar_badge(self):
        return self.get_gravatar_url(size=64)

    def get_gravatar_url(self, size=None, default=None):
        """
        Comptues the gravatar url from an email address
        """
        size = size or settings.GRAVATAR_DEFAULT_SIZE
        default = default or settings.GRAVATAR_DEFAULT_IMAGE
        params = urllib.parse.urlencode({'d': default, 's': str(size)})

        return "http://www.gravatar.com/avatar/{}?{}".format(
            self.email_hash, params)

    def get_api_detail_url(self):
        """
        Returns the API detail endpoint for the object
        """
        return reverse('api:user-detail', args=(self.user.pk, ))

    def get_absolute_url(self):
        """
        Returns the detail view url for the object
        """
        return reverse('member:detail', args=(self.user.username, ))

    def __str__(self):
        return self.full_email
コード例 #3
0
class Package(BaseModel):

    title = models.CharField(_("Title"), max_length="100")
    slug = models.SlugField(
        _("Slug"),
        help_text=
        "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens. Values will be converted to lowercase.",
        unique=True)
    category = models.ManyToManyField(Category,
                                      verbose_name="Installation",
                                      blank=True)
    repo_description = models.TextField(_("Repo Description"), blank=True)
    repo_url = models.URLField(_("repo URL"),
                               help_text=repo_url_help_text,
                               blank=True,
                               unique=True)
    repo_watchers = models.IntegerField(_("Stars"), default=0)
    repo_forks = models.IntegerField(_("repo forks"), default=0)
    pypi_url = models.CharField(_("PyPI slug"),
                                max_length=255,
                                help_text=pypi_url_help_text,
                                blank=True,
                                default='')
    pypi_downloads = models.IntegerField(_("Pypi downloads"), default=0)
    pypi_description = MarkupField(_('text'),
                                   blank=True,
                                   default='',
                                   default_markup_type='restructuredtext')
    participants = models.TextField(
        _("Participants"),
        help_text="List of collaborats/participants on the project",
        blank=True)
    usage = models.ManyToManyField(User, blank=True)
    created_by = models.ForeignKey(User,
                                   blank=True,
                                   null=True,
                                   related_name="creator",
                                   on_delete=models.SET_NULL)
    last_modified_by = models.ForeignKey(User,
                                         blank=True,
                                         null=True,
                                         related_name="modifier",
                                         on_delete=models.SET_NULL)
    last_fetched = models.DateTimeField(blank=True,
                                        null=True,
                                        default=timezone.now)
    documentation_url = models.URLField(_("Documentation URL"),
                                        blank=True,
                                        null=True,
                                        default="")

    commit_list = models.TextField(_("Commit List"), blank=True)
    show_pypi = models.BooleanField(_("Show pypi stats & version"),
                                    default=True)

    @property
    def description(self):
        from markupfield.markup import render_rest
        if self.repo_description:
            return render_rest(self.repo_description)
        return self.pypi_description

    @property
    def pypi_name(self):
        """ return the pypi name of a package"""

        if not self.pypi_url.strip():
            return ""

        name = self.pypi_url.replace("http://pypi.python.org/pypi/", "")
        if "/" in name:
            return name[:name.index("/")]
        return name

    def last_updated(self):
        cache_name = self.cache_namer(self.last_updated)
        last_commit = cache.get(cache_name)
        if last_commit is not None:
            return last_commit
        try:
            last_commit = self.commit_set.latest('commit_date').commit_date
            if last_commit:
                cache.set(cache_name, last_commit)
                return last_commit
        except ObjectDoesNotExist:
            last_commit = None

        return last_commit

    @property
    def repo(self):
        return get_repo_for_repo_url(self.repo_url)

    @property
    def active_examples(self):
        return self.packageexample_set.filter(active=True)

    @property
    def license_latest(self):
        try:
            return self.version_set.latest().license
        except Version.DoesNotExist:
            return "UNKNOWN"

    def repo_name(self):
        return re.sub(self.repo.url_regex, '', self.repo_url)

    def repo_info(self):
        return dict(
            username=self.repo_name().split('/')[0],
            repo_name=self.repo_name().split('/')[1],
        )

    def participant_list(self):

        return self.participants.split(',')

    def get_usage_count(self):
        return self.usage.count()

    def commits_over_52(self):
        cache_name = self.cache_namer(self.commits_over_52)
        value = cache.get(cache_name)
        if value is not None:
            return value
        now = timezone.now()
        commits = self.commit_set.filter(commit_date__gt=now -
                                         timedelta(weeks=52), ).values_list(
                                             'commit_date', flat=True)

        weeks = [0] * 52
        for cdate in commits:
            age_weeks = (now - cdate).days // 7
            if age_weeks < 52:
                weeks[age_weeks] += 1

        value = ','.join(map(str, reversed(weeks)))
        cache.set(cache_name, value)
        return value

    def fetch_pypi_data(self, *args, **kwargs):
        # Get the releases from pypi
        if self.pypi_url.strip(
        ) and self.pypi_url != "http://pypi.python.org/pypi/":

            url = "https://pypi.python.org/pypi/{0}/json".format(
                self.pypi_name)
            response = requests.get(url)
            if settings.DEBUG:
                if response.status_code not in (200, 404):
                    print("BOOM!")
                    print(self, response.status_code)
            if response.status_code == 404:
                if settings.DEBUG:
                    print("BOOM!")
                    print(self, response.status_code)
                return False
            release = json.loads(response.content)
            info = release['info']

            version, created = Version.objects.get_or_create(
                package=self, number=info['version'])

            # add to versions
            license = info['license']
            if not info['license'] or not license.strip(
            ) or 'UNKNOWN' == license.upper():
                for classifier in info['classifiers']:
                    if classifier.strip().startswith('License'):
                        # Do it this way to cover people not quite following the spec
                        # at
                        # http://docs.python.org/distutils/setupscript.html#additional-meta-data
                        license = classifier.strip().replace('License ::', '')
                        license = license.replace('OSI Approved :: ', '')
                        break

            if license and len(license) > 100:
                license = "Other (see http://pypi.python.org/pypi/%s)" % self.pypi_name

            version.license = license

            # version stuff
            try:
                url_data = release['urls'][0]
                version.downloads = url_data['downloads']
                version.upload_time = url_data['upload_time']
            except IndexError:
                # Not a real release so we just guess the upload_time.
                version.upload_time = version.created

            version.hidden = info['_pypi_hidden']
            for classifier in info['classifiers']:
                if classifier.startswith('Development Status'):
                    version.development_status = status_choices_switch(
                        classifier)
                    break
            for classifier in info['classifiers']:
                if classifier.startswith(
                        'Programming Language :: Python :: 3'):
                    version.supports_python3 = True
                    break
            version.save()

            self.pypi_description = info['description']
            self.save()
            # Calculate total downloads

            return True
        return False

    @property
    def total_downloads(self):
        total = 0
        for dl in [v.downloads for v in self.version_set.all()]:
            total += dl
        return total

    def fetch_metadata(self, fetch_pypi=True, fetch_repo=True):

        if fetch_pypi:
            self.fetch_pypi_data()
        if fetch_repo:
            self.repo.fetch_metadata(self)
        self.save()

    def save(self, *args, **kwargs):
        if not self.repo_description:
            self.repo_description = ""
        super(Package, self).save(*args, **kwargs)

    def fetch_commits(self):
        self.repo.fetch_commits(self)

    def pypi_version(self):
        version = get_pypi_version(self)
        return version

    def last_released(self):
        cache_name = self.cache_namer(self.last_released)
        version = cache.get(cache_name)
        if version is not None:
            return version
        version = get_version(self)
        cache.set(cache_name, version)
        return version

    @property
    def development_status(self):
        """ Gets data needed in API v2 calls """
        return self.last_released().pretty_status

    @property
    def pypi_ancient(self):
        release = self.last_released()
        if release:
            return release.upload_time < datetime.now() - timedelta(365)
        return None

    @property
    def no_development(self):
        commit_date = self.last_updated()
        if commit_date is not None:
            return commit_date < datetime.now() - timedelta(365)
        return None

    class Meta:
        ordering = ['title']
        get_latest_by = 'id'

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return urlresolvers.reverse_lazy('package_index:package_detail',
                                         kwargs={'object_slug': self.slug})

    @property
    def last_commit(self):
        return self.commit_set.latest()
コード例 #4
0
class Abstract(models.Model):
    content = MarkupField()

    class Meta:
        abstract = True
コード例 #5
0
ファイル: models.py プロジェクト: jeepurs/ka-lite-central
class Deployment(models.Model):
    title = models.CharField(max_length=250)
    latitude = models.DecimalField(max_digits=5, decimal_places=3)
    longitude = models.DecimalField(max_digits=6, decimal_places=3)
    user_story = MarkupField()
コード例 #6
0
class Event(ContentManageable):
    uid = models.CharField(max_length=200, null=True, blank=True)
    title = models.CharField(max_length=200)
    calendar = models.ForeignKey(Calendar, related_name='events')

    description = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE,
                              escape_html=False)
    venue = models.ForeignKey(EventLocation,
                              null=True,
                              blank=True,
                              related_name='events')

    categories = models.ManyToManyField(EventCategory,
                                        related_name='events',
                                        blank=True,
                                        null=True)
    featured = models.BooleanField(default=False, db_index=True)

    objects = EventManager()

    class Meta:
        ordering = ('-occurring_rule__dt_start', )

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('events:event_detail',
                       kwargs={
                           'calendar_slug': self.calendar.slug,
                           'pk': self.pk
                       })

    @cached_property
    def previous_event(self):
        dt = self.next_time.dt_end
        try:
            return Event.objects.until_datetime(dt).filter(
                calendar=self.calendar)[0]
        except IndexError:
            return None

    @cached_property
    def next_event(self):
        dt = self.next_time.dt_start
        try:
            return Event.objects.for_datetime(dt).filter(
                calendar=self.calendar)[0]
        except IndexError:
            return None

    @property
    def next_time(self):
        """
        Return the OccurringRule or RecurringRule with the closest `dt_start` from now.
        """
        now = timezone.now()
        recurring_start = occurring_start = None

        try:
            occurring_rule = self.occurring_rule
        except OccurringRule.DoesNotExist:
            pass
        else:
            if occurring_rule and occurring_rule.dt_start > now:
                occurring_start = (occurring_rule.dt_start, occurring_rule)

        rrules = self.recurring_rules.filter(finish__gt=now)
        recurring_starts = [(rule.dt_start, rule) for rule in rrules
                            if rule.dt_start is not None]
        recurring_starts.sort(key=itemgetter(0))

        try:
            recurring_start = recurring_starts[0]
        except IndexError:
            pass

        starts = [
            i for i in (recurring_start, occurring_start) if i is not None
        ]
        starts.sort(key=itemgetter(0))
        try:
            return starts[0][1]
        except IndexError:
            return None

    @property
    def previous_time(self):
        now = timezone.now()
        recurring_end = occurring_end = None

        try:
            occurring_rule = self.occurring_rule
        except OccurringRule.DoesNotExist:
            pass
        else:
            if occurring_rule and occurring_rule.dt_end < now:
                occurring_end = (occurring_rule.dt_end, occurring_rule)

        rrules = self.recurring_rules.filter(begin__lt=now)
        recurring_ends = [(rule.dt_end, rule) for rule in rrules
                          if rule.dt_end is not None]
        recurring_ends.sort(key=itemgetter(0), reverse=True)

        try:
            recurring_end = recurring_ends[0]
        except IndexError:
            pass

        ends = [i for i in (recurring_end, occurring_end) if i is not None]
        ends.sort(key=itemgetter(0), reverse=True)
        try:
            return ends[0][1]
        except IndexError:
            return None

    @property
    def next_or_previous_time(self):
        return self.next_time or self.previous_time

    @property
    def is_past(self):
        return self.next_time is None
コード例 #7
0
ファイル: models.py プロジェクト: oslugr/web-pycones
class Proposal(TimeStampedModel):

    audience_level = models.CharField(
        verbose_name=_("Nivel de la audiencia"),
        choices=PROPOSAL_LEVELS,
        null=True,
        default=BASIC_LEVEL,
        max_length=32,
    )
    language = models.CharField(verbose_name=_("Idioma"),
                                max_length=2,
                                choices=PROPOSAL_LANGUAGES,
                                default="es")
    duration = models.PositiveIntegerField(
        verbose_name=_("Duración"),
        choices=PROPOSAL_DURATIONS,
        default=30,
        null=True,
        blank=True,
    )
    tags = TaggableManager(
        verbose_name=_("Etiquetas"),
        help_text=_("Lista de etiquetas separadas por comas."),
        blank=True,
    )

    is_beginners_friendly = models.BooleanField(
        verbose_name=_("¿Es apta para principiantes?"), default=False)

    kind = models.ForeignKey(
        "proposals.ProposalKind",
        verbose_name=_("Tipo de propuesta"),
        on_delete=models.CASCADE,
    )

    title = models.CharField(max_length=100, verbose_name=_("Título"))
    description = models.TextField(
        _("Breve descripción"),
        max_length=500,
        help_text=_(
            "Si tu propuesta se acepta esto se hará público, y se incluirá en el programa. "
            "Debería ser un párrafo, con un máximo de 500 caracteres."),
    )
    abstract = MarkupField(
        _("Resumen detallado"),
        blank=True,
        default="",
        default_markup_type="markdown",
        help_text=
        _("Resumen detallado. Se hará pública si la propuesta se acepta. Edita "
          "usando <a href='http://daringfireball.net/projects/markdown/basics' "
          "target='_blank'>Markdown</a>."),
    )
    additional_notes = MarkupField(
        _("Notas adicionales"),
        blank=True,
        default="",
        default_markup_type="markdown",
        help_text=
        _("Cualquier cosa que te gustaría hacer saber a los revisores para que la tengan en "
          "cuenta al ahora de hacer la selección. Esto no se hará público. Edita usando "
          "<a href='http://daringfireball.net/projects/markdown/basics' "
          "target='_blank'>Markdown</a>."),
    )

    speakers = models.ManyToManyField("speakers.Speaker",
                                      related_name="proposals",
                                      blank=False)

    cancelled = models.BooleanField(default=False)
    notified = models.BooleanField(default=False)
    accepted = models.NullBooleanField(verbose_name=_("Aceptada"),
                                       default=None)
    accepted_notified = models.BooleanField(
        verbose_name=_("Notificación de aceptación enviada"), default=False)
    code = models.CharField(max_length=64, null=True, blank=True)

    def __str__(self):
        return self.title

    @property
    def translated_abstract(self):
        return get_translated_markdown_field(self, "abstract")

    @property
    def translated_additional_notes(self):
        return get_translated_markdown_field(self, "additional_notes")

    @property
    def avg(self):
        data = [
            review.score for review in self.reviews.filter(finished=True)
            if review.score is not None
        ]
        if data:
            return sum(data) / len(data)
        return None

    @property
    def completed_reviews(self):
        return self.reviews.filter(finished=True).count()

    @property
    def assigned_reviews(self):
        return self.reviews.count()

    @property
    def tag_list(self):
        return ", ".join(tag.name for tag in self.tags.all())

    @property
    def speakers_list(self):
        return ", ".join([
            "%s <%s>" % (speaker.name, speaker.email)
            for speaker in self.speakers.all()
        ])

    @property
    def renormalization_o0(self):
        """Renormalization with order 0. Average value of 0"""
        score = []
        for review in self.reviews.all():
            reviewer = Reviewer.objects.get(user=review.user)
            mean = reviewer.mean()
            if reviewer.num_reviews() <= 1:
                continue
            score.append((review.score or 0) - mean)
        if score:
            return np.mean(score)
        return None

    @property
    def renormalization_o1(self):
        """Renormalization with order 1. Expand the value to get the same standard deviation for everyone"""
        score = []
        for review in self.reviews.all():
            reviewer = Reviewer.objects.get(user=review.user)
            std = reviewer.std()
            if reviewer.num_reviews() <= 1 or std < 0.75:
                continue
            score.append((review.score or 0) - std)
        if score:
            return np.mean(score)
        return None

    def notification_email_context(self, speaker):
        site = Site.objects.get_current()
        return {
            "title": self.title,
            "speaker": speaker,
            "kind": self.kind.name,
            "code": self.code,
            "site": site,
        }

    def notify(self):
        """Sends an email to the creator of the proposal with a confirmation email. The emails has a
        link to edit the proposal.
        """
        if not self.code:
            self.code = random_string(64)
        for speaker in self.speakers.all():
            context = self.notification_email_context(speaker=speaker)
            send_email(
                context=context,
                template="emails/proposals/confirmation.html",
                subject=_("[%s] Confirmación de propuesta de charla") %
                settings.CONFERENCE_TITLE,
                to=speaker.email,
                from_email=settings.CONTACT_EMAIL,
            )
        self.notified = True
        self.save()

    def notify_acceptance(self):
        """Sends an email to the creator of the proposal with an email with the resolution of the acceptance or not
        of his proposal.
        """
        for speaker in self.speakers.all():
            context = self.notification_email_context(speaker=speaker)
            if self.accepted is None:
                return
            template = ("emails/proposals/accepted.html"
                        if self.accepted else "emails/proposals/rejected.html")
            send_email(
                context=context,
                template=template,
                subject=_("[%s] Notificación de propuesta de charla") %
                settings.CONFERENCE_TITLE,
                to=self.speaker.email,
                from_email=settings.CONTACT_EMAIL,
            )
        self.accepted_notified = True
        self.save()
コード例 #8
0
class Contract(models.Model):
    """
    Contract model to oficialize a Sponsorship
    """

    DRAFT = "draft"
    OUTDATED = "outdated"
    AWAITING_SIGNATURE = "awaiting signature"
    EXECUTED = "executed"
    NULLIFIED = "nullified"

    STATUS_CHOICES = [
        (DRAFT, "Draft"),
        (OUTDATED, "Outdated"),
        (AWAITING_SIGNATURE, "Awaiting signature"),
        (EXECUTED, "Executed"),
        (NULLIFIED, "Nullified"),
    ]

    FINAL_VERSION_PDF_DIR = "sponsors/contracts/"
    FINAL_VERSION_DOCX_DIR = FINAL_VERSION_PDF_DIR + "docx/"
    SIGNED_PDF_DIR = FINAL_VERSION_PDF_DIR + "signed/"

    status = models.CharField(max_length=20,
                              choices=STATUS_CHOICES,
                              default=DRAFT,
                              db_index=True)
    revision = models.PositiveIntegerField(default=0,
                                           verbose_name="Revision nº")
    document = models.FileField(
        upload_to=FINAL_VERSION_PDF_DIR,
        blank=True,
        verbose_name="Unsigned PDF",
    )
    document_docx = models.FileField(
        upload_to=FINAL_VERSION_DOCX_DIR,
        blank=True,
        verbose_name="Unsigned Docx",
    )
    signed_document = models.FileField(
        upload_to=signed_contract_random_path,
        blank=True,
        verbose_name="Signed PDF",
    )

    # Contract information gets populated during object's creation.
    # The sponsorship FK ís just a reference to keep track of related objects.
    # It shouldn't be used to fetch for any of the sponsorship's data.
    sponsorship = models.OneToOneField(
        "sponsors.Sponsorship",
        null=True,
        on_delete=models.SET_NULL,
        related_name="contract",
    )
    sponsor_info = models.TextField(verbose_name="Sponsor information")
    sponsor_contact = models.TextField(verbose_name="Sponsor contact")

    # benefits_list = """
    #   - Foundation - Promotion of Python case study [^1]
    #   - PyCon - PyCon website Listing [^1][^2]
    #   - PyPI - Social media promotion of your sponsorship
    # """
    benefits_list = MarkupField(markup_type="markdown")
    # legal_clauses = """
    # [^1]: Here's one with multiple paragraphs and code.
    #    Indent paragraphs to include them in the footnote.
    #    `{ my code }`
    #    Add as many paragraphs as you like.
    # [^2]: Here's one with multiple paragraphs and code.
    #    Indent paragraphs to include them in the footnote.
    #    `{ my code }`
    #    Add as many paragraphs as you like.
    # """
    legal_clauses = MarkupField(markup_type="markdown", default="", blank=True)

    # Activity control fields
    created_on = models.DateField(auto_now_add=True)
    last_update = models.DateField(auto_now=True)
    sent_on = models.DateField(null=True)

    class Meta:
        verbose_name = "Contract"
        verbose_name_plural = "Contracts"

    def __str__(self):
        return f"Contract: {self.sponsorship}"

    @classmethod
    def new(cls, sponsorship):
        """
        Factory method to create a new Contract from a Sponsorship
        """
        sponsor = sponsorship.sponsor
        primary_contact = sponsor.primary_contact

        sponsor_info = f"{sponsor.name}, {sponsor.description}"
        sponsor_contact = ""
        if primary_contact:
            sponsor_contact = f"{primary_contact.name} - {primary_contact.phone} | {primary_contact.email}"

        benefits = sponsorship.benefits.all()
        # must query for Legal Clauses again to respect model's ordering
        clauses_ids = [
            c.id for c in chain(*(b.legal_clauses for b in benefits))
        ]
        legal_clauses = list(LegalClause.objects.filter(id__in=clauses_ids))

        benefits_list = []
        for benefit in benefits:
            item = f"- {benefit.program_name} - {benefit.name_for_display}"
            index_str = ""
            for legal_clause in benefit.legal_clauses:
                index = legal_clauses.index(legal_clause) + 1
                index_str += f"[^{index}]"
            if index_str:
                item += f" {index_str}"
            benefits_list.append(item)

        legal_clauses_text = "\n".join([
            f"[^{i}]: {c.clause}" for i, c in enumerate(legal_clauses, start=1)
        ])
        return cls.objects.create(
            sponsorship=sponsorship,
            sponsor_info=sponsor_info,
            sponsor_contact=sponsor_contact,
            benefits_list="\n".join([b for b in benefits_list]),
            legal_clauses=legal_clauses_text,
        )

    @property
    def is_draft(self):
        return self.status == self.DRAFT

    @property
    def preview_url(self):
        return reverse("admin:sponsors_contract_preview", args=[self.pk])

    @property
    def awaiting_signature(self):
        return self.status == self.AWAITING_SIGNATURE

    @property
    def next_status(self):
        states_map = {
            self.DRAFT: [self.AWAITING_SIGNATURE, self.EXECUTED],
            self.OUTDATED: [],
            self.AWAITING_SIGNATURE: [self.EXECUTED, self.NULLIFIED],
            self.EXECUTED: [],
            self.NULLIFIED: [self.DRAFT],
        }
        return states_map[self.status]

    def save(self, **kwargs):
        if all([self.pk, self.is_draft]):
            self.revision += 1
        return super().save(**kwargs)

    def set_final_version(self, pdf_file, docx_file=None):
        if self.AWAITING_SIGNATURE not in self.next_status:
            msg = f"Can't send a {self.get_status_display()} contract."
            raise InvalidStatusException(msg)

        sponsor = self.sponsorship.sponsor.name.upper()

        # save contract as PDF file
        path = f"{self.FINAL_VERSION_PDF_DIR}"
        pdf_filename = f"{path}SoW: {sponsor}.pdf"
        file = file_from_storage(pdf_filename, mode="wb")
        file.write(pdf_file)
        file.close()
        self.document = pdf_filename

        # save contract as docx file
        if docx_file:
            path = f"{self.FINAL_VERSION_DOCX_DIR}"
            docx_filename = f"{path}SoW: {sponsor}.docx"
            file = file_from_storage(docx_filename, mode="wb")
            file.write(docx_file)
            file.close()
            self.document_docx = docx_filename

        self.status = self.AWAITING_SIGNATURE
        self.save()

    def execute(self, commit=True, force=False):
        if not force and self.EXECUTED not in self.next_status:
            msg = f"Can't execute a {self.get_status_display()} contract."
            raise InvalidStatusException(msg)

        self.status = self.EXECUTED
        self.sponsorship.status = Sponsorship.FINALIZED
        self.sponsorship.finalized_on = timezone.now().date()
        if commit:
            self.sponsorship.save()
            self.save()

    def nullify(self, commit=True):
        if self.NULLIFIED not in self.next_status:
            msg = f"Can't nullify a {self.get_status_display()} contract."
            raise InvalidStatusException(msg)

        self.status = self.NULLIFIED
        if commit:
            self.sponsorship.save()
            self.save()
コード例 #9
0
class Post(models.Model):
    title = models.CharField(max_length=50)
    body = MarkupField('body of post')

    def __unicode__(self):
        return self.title
コード例 #10
0
ファイル: models.py プロジェクト: wpbird007/pythondotorg
class Job(ContentManageable):
    NEW_THRESHOLD = datetime.timedelta(days=30)

    category = models.ForeignKey(JobCategory, related_name='jobs')
    job_types = models.ManyToManyField(JobType,
                                       related_name='jobs',
                                       blank=True)
    company = models.ForeignKey('companies.Company', related_name='jobs')

    city = models.CharField(max_length=100)
    region = models.CharField(max_length=100)
    country = models.CharField(max_length=100, db_index=True)
    location_slug = models.SlugField(max_length=350, editable=False)

    description = MarkupField(blank=True,
                              default_markup_type=DEFAULT_MARKUP_TYPE)
    requirements = MarkupField(blank=True,
                               default_markup_type=DEFAULT_MARKUP_TYPE)

    contact = models.CharField(null=True, blank=True, max_length=100)
    email = models.EmailField()
    url = models.URLField('URL', null=True, blank=True)

    STATUS_DRAFT = 'draft'
    STATUS_REVIEW = 'review'
    STATUS_APPROVED = 'approved'
    STATUS_REJECTED = 'rejected'
    STATUS_ARCHIVED = 'archived'
    STATUS_REMOVED = 'removed'
    STATUS_EXPIRED = 'expired'

    STATUS_CHOICES = (
        (STATUS_DRAFT, 'draft'),
        (STATUS_REVIEW, 'review'),
        (STATUS_APPROVED, 'approved'),
        (STATUS_REJECTED, 'rejected'),
        (STATUS_ARCHIVED, 'archived'),
        (STATUS_REMOVED, 'removed'),
        (STATUS_EXPIRED, 'expired'),
    )
    status = models.CharField(max_length=20,
                              choices=STATUS_CHOICES,
                              default=STATUS_DRAFT,
                              db_index=True)
    dt_start = models.DateTimeField('Job start date', blank=True, null=True)
    dt_end = models.DateTimeField('Job end date', blank=True, null=True)

    telecommuting = models.BooleanField(default=True)
    agencies = models.BooleanField(default=True)

    is_featured = models.BooleanField(default=False, db_index=True)

    objects = JobManager()

    class Meta:
        ordering = ('-created', )
        get_latest_by = 'created'
        verbose_name = 'job'
        verbose_name_plural = 'jobs'
        permissions = [('can_moderate_jobs', 'Can moderate Job listings')]

    def __str__(self):
        return 'Job Listing #{0}'.format(self.pk)

    def save(self, **kwargs):
        self.location_slug = slugify('%s %s %s' %
                                     (self.city, self.region, self.country))

        if not self.dt_start and self.status == self.STATUS_APPROVED:
            self.dt_start = timezone.now()
            self.dt_end = timezone.now() + self.NEW_THRESHOLD

        return super().save(**kwargs)

    def get_absolute_url(self):
        return reverse('jobs:job_detail', kwargs={'pk': self.pk})

    @property
    def is_new(self):
        return self.created > (timezone.now() - self.NEW_THRESHOLD)

    @property
    def editable(self):
        return self.status in (self.STATUS_DRAFT, self.STATUS_REVIEW,
                               self.STATUS_REJECTED)
コード例 #11
0
class Speaker(TimeStampedModel):

    user = models.OneToOneField(settings.AUTH_USER_MODEL,
                                related_name="speaker")
    name = models.CharField(
        verbose_name=_("Nombre"),
        max_length=100,
        help_text=_(
            "Tal como quieres que apareza en el programa de la conferencia."))
    biography = MarkupField(verbose_name=_("Biografía"),
                            blank=True,
                            default="",
                            default_markup_type='markdown',
                            help_text=_(
                                "Unas palabras sobre ti. Edita usando "
                                "<a href='http://warpedvisions.org/projects/"
                                "markdown-cheat-sheet/target='_blank'>"
                                "Markdown</a>."))
    photo = models.ImageField(verbose_name=_("Foto"),
                              upload_to="speakers",
                              blank=True,
                              null=True)
    annotation = models.TextField(default="", blank=True)
    is_keynoter = models.BooleanField(default=False)

    class Meta:
        ordering = ['name']

    @property
    def photo_url(self):
        try:
            return self.photo.url
        except ValueError:
            return static("img/default-avatar.png")

    @property
    def email(self):
        if self.user is not None:
            return self.user.email
        else:
            return self.invite_email

    @property
    def all_presentations(self):
        presentations = []
        if self.presentations:
            for p in self.presentations.all():
                presentations.append(p)
            for p in self.copresentations.all():
                presentations.append(p)
        return presentations

    def __str__(self):
        if self.user:
            return self.name
        else:
            return "?"

    def has_biography(self):
        return bool(self.biography.raw)

    def get_api_id(self):
        return "S{:05d}".format(self.pk)

    def save(self, **kwargs):
        """Save user full name by default for speaker."""
        if not self.name:
            self.name = self.user.get_full_name()
        return super(Speaker, self).save(**kwargs)
コード例 #12
0
class DescribeAble(models.Model):
    description = MarkupField(default="No Description Provided",
                              default_markup_type='markdown')

    class Meta:
        abstract = True
コード例 #13
0
class LocateAble(models.Model):
    phone = models.CharField(max_length=10, null=True, blank=True)
    address = MarkupField(default="No Address Provided")

    class Meta:
        abstract = True
コード例 #14
0
ファイル: models.py プロジェクト: ImgBotApp/website-30
class PMASA(models.Model):
    year = models.IntegerField(choices=YEAR_CHOICES, default=YEAR_TODAY)
    sequence = models.IntegerField(
        help_text='Sequence number of PMASA in given year')
    date = models.DateTimeField(db_index=True, default=timezone.now)
    updated = models.DateTimeField(
        null=True,
        blank=True,
        help_text='Set this in case of major update to the entry')
    summary = models.CharField(max_length=200)
    description = MarkupField(default_markup_type='markdown')
    severity = models.TextField()
    mitigation = models.TextField(blank=True)
    affected = models.TextField()
    unaffected = models.TextField(blank=True)
    solution = models.TextField(
        max_length=200,
        default='Upgrade to phpMyAdmin ? or newer or apply patch listed below.'
    )
    references = models.TextField(
        help_text='Links to reporter etc.',
        blank=True,
    )
    cve = models.CharField(
        max_length=200,
        help_text=
        'Space separated list of related CVE entries, enter CVE-2017- in case none is assigned yet'
    )
    cwe = models.CharField(
        max_length=200,
        default='661',
        help_text='Space separated list of CWE classifications')
    commits = models.TextField(help_text=(
        'Space separated list of commits, commits for different branches '
        'should be placed on separate line prefixed with version prefix. '
        'For example: 3.5: 01d35b3558e47fba947719857bd71f6fd9e5dce8'))
    draft = models.BooleanField(
        default=True,
        help_text='Draft entries are not shown in website listings')

    class Meta(object):
        unique_together = ('year', 'sequence')
        ordering = ('-year', '-sequence')
        verbose_name = 'PMASA'
        verbose_name_plural = 'PMASAs'

    def __unicode__(self):
        return 'PMASA-{0}-{1}'.format(self.year, self.sequence)

    @models.permalink
    def get_absolute_url(self):
        if self.draft:
            page = 'security-issue-draft'
        else:
            page = 'security-issue'
        return (page, (), {'year': self.year, 'sequence': self.sequence})

    def get_cves(self):
        for cve in self.cve.split():
            # Incomplete reference as CVE-2016-
            if cve[-1] == '-':
                yield '', 'Not yet assigned'
            else:
                yield 'https://cve.mitre.org/cgi-bin/cvename.cgi?name={0}'.format(
                    cve), cve

    def get_cwes(self):
        return self.cwe.split()

    def get_commits(self):
        lines = self.commits.strip().split('\n')
        result = []
        for line in lines:
            if ':' in line:
                branch, line = line.split(':')
            else:
                branch = ''
            result.append({
                'branch': branch,
                'commits': line.strip().split(),
            })
        return result
コード例 #15
0
ファイル: models.py プロジェクト: olea/PyConES-2015
class Slot(models.Model):

    day = models.ForeignKey(Day)
    kind = models.ForeignKey(SlotKind)
    start = models.TimeField()
    end = models.TimeField()
    content_override = MarkupField(blank=True, default_markup_type='markdown')
    default_room = models.ForeignKey(Room, null=True, blank=True)

    video_url = models.URLField(_("video URL"), blank=True, null=True)

    keynote_url = models.URLField(_("keynote URL"), blank=True, null=True)
    keynote = models.FileField(_("keynote file"), blank=True, null=True, upload_to="keynotes")

    def assign(self, content):
        """
        Assign the given content to this slot and if a previous slot content
        was given we need to unlink it to avoid integrity errors.
        """
        self.unassign()
        content.slot = self
        content.save()

    def unassign(self):
        """
        Unassign the associated content with this slot.
        """
        content = self.content
        if content and content.slot_id:
            content.slot = None
            content.save()

    @property
    def content(self):
        """
        Return the content this slot represents.
        @@@ hard-coded for presentation for now
        """
        try:
            return self.content_ptr
        except ObjectDoesNotExist:
            return None

    def get_video_url(self):
        if self.video_url:
            return self.video_url
        if not self.content_ptr.video_url:
            return ""
        return self.content_ptr.video_url

    def get_keynote_url(self):
        if self.keynote and not self.keynote_url:
            return self.keynote
        elif self.keynote_url:
            return self.keynote_url
        if self.content_ptr.keynote and not self.content_ptr.keynote_url:
            return self.content_ptr.keynote.url
        elif self.content_ptr.keynote_url:
            return self.content_ptr.keynote_url
        return ""

    @property
    def start_datetime(self):
        return datetime.datetime(
            self.day.date.year,
            self.day.date.month,
            self.day.date.day,
            self.start.hour,
            self.start.minute)

    @property
    def end_datetime(self):
        return datetime.datetime(
            self.day.date.year,
            self.day.date.month,
            self.day.date.day,
            self.end.hour,
            self.end.minute)

    @property
    def length_in_minutes(self):
        return int(
            (self.end_datetime - self.start_datetime).total_seconds() / 60)

    @property
    def rooms(self):
        return Room.objects.filter(pk__in=self.slotroom_set.values("room"))

    def __str__(self):
        if not self.rooms:
            return "%s %s (%s - %s)" % (self.day, self.kind, self.start, self.end)
        rooms = ", ".join(map(lambda room: room.name, self.rooms))
        return "%s %s (%s - %s, %s)" % (self.day, self.kind, self.start, self.end, rooms)

    class Meta:
        ordering = ["day", "start", "end", "default_room__order"]
コード例 #16
0
class CustomArticle(models.Model):
    text = MarkupField(markup_choices=CUSTOM_MARKUP_TYPES,
                       default_markup_type='text/x-rst')
コード例 #17
0
class Job(ContentManageable):
    NEW_THRESHOLD = datetime.timedelta(days=30)

    category = models.ForeignKey(
        JobCategory,
        related_name='jobs',
        limit_choices_to={'active': True},
        on_delete=models.CASCADE,
    )
    job_types = models.ManyToManyField(
        JobType,
        related_name='jobs',
        blank=True,
        verbose_name='Job technologies',
        limit_choices_to={'active': True},
    )
    other_job_type = models.CharField(
        verbose_name='Other job technologies',
        max_length=100,
        blank=True,
    )
    company_name = models.CharField(max_length=100, null=True)
    company_description = MarkupField(blank=True,
                                      default_markup_type=DEFAULT_MARKUP_TYPE)
    job_title = models.CharField(max_length=100)

    city = models.CharField(max_length=100)
    region = models.CharField(verbose_name='State, Province or Region',
                              blank=True,
                              max_length=100)
    country = models.CharField(max_length=100, db_index=True)
    location_slug = models.SlugField(max_length=350, editable=False)
    country_slug = models.SlugField(max_length=100, editable=False)

    description = MarkupField(verbose_name='Job description',
                              default_markup_type=DEFAULT_MARKUP_TYPE)
    requirements = MarkupField(verbose_name='Job requirements',
                               default_markup_type=DEFAULT_MARKUP_TYPE)

    contact = models.CharField(verbose_name='Contact name',
                               null=True,
                               blank=True,
                               max_length=100)
    email = models.EmailField(verbose_name='Contact email')
    url = models.URLField(verbose_name='URL', null=True, blank=True)

    STATUS_DRAFT = 'draft'
    STATUS_REVIEW = 'review'
    STATUS_APPROVED = 'approved'
    STATUS_REJECTED = 'rejected'
    STATUS_ARCHIVED = 'archived'
    STATUS_REMOVED = 'removed'
    STATUS_EXPIRED = 'expired'

    STATUS_CHOICES = (
        (STATUS_DRAFT, 'draft'),
        (STATUS_REVIEW, 'review'),
        (STATUS_APPROVED, 'approved'),
        (STATUS_REJECTED, 'rejected'),
        (STATUS_ARCHIVED, 'archived'),
        (STATUS_REMOVED, 'removed'),
        (STATUS_EXPIRED, 'expired'),
    )
    status = models.CharField(max_length=20,
                              choices=STATUS_CHOICES,
                              default=STATUS_REVIEW,
                              db_index=True)
    expires = models.DateTimeField(verbose_name='Job Listing Expiration Date',
                                   blank=True,
                                   null=True)

    telecommuting = models.BooleanField(verbose_name='Telecommuting allowed?',
                                        default=False)
    agencies = models.BooleanField(verbose_name='Agencies are OK to contact?',
                                   default=True)

    is_featured = models.BooleanField(default=False, db_index=True)

    objects = JobQuerySet.as_manager()

    class Meta:
        ordering = ('-created', )
        get_latest_by = 'created'
        verbose_name = 'job'
        verbose_name_plural = 'jobs'
        permissions = [('can_moderate_jobs', 'Can moderate Job listings')]

    def __str__(self):
        return 'Job Listing #{}'.format(self.pk)

    def save(self, **kwargs):
        location_parts = (self.city, self.region, self.country)
        location_str = ''
        for location_part in location_parts:
            if location_part is not None:
                location_str = ' '.join([location_str, location_part])
        self.location_slug = slugify(location_str)
        self.country_slug = slugify(self.country)

        if not self.expires and self.status == self.STATUS_APPROVED:
            delta = datetime.timedelta(days=settings.JOB_THRESHOLD_DAYS)
            self.expires = timezone.now() + delta

        return super().save(**kwargs)

    def review(self):
        """Updates job status to Job.STATUS_REVIEW after preview was done by
        user.
        """
        old_status = self.status
        self.status = Job.STATUS_REVIEW
        self.save()
        if old_status != self.status:
            job_was_submitted.send(sender=self.__class__, job=self)

    def approve(self, approving_user):
        """Updates job status to Job.STATUS_APPROVED after approval was issued
        by approving_user.
        """
        self.status = Job.STATUS_APPROVED
        self.save()
        job_was_approved.send(sender=self.__class__,
                              job=self,
                              approving_user=approving_user)

    def reject(self, rejecting_user):
        """Updates job status to Job.STATUS_REJECTED after rejection was issued
        by rejecing_user.
        """
        self.status = Job.STATUS_REJECTED
        self.save()
        job_was_rejected.send(sender=self.__class__,
                              job=self,
                              rejecting_user=rejecting_user)

    def get_absolute_url(self):
        return reverse('jobs:job_detail', kwargs={'pk': self.pk})

    @property
    def display_name(self):
        return "%s, %s" % (self.job_title, self.company_name)

    @property
    def display_description(self):
        return self.company_description

    @property
    def display_location(self):
        location_parts = [
            part for part in (self.city, self.region, self.country) if part
        ]
        location_str = ', '.join(location_parts)
        return location_str

    @property
    def is_new(self):
        return self.created > (timezone.now() - self.NEW_THRESHOLD)

    @property
    def editable(self):
        return self.status in (self.STATUS_DRAFT, self.STATUS_REVIEW,
                               self.STATUS_REJECTED)

    def get_previous_listing(self):
        return self.get_previous_by_created(status=self.STATUS_APPROVED)

    def get_next_listing(self):
        return self.get_next_by_created(status=self.STATUS_APPROVED)
コード例 #18
0
class Presentation(models.Model):

    slot = models.OneToOneField(Slot,
                                null=True,
                                blank=True,
                                related_name="presentation",
                                on_delete=SET_NULL)

    title = models.CharField(max_length=100, default="", blank=True)
    slug = models.SlugField(max_length=100,
                            null=True,
                            blank=True,
                            allow_unicode=True)
    description = MarkupField(default="",
                              blank=True,
                              default_markup_type='markdown')
    abstract = MarkupField(default="",
                           blank=True,
                           default_markup_type='markdown')
    language = models.CharField(verbose_name=_("Idioma"),
                                max_length=2,
                                choices=PROPOSAL_LANGUAGES,
                                null=True,
                                blank=True)

    speakers = models.ManyToManyField("speakers.Speaker",
                                      related_name="presentations",
                                      blank=True)
    proposal = models.OneToOneField("proposals.Proposal",
                                    related_name="presentation",
                                    null=True,
                                    blank=True)

    cancelled = models.BooleanField(default=False)

    video_url = models.URLField(_("video URL"), blank=True, null=True)
    keynote_url = models.URLField(_("URL de la presentación o del código"),
                                  blank=True,
                                  null=True)
    keynote = models.FileField(_("Fichero de presentación"),
                               blank=True,
                               null=True,
                               upload_to="keynotes")

    class Meta:
        ordering = ["slot"]

    def __str__(self):
        return "#%s %s (%s)" % (self.pk, self.get_title(), ",".join(
            map(lambda s: six.text_type(s), self.get_speakers())))

    def get_title(self):
        if self.title:
            return self.title
        if self.proposal:
            return self.proposal.title
        return None

    def get_description(self):
        if self.description.raw:
            return self.description
        if self.proposal:
            return self.proposal.description
        return None

    def get_abstract(self):
        if self.abstract.raw:
            return self.abstract
        if self.proposal:
            return self.proposal.translated_abstract
        return None

    def get_additional_notes(self):
        if self.additional_notes.raw:
            return self.additional_notes
        if self.proposal:
            return self.proposal.translated_additional_notes
        return None

    def get_language(self):
        if self.language:
            return self.language
        if self.proposal:
            return self.proposal.language
        return None

    def get_speakers(self):
        if self.speakers.exists():
            return self.speakers.all()
        if self.proposal:
            return self.proposal.speakers.all()
        return self.speakers.all()

    def has_speakers(self):
        return self.get_speakers().exists()

    def get_audience_level(self):
        if self.proposal:
            return self.proposal.audience_level
        return BASIC_LEVEL

    def get_video_url(self):
        if not self.video_url:
            return ""
        return self.video_url

    def get_keynote_url(self):
        if self.keynote and not self.keynote_url:
            return self.keynote.url
        elif self.keynote_url:
            return self.keynote_url
        return ""

    def get_api_id(self):
        return "T{:04d}".format(self.pk)

    def save(self, *args, **kwargs):
        title = self.get_title()
        if title and not self.slug:
            self.slug = slugify(title)
        super(Presentation, self).save(*args, **kwargs)
コード例 #19
0
ファイル: models.py プロジェクト: HorseTechInnovation/eqenum
class Authority(models.Model):
    ref = models.CharField(max_length=20, primary_key=True)
    name = models.CharField(max_length=60, unique=True)
    url = models.URLField(blank=True, null=True)
    notes = MarkupField(markup_type='markdown', blank=True, null=True)
コード例 #20
0
class Slot(models.Model):

    day = models.ForeignKey(Day)
    kind = models.ForeignKey(SlotKind)
    start = models.TimeField()
    end = models.TimeField()
    order = models.PositiveIntegerField(default=0)
    content_override = MarkupField(blank=True, default_markup_type='markdown')

    room = models.ForeignKey(Room, related_name="slots", null=True, blank=True)
    track = models.ForeignKey(Track,
                              related_name="slots",
                              null=True,
                              blank=True)

    video_url = models.URLField(_("video URL"), blank=True, null=True)
    keynote_url = models.URLField(_("keynote URL"), blank=True, null=True)
    keynote = models.FileField(_("keynote file"),
                               blank=True,
                               null=True,
                               upload_to="keynotes")

    class Meta:
        ordering = ["day", "start", "end", "track__order", "order"]

    @property
    def content(self):
        """ Return the content this slot represents."""
        try:
            return self.presentation
        except ObjectDoesNotExist:
            return None

    @property
    def start_datetime(self):
        return make_aware(
            datetime.datetime(self.day.date.year, self.day.date.month,
                              self.day.date.day, self.start.hour,
                              self.start.minute))

    @property
    def end_datetime(self):
        return make_aware(
            datetime.datetime(self.day.date.year, self.day.date.month,
                              self.day.date.day, self.end.hour,
                              self.end.minute))

    def __str__(self):
        return "%s %s (%s - %s, %s)" % (self.day, self.kind, self.start,
                                        self.end, self.room)

    def assign(self, content):
        """Assign the given content to this slot and if a previous slot content
        was given we need to unlink it to avoid integrity errors.
        """
        self.unassign()
        content.slot = self
        content.save()

    def unassign(self):
        """Unassign the associated content with this slot."""
        content = self.presentation
        if content and content.slot_id:
            content.slot = None
            content.save()

    def get_video_url(self):
        if self.video_url:
            return self.video_url
        try:
            return self.presentation.get_video_url()
        except ObjectDoesNotExist:
            pass
        return ""

    def get_keynote_url(self):
        if self.keynote and not self.keynote_url:
            return self.keynote
        elif self.keynote_url:
            return self.keynote_url
        try:
            return self.presentation.get_keynote_url()
        except ObjectDoesNotExist:
            pass
        return ""

    def get_absolute_url(self):
        if self.content and self.content.slug:
            return reverse("schedule:slot", kwargs={"slot": self.content.slug})
        return reverse("schedule:slot", kwargs={"slot": self.pk})
コード例 #21
0
class Release(ContentManageable, NameSlugModel):
    """
    A particular version release.  Name field should be version number for
    example: 3.3.4 or 2.7.6
    """
    PYTHON1 = 1
    PYTHON2 = 2
    PYTHON3 = 3
    PYTHON_VERSION_CHOICES = (
        (PYTHON3, 'Python 3.x.x'),
        (PYTHON2, 'Python 2.x.x'),
        (PYTHON1, 'Python 1.x.x'),
    )
    version = models.IntegerField(default=PYTHON3,
                                  choices=PYTHON_VERSION_CHOICES)
    is_latest = models.BooleanField(
        verbose_name='Is this the latest release?',
        default=False,
        db_index=True,
        help_text="Set this if this should be considered the latest release "
        "for the major version. Previous 'latest' versions will "
        "automatically have this flag turned off.",
    )
    is_published = models.BooleanField(
        verbose_name='Is Published?',
        default=False,
        db_index=True,
        help_text=
        "Whether or not this should be considered a released/published version",
    )
    pre_release = models.BooleanField(
        verbose_name='Pre-release',
        default=False,
        db_index=True,
        help_text="Boolean to denote pre-release/beta/RC versions",
    )
    show_on_download_page = models.BooleanField(
        default=True,
        db_index=True,
        help_text=
        "Whether or not to show this release on the main /downloads/ page",
    )
    release_date = models.DateTimeField(default=timezone.now)
    release_page = models.ForeignKey(
        Page,
        related_name='release',
        blank=True,
        null=True,
        on_delete=models.CASCADE,
    )
    release_notes_url = models.URLField('Release Notes URL', blank=True)

    content = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE, default='')

    objects = ReleaseManager()

    class Meta:
        verbose_name = 'Release'
        verbose_name_plural = 'Releases'
        ordering = ('name', )
        get_latest_by = 'release_date'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        if not self.content.raw and self.release_page:
            return self.release_page.get_absolute_url()
        else:
            return reverse('download:download_release_detail',
                           kwargs={'release_slug': self.slug})

    def download_file_for_os(self, os_slug):
        """ Given an OS slug return the appropriate download file """
        try:
            file = self.files.get(os__slug=os_slug, download_button=True)
        except ReleaseFile.DoesNotExist:
            file = None

        return file

    def files_for_os(self, os_slug):
        """ Return all files for this release for a given OS """
        files = self.files.filter(os__slug=os_slug).order_by('-name')
        return files

    def get_version(self):
        version = re.match(r'Python\s([\d.]+)', self.name)
        if version is not None:
            return version.group(1)
        return None
コード例 #22
0
class Question(KnowledgeBase):
    is_question = True
    _requesting_user = None

    title = models.CharField(max_length=255,
                             verbose_name=_('Question'),
                             help_text=_('Enter your question or suggestion.'))
    body = MarkupField(blank=True,
                       null=True,
                       verbose_name=_('Description'),
                       default_markup_type="markdown",
                       help_text=_('Please offer details. Markdown enabled.'))

    status = models.CharField(verbose_name=_('Status'),
                              max_length=32,
                              choices=STATUSES,
                              default='private',
                              db_index=True)

    locked = models.BooleanField(default=False)

    categories = models.ManyToManyField('knowledge.Category', blank=True)

    objects = QuestionManager()

    class Meta:
        ordering = ['-added']
        verbose_name = _('Question')
        verbose_name_plural = _('Questions')

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        from django.template.defaultfilters import slugify

        if settings.SLUG_URLS:
            return reverse('knowledge_thread',
                           kwargs={
                               'question_id': self.id,
                               'slug': slugify(self.title)
                           })
        else:
            return reverse('knowledge_thread_no_slug',
                           kwargs={'question_id': self.id})

    def inherit(self):
        pass

    def internal(self):
        pass

    def lock(self, save=True):
        self.locked = not self.locked
        if save:
            self.save()

    lock.alters_data = True

    ###################
    #### RESPONSES ####
    ###################

    def get_responses(self, user=None):
        user = user or self._requesting_user
        if user:
            return [
                r for r in self.responses.all().select_related('user')
                if r.can_view(user)
            ]
        else:
            return self.responses.all().select_related('user')

    def answered(self):
        """
        Returns a boolean indictating whether there any questions.
        """
        return bool(self.get_responses())

    def accepted(self):
        """
        Returns a boolean indictating whether there is a accepted answer
        or not.
        """
        return any([r.accepted for r in self.get_responses()])

    def clear_accepted(self):
        self.get_responses().update(accepted=False)

    clear_accepted.alters_data = True

    def accept(self, response=None):
        """
        Given a response, make that the one and only accepted answer.
        Similar to StackOverflow.
        """
        self.clear_accepted()

        if response and response.question == self:
            response.accepted = True
            response.save()
            return True
        else:
            return False

    accept.alters_data = True

    def states(self):
        """
        Handy for checking for mod bar button state.
        """
        return [self.status, 'lock' if self.locked else None]

    @property
    def url(self):
        return self.get_absolute_url()
コード例 #23
0
 def test_markuptextarea_used(self):
     self.assertTrue(isinstance(MarkupField().formfield().widget,
                                MarkupTextarea))
     self.assertTrue(isinstance(ArticleForm()['normal_field'].field.widget,
                                MarkupTextarea))
コード例 #24
0
ファイル: models.py プロジェクト: bihealth/sodar-core
class AdminAlert(models.Model):
    """An un-dismissable alert from a superuser to site users. Not dependent on
    project. Will expire after a set time."""

    #: Alert message to be shown for users
    message = models.CharField(
        max_length=255,
        unique=False,
        help_text='Alert message to be shown for users',
    )

    #: Superuser who has set the alert
    user = models.ForeignKey(
        AUTH_USER_MODEL,
        related_name='alerts',
        help_text='Superuser who has set the alert',
        on_delete=models.CASCADE,
    )

    #: Full description (optional, will be shown on a separate page)
    description = MarkupField(
        unique=False,
        blank=True,
        null=True,
        markup_type='markdown',
        help_text='Full description of alert '
        '(optional, will be shown on a separate page)',
    )

    #: Alert creation timestamp
    date_created = models.DateTimeField(auto_now_add=True,
                                        help_text='Alert creation timestamp')

    #: Alert expiration timestamp
    date_expire = models.DateTimeField(blank=False,
                                       null=False,
                                       help_text='Alert expiration timestamp')

    #: Alert status (for disabling the alert before expiration)
    active = models.BooleanField(
        default=True,
        help_text='Alert status (for disabling the alert before expiration)',
    )

    #: Require authorization to view alert
    require_auth = models.BooleanField(
        default=True, help_text='Require authorization to view alert')

    #: Adminalerts SODAR UUID
    sodar_uuid = models.UUIDField(default=uuid.uuid4,
                                  unique=True,
                                  help_text='Adminalerts SODAR UUID')

    def __str__(self):
        return '{}{}'.format(
            self.message,
            ' [ACTIVE]' if
            (self.active and self.date_expire > timezone.now()) else '',
        )

    def __repr__(self):
        values = (self.message, self.user.username, self.active)
        return 'AdminAlert({})'.format(', '.join(repr(v) for v in values))

    def is_active(self):
        """Return True if alert is active and has not expired"""
        return (True if
                (self.date_expire > timezone.now() and self.active) else False)

    def is_expired(self):
        """Return True if alert has expired"""
        return True if self.date_expire < timezone.now() else False
コード例 #25
0
class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Entry',
            fields=[
                ('id',
                 models.AutoField(verbose_name='ID',
                                  serialize=False,
                                  auto_created=True,
                                  primary_key=True)),
                ('created',
                 model_utils.fields.AutoCreatedField(
                     default=django.utils.timezone.now,
                     verbose_name='created',
                     editable=False)),
                ('modified',
                 model_utils.fields.AutoLastModifiedField(
                     default=django.utils.timezone.now,
                     verbose_name='modified',
                     editable=False)),
                ('title', models.CharField(max_length=500)),
                ('slug', models.SlugField(unique=True, editable=False)),
                ('content', MarkupField(default_markup_type='markdown')),
                ('is_published', models.BooleanField(default=False)),
                ('published_timestamp',
                 models.DateTimeField(null=True, editable=False, blank=True)),
                ('_content_rendered',
                 models.TextField(editable=False, blank=True)),
                ('author',
                 models.ForeignKey(editable=False,
                                   to=settings.AUTH_USER_MODEL,
                                   null=True,
                                   on_delete=models.CASCADE)),
            ],
            options={
                'verbose_name_plural': 'entries',
            },
            bases=(models.Model, ),
        ),
        migrations.CreateModel(
            name='EntryImage',
            fields=[
                ('id',
                 models.AutoField(verbose_name='ID',
                                  serialize=False,
                                  auto_created=True,
                                  primary_key=True)),
                ('created',
                 model_utils.fields.AutoCreatedField(
                     default=django.utils.timezone.now,
                     verbose_name='created',
                     editable=False)),
                ('modified',
                 model_utils.fields.AutoLastModifiedField(
                     default=django.utils.timezone.now,
                     verbose_name='modified',
                     editable=False)),
                ('image',
                 models.ImageField(upload_to=b'andablog/images', blank=True)),
                ('entry',
                 models.ForeignKey(to='andablog.Entry',
                                   on_delete=models.CASCADE)),
            ],
            options={
                'abstract': False,
            },
            bases=(models.Model, ),
        ),
    ]
コード例 #26
0
class BlogEntry(models.Model):
    """Each blog entry.
    Title: Post title.
    Slug: Post slug.
          These two if not given are inferred directly from entry text.
    text = The main data for the post.
    summary = The summary for the text. probably can be derived from text,
              but we dont want do do that each time main page is displayed.
    created_on = The date this entry was created. Defaults to now.
    Created by: The user who wrote this.
    is_page: Is this a page or a post? Pages are the more important posts,
             which might be displayed differently. Defaults to false.
    is_published: Is this page published.
                  If yes then we would display this on site, otherwise no.
                  Defaults to true.
    comments_allowed: Are comments allowed on this post? Defaults to True
    is_rte: Was this post done using a Rich text editor?"""

    title = models.CharField(max_length=100)
    slug = models.SlugField()
    text = MarkupField(default_markup_type=getattr(settings,
                                                   'DEFAULT_MARKUP_TYPE',
                                                   'plain'),
                       markup_choices=getattr(settings, "MARKUP_RENDERERS",
                                              DEFAULT_MARKUP_TYPES))
    summary = models.TextField()
    created_on = models.DateTimeField(default=datetime.max, editable=False)
    created_by = models.ForeignKey(User, unique=False)
    is_page = models.BooleanField(default=False)
    is_published = models.BooleanField(default=True)
    publish_date = models.DateTimeField()
    comments_allowed = models.BooleanField(default=True)
    is_rte = models.BooleanField(default=False)

    meta_keywords = models.TextField(blank=True, null=True)
    meta_description = models.TextField(blank=True, null=True)

    tags = TaggableManager()

    default = models.Manager()
    objects = BlogPublishedManager()

    class Meta:
        ordering = ['-created_on']
        verbose_name_plural = 'Blog entries'

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        if self.title is None or self.title == '':
            self.title = _infer_title_or_slug(self.text.raw)

        if self.slug is None or self.slug == '':
            self.slug = slugify(self.title)

        i = 1
        while True:
            created_slug = self.create_slug(self.slug, i)
            slug_count = BlogEntry.objects.filter(slug__exact=created_slug).exclude(pk=self.pk)
            if not slug_count:
                break
            i += 1
        self.slug = created_slug

        if not self.summary:
            self.summary = _generate_summary(self.text.raw)
        if not self.meta_keywords:
            self.meta_keywords = self.summary
        if not self.meta_description:
            self.meta_description = self.summary

        if self.is_published:
            #default value for created_on is datetime.max whose year is 9999
            if self.created_on.year == 9999:
                self.created_on = self.publish_date
        # Call the "real" save() method.
        super(BlogEntry, self).save(*args, **kwargs)

    def create_slug(self, initial_slug, i=1):
        if not i == 1:
            initial_slug += "-%s" % (i,)
        return initial_slug

    def get_absolute_url(self):
        return reverse('blogango_details',
                       kwargs={'year': self.created_on.strftime('%Y'),
                               'month': self.created_on.strftime('%m'),
                               'slug': self.slug})

    def get_edit_url(self):
        return reverse('blogango_admin_entry_edit', args=[self.id])

    def get_num_comments(self):
        cmnt_count = Comment.objects.filter(comment_for=self, is_spam=False).count()
        return cmnt_count

    def get_num_reactions(self):
        reaction_count = Reaction.objects.filter(comment_for=self).count()
        return reaction_count
コード例 #27
0
class Release(models.Model):
    version = models.CharField(max_length=50, unique=True)
    version_num = models.IntegerField(default=0, unique=True)
    release_notes = MarkupField(default_markup_type='markdown')
    stable = models.BooleanField(default=False, db_index=True)
    snapshot = models.BooleanField(default=False, db_index=True)
    date = models.DateTimeField(db_index=True, default=timezone.now)

    purged = False

    class Meta(object):
        ordering = ['-version_num']

    def __unicode__(self):
        return self.version

    def get_absolute_url(self):
        if self.snapshot:
            return reverse('downloads')
        return reverse('release', kwargs={'version': self.version})

    def simpledownload(self):
        try:
            return self.download_set.get(
                filename__endswith='-all-languages.zip')
        except Download.DoesNotExist:
            try:
                return self.download_set.all()[0]
            except IndexError:
                return None

    @staticmethod
    def parse_version(version):
        if '+' in version:
            # Snapshots, eg. 4.7+snapshot
            parts = [int(x) for x in version.split('+')[0].split('.')]
            assert len(parts) == 2
            return (100000000 * parts[0] + 1000000 * parts[1])
        if '-' in version:
            version, suffix = version.split('-')
            if suffix.startswith('alpha'):
                suffix_num = int(suffix[5:])
            elif suffix.startswith('beta'):
                suffix_num = 10 + int(suffix[4:])
            elif suffix.startswith('rc'):
                suffix_num = 50 + int(suffix[2:])
            else:
                raise ValueError(version)
        else:
            suffix_num = 99
            version = version
        parts = [int(x) for x in version.split('.')]
        if len(parts) == 2:
            parts.append(0)
        if len(parts) == 3:
            parts.append(0)
        assert len(parts) == 4
        return (100000000 * parts[0] + 1000000 * parts[1] + 10000 * parts[2] +
                100 * parts[3] + suffix_num)

    def save(self, *args, **kwargs):
        self.version_num = self.parse_version(self.version)
        self.stable = self.version_num % 100 == 99
        super(Release, self).save(*args, **kwargs)

    def get_version_suffix(self):
        '''
        Returns suffix for a version.
        '''
        for match, result in VERSION_INFO:
            if self.version.find(match) != -1:
                return result
        return ''

    def get_php_versions(self):
        if self.version[:3] == '5.1':
            return '>=7.1,<7.3'
        elif self.version[:3] == '5.0':
            return '>=7.1,<7.3'
        elif self.version[:3] == '4.9':
            return '>=5.5,<7.3'
        elif self.version[:3] == '4.8':
            return '>=5.5,<7.3'
        elif self.version[:3] == '4.7':
            return '>=5.5,<7.3'
        elif self.version[:3] == '4.6':
            return '>=5.5,<7.2'
        elif self.version[:3] == '4.5':
            return '>=5.5,<7.1'
        elif self.version[:3] == '4.4':
            return '>=5.3,<7.1'
        elif self.version[:3] == '4.3':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.2':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.1':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.0':
            return '>=5.2,<5.3'

    def get_mysql_versions(self):
        if self.version[:3] == '5.1':
            return '>=5.5'
        elif self.version[:3] == '5.0':
            return '>=5.5'
        elif self.version[:3] == '4.9':
            return '>=5.5'
        elif self.version[:3] == '4.8':
            return '>=5.5'
        elif self.version[:3] == '4.7':
            return '>=5.5'
        elif self.version[:3] == '4.6':
            return '>=5.5'
        elif self.version[:3] == '4.5':
            return '>=5.5'
        elif self.version[:3] == '4.4':
            return '>=5.5'
        elif self.version[:3] == '4.3':
            return '>=5.5'
        elif self.version[:3] == '4.2':
            return '>=5.5'
        elif self.version[:3] == '4.1':
            return '>=5.5'
        elif self.version[:3] == '4.0':
            return '>=5.0'

    def get_version_info(self):
        '''
        Returns description to the phpMyAdmin version.
        '''
        text = ''
        if self.version[:2] == '0.':
            text = 'Historical release.'
        elif self.version[:2] == '1.':
            text = 'Historical release.'
        elif self.version[:2] == '2.':
            text = 'Version compatible with PHP 4+ and MySQL 3+.'
        elif self.version[:2] == '3.':
            text = ('Frames version not requiring Javascript. ' +
                    'Requires PHP 5.2 and MySQL 5. ' +
                    'Supported for security fixes only, until Jan 1, 2014.')
        elif self.version[:3] == '5.1':
            text = (
                'Future version compatible with PHP 7.1 and newer and MySQL 5.5 and newer. '
            )
        elif self.version[:3] == '5.0':
            text = (
                'Future version compatible with PHP 7.1 and newer and MySQL 5.5 and newer. '
            )
        elif self.version[:3] == '4.9':
            text = (
                'Current version compatible with PHP 5.5 to 7.2 and MySQL 5.5 and newer. '
            )
        elif self.version[:3] == '4.8':
            text = (
                'Older version compatible with PHP 5.5 to 7.2 and MySQL 5.5 and newer. '
                + 'Was supported until June 4, 2019.')
        elif self.version in ('4.7.0', '4.7.1', '4.7.2', '4.7.3', '4.7.0-rc1',
                              '4.7.0-beta1'):
            text = (
                'Older version compatible with PHP 5.5 to 7.1 and MySQL 5.5 and newer. '
                + 'Was supported until April 7, 2018.')
        elif self.version[:3] == '4.7':
            text = (
                'Older version compatible with PHP 5.5 to 7.2 and MySQL 5.5 and newer. '
                + 'Was supported until April 7, 2018.')
        elif self.version[:3] == '4.6':
            text = (
                'Older version compatible with PHP 5.5 to 7.1 and MySQL 5.5 and newer. '
                + 'Was supported until April 1, 2017.')
        elif self.version[:3] == '4.5':
            text = (
                'Older version compatible with PHP 5.5 to 7.0 and MySQL 5.5. '
                + 'Was supported until April 1, 2016.')
        elif self.version[:3] == '4.4':
            text = (
                'Older version compatible with PHP 5.3.7 to 7.0 and MySQL 5.5. '
                + 'Was supported until October 1, 2016.')
        elif self.version[:3] == '4.3':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Was supported until October 1, 2015.')
        elif self.version[:3] == '4.2':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Was supported until July 1, 2015.')
        elif self.version[:3] == '4.1':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Was supported until January 1, 2015.')
        elif self.version[:3] == '4.0':
            text = ('Older version compatible with PHP 5.2 and MySQL 5. ' +
                    'Does not support PHP 5.5 or newer. ' +
                    'Was supported until April 1, 2017.')
        text += self.get_version_suffix()

        return text

    def get_downloads(self):
        """Lists downloads, making all-languages.zip first"""
        dlset = self.download_set
        return (list(dlset.filter(filename__endswith='all-languages.zip')) +
                list(dlset.exclude(filename__endswith='all-languages.zip')))
コード例 #28
0
ファイル: models.py プロジェクト: olea/PyConES-2015
class Presentation(models.Model):

    slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr", on_delete=SET_NULL)
    title = models.CharField(max_length=100, default="", blank=True)
    description = MarkupField(default="", blank=True, default_markup_type='markdown')
    abstract = MarkupField(default="", blank=True, default_markup_type='markdown')
    speaker = models.ForeignKey("speakers.Speaker", related_name="presentations")
    additional_speakers = models.ManyToManyField("speakers.Speaker", related_name="copresentations",
                                                 blank=True)
    cancelled = models.BooleanField(default=False)
    proposal_base = models.OneToOneField("proposals.ProposalBase", related_name="presentation")
    section = models.ForeignKey("conference.Section", related_name="presentations")

    video_url = models.URLField(_("video URL"), blank=True, null=True)

    keynote_url = models.URLField(_("keynote URL"), blank=True, null=True)
    keynote = models.FileField(_("keynote file"), blank=True, null=True, upload_to="keynotes")

    @property
    def number(self):
        return self.proposal.number

    @property
    def proposal(self):
        if self.proposal_base_id is None:
            return None
        return ProposalBase.objects.get_subclass(pk=self.proposal_base_id)

    def speakers(self):
        yield self.speaker
        for speaker in self.additional_speakers.all():
            if speaker.user:
                yield speaker

    def get_title(self):
        if self.title:
            return self.title
        return self.proposal_base.title

    def get_description(self):
        if self.description.raw:
            return self.description
        return self.proposal_base.description

    def get_abstract(self):
        if self.abstract.raw:
            return self.abstract
        return self.proposal_base.abstract

    def get_video_url(self):
        if not self.video_url:
            return ""
        return self.video_url

    def get_keynote_url(self):
        if self.keynote and not self.keynote_url:
            return self.keynote.url
        elif self.keynote_url:
            return self.keynote_url
        return ""

    def __str__(self):
        return "#%s %s (%s)" % (self.number, self.get_title(), self.speaker)

    class Meta:
        ordering = ["slot"]
コード例 #29
0
class Nomination(models.Model):
    def __str__(self):
        return f"{self.name} <{self.email}>"

    election = models.ForeignKey(Election, on_delete=models.CASCADE)

    name = models.CharField(max_length=1024, blank=False, null=True)
    email = models.CharField(max_length=1024, blank=False, null=True)
    previous_board_service = models.CharField(max_length=1024,
                                              blank=False,
                                              null=True)
    employer = models.CharField(max_length=1024, blank=False, null=True)
    other_affiliations = models.CharField(max_length=2048,
                                          blank=True,
                                          null=True)
    nomination_statement = MarkupField(escape_html=True,
                                       markup_type="markdown",
                                       blank=False,
                                       null=True)

    nominator = models.ForeignKey(User,
                                  related_name="nominations_made",
                                  on_delete=models.CASCADE)
    nominee = models.ForeignKey(
        Nominee,
        related_name="nominations",
        null=True,
        on_delete=models.CASCADE,
        blank=True,
    )

    accepted = models.BooleanField(null=False, default=False)
    approved = models.BooleanField(null=False, default=False)

    def get_absolute_url(self):
        return reverse(
            "nominations:nomination_detail",
            kwargs={
                "election": self.election.slug,
                "pk": self.pk
            },
        )

    def get_edit_url(self):
        return reverse(
            "nominations:nomination_edit",
            kwargs={
                "election": self.election.slug,
                "pk": self.pk
            },
        )

    def editable(self, user=None):
        if (self.nominee and user == self.nominee.user
                and self.election.nominations_open):
            return True

        if (user == self.nominator and not (self.accepted or self.approved)
                and self.election.nominations_open):
            return True

        return False

    def visible(self, user=None):
        if self.accepted and self.approved and not self.election.nominations_open_at:
            return True

        if user is None:
            return False

        if user.is_staff:
            return True

        if user == self.nominator:
            return True

        if self.nominee and user == self.nominee.user:
            return True

        return False
コード例 #30
0
ファイル: models.py プロジェクト: pkdevbox/website-2
class Release(models.Model):
    version = models.CharField(max_length=50, unique=True)
    version_num = models.IntegerField(default=0, unique=True)
    release_notes = MarkupField(default_markup_type='markdown')
    stable = models.BooleanField(default=False, db_index=True)
    date = models.DateTimeField(db_index=True, default=timezone.now)

    class Meta(object):
        ordering = ['-version_num']

    def __unicode__(self):
        return self.version

    @models.permalink
    def get_absolute_url(self):
        return ('release', (), {'version': self.version})

    def simpledownload(self):
        try:
            return self.download_set.get(
                filename__endswith='-all-languages.zip')
        except Download.DoesNotExist:
            return self.download_set.all()[0]

    @staticmethod
    def parse_version(version):
        if '-' in version:
            version, suffix = version.split('-')
            if suffix.startswith('alpha'):
                suffix_num = int(suffix[5:])
            elif suffix.startswith('beta'):
                suffix_num = 10 + int(suffix[4:])
            elif suffix.startswith('rc'):
                suffix_num = 50 + int(suffix[2:])
            else:
                raise ValueError(version)
        else:
            suffix_num = 99
            version = version
        parts = [int(x) for x in version.split('.')]
        if len(parts) == 2:
            parts.append(0)
        if len(parts) == 3:
            parts.append(0)
        assert len(parts) == 4
        return (100000000 * parts[0] + 1000000 * parts[1] + 10000 * parts[2] +
                100 * parts[3] + suffix_num)

    def save(self, *args, **kwargs):
        self.version_num = self.parse_version(self.version)
        self.stable = self.version_num % 100 == 99
        super(Release, self).save(*args, **kwargs)

    def get_version_suffix(self):
        '''
        Returns suffix for a version.
        '''
        for match, result in VERSION_INFO:
            if self.version.find(match) != -1:
                return result
        return ''

    def get_php_versions(self):
        if self.version[:3] == '4.5':
            return '>=5.5,<7.1'
        elif self.version[:3] == '4.4':
            return '>=5.3,<7.1'
        elif self.version[:3] == '4.3':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.2':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.1':
            return '>=5.3,<7.0'
        elif self.version[:3] == '4.0':
            return '>=5.2,<5.3'

    def get_mysql_versions(self):
        if self.version[:3] == '4.5':
            return '>=5.5'
        elif self.version[:3] == '4.4':
            return '>=5.5'
        elif self.version[:3] == '4.3':
            return '>=5.5'
        elif self.version[:3] == '4.2':
            return '>=5.5'
        elif self.version[:3] == '4.1':
            return '>=5.5'
        elif self.version[:3] == '4.0':
            return '>=5.0'

    def get_version_info(self):
        '''
        Returns description to the phpMyAdmin version.
        '''
        if self.version[:2] == '1.':
            text = 'Historical release.'
        elif self.version[:2] == '2.':
            text = 'Version compatible with PHP 4+ and MySQL 3+.'
        elif self.version[:2] == '3.':
            text = ('Frames version not requiring Javascript. ' +
                    'Requires PHP 5.2 and MySQL 5. ' +
                    'Supported for security fixes only, until Jan 1, 2014.')
        elif self.version[:3] == '4.5':
            text = 'Current version compatible with PHP 5.5 to 7.0 and MySQL 5.5.'
        elif self.version[:3] == '4.4':
            text = (
                'Older version compatible with PHP 5.3.7 to 7.0 and MySQL 5.5. '
                + 'Supported for security fixes only, until April 1, 2016')
        elif self.version[:3] == '4.3':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Supported for security fixes only, until Oct 1, 2015.')
        elif self.version[:3] == '4.2':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Supported for security fixes only, until Jul 1, 2015.')
        elif self.version[:3] == '4.1':
            text = ('Older version compatible with PHP 5.3 and MySQL 5.5. ' +
                    'Supported for security fixes only, until Jan 1, 2015.')
        elif self.version[:3] == '4.0':
            text = ('Older version compatible with PHP 5.2 and MySQL 5. ' +
                    'Supported for security fixes only, until Apr 1, 2017.')
        text += self.get_version_suffix()

        return text