Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
L10N_METRIC_CODE = 'general l10n:coverage'
AOA_CONTRIBUTORS_METRIC_CODE = 'general aoa:contributors'
SUPPORT_FORUM_CONTRIBUTORS_METRIC_CODE = 'general supportforum:contributors'
KB_ENUS_CONTRIBUTORS_METRIC_CODE = 'general kb:en-US:contributors'
KB_L10N_CONTRIBUTORS_METRIC_CODE = 'general kb:l10n:contributors'
class MetricKind(ModelBase):
"""A programmer-readable identifier of a metric, like 'clicks: search'"""
code = CharField(max_length=255, unique=True)
def __unicode__(self):
return self.code
class Metric(ModelBase):
"""A single numeric measurement aggregated over a span of time.
For example, the number of hits to a page during a specific week.
"""
# If we need to (and I would prefer to avoid this, because it wrecks the
# consistent semantics of rows--some will be aggregations and others will
# not), we can lift the unique constraint on kind/start/end for things that
# are collected in realtime and can't be immediately bucketed. However, in
# such cases it would probably be nicer to our future selves to put them in
# a separate store (table or whatever) until bucketing.
# In the design of this table, we trade off constraints for generality.
# There's no way to have the DB prove, for example, that both halves of a
# clickthrough rate ratio will always exist, but the app can make sure it's
# true upon inserting them.
log = logging.getLogger('k.wiki')
class TitleCollision(Exception):
"""An attempt to create two pages of the same title in one locale"""
class SlugCollision(Exception):
"""An attempt to create two pages of the same slug in one locale"""
class _NotDocumentView(Exception):
"""A URL not pointing to the document view was passed to from_url()."""
class Document(NotificationsMixin, ModelBase, BigVocabTaggableMixin,
SearchMixin, DocumentPermissionMixin):
"""A localized knowledgebase document, not revision-specific."""
title = models.CharField(max_length=255, db_index=True)
slug = models.CharField(max_length=255, db_index=True)
# Is this document a template or not?
is_template = models.BooleanField(default=False, editable=False,
db_index=True)
# Is this document localizable or not?
is_localizable = models.BooleanField(default=True, db_index=True)
# TODO: validate (against settings.SUMO_LANGUAGES?)
locale = LocaleField(default=settings.WIKI_DEFAULT_LANGUAGE, db_index=True)
# Latest approved revision. L10n dashboard depends on this being so (rather
# than being able to set it to earlier approved revisions). (Remove "+" to
class HelpfulVoteMetadata(ModelBase):
"""Metadata for article votes."""
vote = models.ForeignKey(HelpfulVote, related_name='metadata')
key = models.CharField(max_length=40, db_index=True)
value = models.CharField(max_length=1000)
class ImportantDate(ModelBase):
"""Important date that shows up globally on metrics graphs."""
text = models.CharField(max_length=100)
date = models.DateField(db_index=True)
class Locale(ModelBase):
"""A locale supported in the KB."""
locale = models.CharField(max_length=7, db_index=True)
leaders = models.ManyToManyField(
User, blank=True, related_name='locales_leader')
reviewers = models.ManyToManyField(
User, blank=True, related_name='locales_reviewer')
editors = models.ManyToManyField(
User, blank=True, related_name='locales_editor')
class Meta:
ordering = ['locale']
def get_absolute_url(self):
return reverse('wiki.locale_details', args=[self.locale])
def __unicode__(self):
class HelpfulVote(ModelBase):
"""Helpful or Not Helpful vote on Revision."""
revision = models.ForeignKey(Revision, related_name='poll_votes')
helpful = models.BooleanField(default=False)
created = models.DateTimeField(default=datetime.now, db_index=True)
creator = models.ForeignKey(User, related_name='poll_votes', null=True)
anonymous_id = models.CharField(max_length=40, db_index=True)
user_agent = models.CharField(max_length=1000)
def add_metadata(self, key, value):
HelpfulVoteMetadata.objects.create(vote=self, key=key, value=value)
class HelpfulVoteMetadata(ModelBase):
"""Metadata for article votes."""
vote = models.ForeignKey(HelpfulVote, related_name='metadata')
key = models.CharField(max_length=40, db_index=True)
value = models.CharField(max_length=1000)
class ImportantDate(ModelBase):
"""Important date that shows up globally on metrics graphs."""
text = models.CharField(max_length=100)
date = models.DateField(db_index=True)
class Locale(ModelBase):
"""A locale supported in the KB."""
locale = models.CharField(max_length=7, db_index=True)
leaders = models.ManyToManyField(
Because this works off of a set, it naturally de-dupes the tasks,
so if four tasks get tossed into the set that are identical, we
execute it only once.
"""
tasks = _local_tasks()
for fun, args in tasks:
fun(*args)
tasks.clear()
signals.request_finished.connect(generate_tasks)
class Record(ModelBase):
"""Record for the reindexing log"""
starttime = models.DateTimeField(null=True)
endtime = models.DateTimeField(null=True)
text = models.CharField(max_length=255)
class Meta:
permissions = (
('reindex', 'Can run a full reindexing'),
)
def delta(self):
"""Returns the timedelta"""
if self.starttime and self.endtime:
return self.endtime - self.starttime
return None
import os
from django.conf import settings
from django.db import models
from sumo.models import ModelBase
class Product(ModelBase):
title = models.CharField(max_length=255, db_index=True)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField(upload_to=settings.PRODUCT_IMAGE_PATH, null=True,
blank=True,
max_length=settings.MAX_FILEPATH_LENGTH)
# Dictates the order in which products are displayed in product
# lists.
display_order = models.IntegerField()
# Whether or not this product is visible in the ui to users.
visible = models.BooleanField(default=False)
class Meta(object):
ordering = ['display_order']
from django.db.models import (CharField, DateField, ForeignKey,
PositiveIntegerField)
from sumo.models import ModelBase
VISITORS_METRIC_CODE = 'general keymetrics:visitors'
L10N_METRIC_CODE = 'general l10n:coverage'
AOA_CONTRIBUTORS_METRIC_CODE = 'general aoa:contributors'
SUPPORT_FORUM_CONTRIBUTORS_METRIC_CODE = 'general supportforum:contributors'
KB_ENUS_CONTRIBUTORS_METRIC_CODE = 'general kb:en-US:contributors'
KB_L10N_CONTRIBUTORS_METRIC_CODE = 'general kb:l10n:contributors'
class MetricKind(ModelBase):
"""A programmer-readable identifier of a metric, like 'clicks: search'"""
code = CharField(max_length=255, unique=True)
def __unicode__(self):
return self.code
class Metric(ModelBase):
"""A single numeric measurement aggregated over a span of time.
For example, the number of hits to a page during a specific week.
"""
# If we need to (and I would prefer to avoid this, because it wrecks the
# consistent semantics of rows--some will be aggregations and others will
# not), we can lift the unique constraint on kind/start/end for things that
verbose_name=_lazy(u'City'))
locale = LocaleField(default=settings.LANGUAGE_CODE,
verbose_name=_lazy(u'Preferred language'))
class Meta(object):
permissions = (('view_karma_points', 'Can view karma points'),
('deactivate_users', 'Can deactivate users'),)
def __unicode__(self):
return unicode(self.user)
def get_absolute_url(self):
return reverse('users.profile', args=[self.user_id])
class Setting(ModelBase):
"""User specific value per setting"""
user = models.ForeignKey(User, verbose_name=_lazy(u'User'),
related_name='settings')
name = models.CharField(max_length=100)
value = models.CharField(blank=True, max_length=60,
verbose_name=_lazy(u'Value'))
class Meta(object):
unique_together = (('user', 'name'),)
def __unicode__(self):
return u'%s %s:%s' % (self.user, self.name, self.value or u'[none]')
@classmethod
def get_for_user(cls, user, name):
register_for_indexing('wiki', Document)
register_for_indexing(
'wiki',
Document.topics.through,
m2m=True)
register_for_indexing(
'wiki',
Document.products.through,
m2m=True)
MAX_REVISION_COMMENT_LENGTH = 255
class Revision(ModelBase):
"""A revision of a localized knowledgebase document"""
document = models.ForeignKey(Document, related_name='revisions')
summary = models.TextField() # wiki markup
content = models.TextField() # wiki markup
# Keywords are used mostly to affect search rankings. Moderators may not
# have the language expertise to translate keywords, so we put them in the
# Revision so the translators can handle them:
keywords = models.CharField(max_length=255, blank=True)
created = models.DateTimeField(default=datetime.now)
reviewed = models.DateTimeField(null=True)
# The significance of the initial revision of a document is NULL.
significance = models.IntegerField(choices=SIGNIFICANCES, null=True)
reviewers = models.ManyToManyField(
User, blank=True, related_name='locales_reviewer')
editors = models.ManyToManyField(
User, blank=True, related_name='locales_editor')
class Meta:
ordering = ['locale']
def get_absolute_url(self):
return reverse('wiki.locale_details', args=[self.locale])
def __unicode__(self):
return self.locale
class DocumentLink(ModelBase):
"""Model a link between documents.
If article A contains [[Link:B]], then `linked_to` is B,
`linked_from` is A, and kind is 'link'.
"""
linked_to = models.ForeignKey(Document,
related_name='documentlink_from_set')
linked_from = models.ForeignKey(Document,
related_name='documentlink_to_set')
kind = models.CharField(max_length=16)
class Meta:
unique_together = ('linked_from', 'linked_to')
def __repr__(self):
return ('' %