Exemple #1
0
class Presentation(models.Model):

    title = models.CharField(max_length=100)
    name = models.SlugField(max_length=50, unique=True)
    owner = models.ForeignKey(User)
    hidden = models.BooleanField(default=False)
    source = models.CharField(max_length=1024, null=True)
    description = models.TextField(blank=True, null=True)
    password = models.CharField(max_length=32, blank=True, null=True)
    fieldset = models.ForeignKey(FieldSet, null=True)
    hide_default_data = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    ownedwrapper = generic.GenericRelation('util.OwnedWrapper')

    def save(self, **kwargs):
        unique_slug(self,
                    slug_source='title',
                    slug_field='name',
                    check_current_slug=kwargs.get('force_insert'))
        super(Presentation, self).save(kwargs)

    def get_absolute_url(self, edit=False):
        return reverse(edit and 'presentation-edit' or 'presentation-view',
                       kwargs={
                           'id': self.id,
                           'name': self.name
                       })

    def override_dates(self, created=None, modified=None):
        cursor = connection.cursor()
        if created and self.id:
            cursor.execute(
                "UPDATE %s SET created=%%s WHERE id=%%s" % self._meta.db_table,
                [created, self.id])
        if modified and self.id:
            cursor.execute(
                "UPDATE %s SET modified=%%s WHERE id=%%s" %
                self._meta.db_table, [modified, self.id])

    def cached_items(self):
        if not hasattr(self, '_cached_items'):
            self._cached_items = tuple(self.items.all())
        return self._cached_items

    def records(self):
        return [i.record for i in self.items.all()]

    def visible_item_count(self):
        return len(filter(lambda i: not i.hidden, self.cached_items()))

    def hidden_item_count(self):
        return len(filter(lambda i: i.hidden, self.cached_items()))

    def duplicate(self):
        dup = Presentation()
        dup.title = self.title
        dup.owner = self.owner
        dup.hidden = self.hidden
        dup.description = self.description
        dup.password = self.password
        dup.fieldset = self.fieldset
        dup.hide_default_data = self.hide_default_data
        return dup

    @staticmethod
    def check_passwords(passwords):
        if passwords:
            q = reduce(lambda a, b: a | b,
                       (Q(id=id, password=password)
                        for id, password in passwords.iteritems()))
            return Presentation.objects.filter(q).values_list('id', flat=True)
        else:
            return []

    def verify_password(self, request):
        self.unlocked = (self.owner == request.user) or (
            not self.password) or (request.session.get(
                'passwords', dict()).get(self.id) == self.password)
        return self.unlocked

    @staticmethod
    def published_Q(owner=None):
        publish_permission = Permission.objects.get(
            codename='publish_presentations')
        valid_publishers = User.objects.filter(
            Q(id__in=publish_permission.user_set.all())
            | Q(groups__id__in=publish_permission.group_set.all())
            | Q(is_superuser=True))
        q = Q(owner__in=valid_publishers) & Q(hidden=False)
        if owner and not owner.is_anonymous():
            return q | Q(
                id__in=filter_by_access(owner, Presentation, manage=True))
        else:
            return q

    @staticmethod
    def get_by_id_for_request(id, request):
        p = (filter_by_access(request.user, Presentation).filter(
            Presentation.published_Q(request.user), id=id))
        return p[0] if p and p[0].verify_password(request) else None

    class Meta:
        permissions = (("publish_presentations",
                        "Can publish presentations"), )
Exemple #2
0
class View(Entity):
    """
	:class:`View` is an abstract model that represents an item which can be "rendered", generally in response to an :class:`HttpRequest`.
	
	"""
    #: A generic relation back to nodes.
    nodes = generic.GenericRelation(Node,
                                    content_type_field='view_content_type',
                                    object_id_field='view_object_id')

    #: An attribute on the class which defines whether this :class:`View` can handle subpaths. Default: ``False``
    accepts_subpath = False

    @classmethod
    def handles_subpath(cls, subpath):
        """Returns True if the :class:`View` handles the given subpath, and False otherwise."""
        if not cls.accepts_subpath and subpath != "/":
            return False
        return True

    def reverse(self,
                view_name=None,
                args=None,
                kwargs=None,
                node=None,
                obj=None):
        """
		If :attr:`accepts_subpath` is True, try to reverse a URL using the given parameters using ``self`` as the urlconf.
		
		If ``obj`` is provided, :meth:`get_reverse_params` will be called and the results will be combined with any ``view_name``, ``args``, and ``kwargs`` that may have been passed in.
		
		:param view_name: The name of the view to be reversed.
		:param args: Extra args for reversing the view.
		:param kwargs: A dictionary of arguments for reversing the view.
		:param node: The node whose subpath this is.
		:param obj: An object to be passed to :meth:`get_reverse_params` to generate a view_name, args, and kwargs for reversal.
		:returns: A subpath beyond the node that reverses the view, or an absolute url that reverses the view if a node was passed in.
		:except philo.exceptions.ViewDoesNotProvideSubpaths: if :attr:`accepts_subpath` is False
		:except philo.exceptions.ViewCanNotProvideSubpath: if a reversal is not possible.
		
		"""
        if not self.accepts_subpath:
            raise ViewDoesNotProvideSubpaths

        if obj is not None:
            # Perhaps just override instead of combining?
            obj_view_name, obj_args, obj_kwargs = self.get_reverse_params(obj)
            if view_name is None:
                view_name = obj_view_name
            args = list(obj_args) + list(args or [])
            obj_kwargs.update(kwargs or {})
            kwargs = obj_kwargs

        try:
            subpath = reverse(view_name,
                              urlconf=self,
                              args=args or [],
                              kwargs=kwargs or {})
        except NoReverseMatch, e:
            raise ViewCanNotProvideSubpath(e.message)

        if node is not None:
            return node.construct_url(subpath)
        return subpath
Exemple #3
0
class BaseContent(models.Model):
    """Parent class for every content model.
    """
    name = models.CharField(_('name'), max_length=250,
                             db_index=True, blank=False)
    slug = AutoSlugField(populate_from='name', unique=True, db_index=True,
                         always_update=False, editable=True, blank=True)
    published =  models.BooleanField(_('published'), default=True)
    # user that uploads the content
    user = models.ForeignKey(User, editable=False, blank=True, null=True)
    related_contents = generic.GenericRelation(RelatedContent,
                                               object_id_field='self_id',
                                               content_type_field='self_type')
    creation_date = models.DateTimeField(_('creation date'), editable=True,
                                         default=datetime.now)
    modification_date = models.DateTimeField(_('modification date'), auto_now=True,
                                             editable=False, default=datetime.now)
    allow_comments = models.CharField(_('allow comments'), max_length=4,
                                choices = (
                                    ('SITE',_('default')),
                                    ('YES',_('enabled')),
                                    ('NO',_('disabled'))
                                ), default='SITE')
    comments = generic.GenericRelation(Comment, object_id_field="object_pk")
    show_author = models.CharField(_('show author'), max_length=6, default='SITE',
                                   choices = (
                                        ('AUTHOR', _('author')),
                                        ('USER', _('user if author is empty')),
                                        ('SITE', _('default'))
                                   ), help_text=_('Select which field to use to show as author of this content.'))

    def get_absolute_url(self):
        return '/%s/%s/' % (self.get_object_name(), self.slug)

    @classmethod
    def get_app_label(cls):
        return get_app_label(cls)

    @classmethod
    def get_object_name(cls):
        return get_object_name(cls)

    @classmethod
    def get_verbose_name(cls):
        return cls._meta.verbose_name

    @property
    def get_last_change_date(self):
        return self.modification_date

    def translations(self):
        trans_links = []

        for lang in settings.LANGUAGES:
            # we look for the number rosetta uses to identity an app
            # which can be different for each language
            lang_code = lang[0]
            app_idx = None
            for i, path in enumerate(find_pos(lang_code)):
                project_path = cyclope.settings.CYCLOPE_PROJECT_PATH
                common_prefix = os.path.commonprefix([path, project_path])
                if common_prefix == project_path:
                    # we found the position for our app
                    app_idx = i
                    break
            if app_idx is not None:
                signature = "%s/%s/%s/" % (self._meta.app_label,
                                       self._meta.module_name, self.slug)
                trans_links.append(
                    u'<a href="/rosetta/select/%s/%s/?query=%s">%s</a> '
                    % (lang[0], app_idx, signature, _(lang[1])))
        trans_links = ''.join(trans_links)
        return trans_links

    def pictures(self):
        if getattr(self, "_pictures", False) is not False:
            return self._pictures
        self._pictures = None
        if self.related_contents:
            pic_model = models.get_model('medialibrary', 'picture')
            ctype = ContentType.objects.get_for_model(pic_model)
            rel_contents = self.related_contents.filter(other_type__pk=ctype.pk)
            self._pictures = [ r.other_object for r in rel_contents ]
        return self._pictures

    def get_author_or_user(self):
        """
        Returns the author or the user that created the content as stated on
        self.show_author and/or SiteSettings.show_author.
        """
        ret = None
        author = getattr(self, "author", None)
        site_settings = get_singleton(SiteSettings)
        if self.show_author == "AUTHOR" or (self.show_author == "SITE" and
                                            site_settings.show_author == "AUTHOR"):
            ret = author
        elif self.show_author == "USER" or (self.show_author == "SITE" and
                                            site_settings.show_author == "USER"):
            ret = author or self.user  # If the ir no author it defaults to user
        return ret

    translations.allow_tags = True
    translations.short_description = _('translations')

    def __unicode__(self):
        return self.name

    class Meta:
        abstract = True
Exemple #4
0
class ShippingMethodCriterion(models.Model, Criterion):
    """A criterion for the shipping method.
    """
    operator = models.PositiveIntegerField(_(u"Operator"), blank=True, null=True, choices=SELECT_OPERATORS)
    shipping_methods = models.ManyToManyField(ShippingMethod, verbose_name=_(u"Shipping methods"))

    criteria_objects = generic.GenericRelation(CriteriaObjects,
        object_id_field="criterion_id", content_type_field="criterion_type")

    def __unicode__(self):
        values = []
        for value in self.value.all():
            values.append(value.name)

        return "%s %s %s" % ("Shipping", self.get_operator_display(), ", ".join(values))

    @property
    def content_type(self):
        """Returns the content_type of the criterion as lower string.

        This is for instance used to select the appropriate form for the
        criterion.
        """
        return u"shipping_method"

    @property
    def name(self):
        """Returns the descriptive name of the criterion.
        """
        return _(u"Shipping method")

    def is_valid(self, request, product=None):
        """Returns True if the criterion is valid.
        """
        # Check whether the criteria is part of a shipping method if so the
        # operator IS and IS_NOT are not allowed. This will later exluded by the
        # UID.

        # The reason why we have to check this is that the get_selected_shipping_method
        # checks for valid shipping methods and call this method again, so that
        # we get an infinte recursion.

        import lfs.shipping.utils
        content_object = self.criteria_objects.filter()[0].content
        if isinstance(content_object, ShippingMethod):
            is_shipping_method = True
        else:
            is_shipping_method = False

        if not is_shipping_method and self.operator == IS:
            shipping_method = lfs.shipping.utils.get_selected_shipping_method(request)
            return shipping_method in self.shipping_methods.all()
        elif not is_shipping_method and self.operator == IS_NOT:
            shipping_method = lfs.shipping.utils.get_selected_shipping_method(request)
            return shipping_method not in self.shipping_methods.all()
        elif self.operator == IS_VALID:
            for sm in self.shipping_methods.all():
                if not lfs.criteria.utils.is_valid(request, sm, product):
                    return False
            return True
        elif self.operator == IS_NOT_VALID:
            for sm in self.shipping_methods.all():
                if lfs.criteria.utils.is_valid(request, sm, product):
                    return False
            return True
        else:
            return False

    @property
    def value(self):
        """Returns the value of the criterion.
        """
        return self.shipping_methods

    def as_html(self, request, position):
        """Renders the criterion as html in order to be displayed within several
        forms.
        """
        selected_shipping_methods = self.shipping_methods.all()
        shipping_methods = []
        for sm in ShippingMethod.objects.filter(active=True):
            if sm in selected_shipping_methods:
                selected = True
            else:
                selected = False

            shipping_methods.append({
                "id": sm.id,
                "name": sm.name,
                "selected": selected,
            })

        return render_to_string("manage/criteria/shipping_method_criterion.html", RequestContext(request, {
            "id": "ex%s" % self.id,
            "operator": self.operator,
            "value": self.value,
            "position": position,
            "shipping_methods": shipping_methods,
        }))
Exemple #5
0
class Document2(models.Model):
    owner = models.ForeignKey(auth_models.User,
                              db_index=True,
                              verbose_name=_t('Owner'),
                              help_text=_t('Creator.'),
                              related_name='doc2_owner')
    name = models.CharField(default='', max_length=255)
    description = models.TextField(default='')
    uuid = models.CharField(default=uuid_default, max_length=36, db_index=True)
    type = models.CharField(
        default='',
        max_length=32,
        db_index=True,
        help_text=_t(
            'Type of document, e.g. Hive query, Oozie workflow, Search Dashboard...'
        ))

    data = models.TextField(default='{}')
    extra = models.TextField(default='')

    last_modified = models.DateTimeField(auto_now=True,
                                         db_index=True,
                                         verbose_name=_t('Time last modified'))
    version = models.SmallIntegerField(default=1,
                                       verbose_name=_t('Document version'),
                                       db_index=True)
    is_history = models.BooleanField(default=False, db_index=True)

    tags = models.ManyToManyField('self', db_index=True)
    dependencies = models.ManyToManyField('self', db_index=True)
    doc = generic.GenericRelation(
        Document, related_name='doc_doc')  # Compatibility with Hue 3

    objects = Document2Manager()
    unique_together = ('uuid', 'version', 'is_history')

    def natural_key(self):
        return (self.uuid, self.version, self.is_history)

    @property
    def data_dict(self):
        if not self.data:
            self.data = json.dumps({})
        data_python = json.loads(self.data)

        return data_python

    def update_data(self, post_data):
        data_dict = self.data_dict

        data_dict.update(post_data)

        self.data = json.dumps(data_dict)

    def get_absolute_url(self):
        if self.type == 'oozie-coordinator2':
            return reverse('oozie:edit_coordinator') + '?coordinator=' + str(
                self.id)
        elif self.type == 'oozie-bundle2':
            return reverse('oozie:edit_bundle') + '?bundle=' + str(self.id)
        elif self.type == 'notebook':
            return reverse('spark:editor') + '?notebook=' + str(self.id)
        elif self.type == 'search-dashboard':
            return reverse('search:index') + '?collection=' + str(self.id)
        else:
            return reverse('oozie:edit_workflow') + '?workflow=' + str(self.id)

    def to_dict(self):
        return {
            'owner': self.owner.username,
            'name': self.name,
            'description': self.description,
            'uuid': self.uuid,
            'id': self.id,
            'doc1_id': self.doc.get().id if self.doc.exists() else -1,
            'type': self.type,
            'last_modified': self.last_modified.strftime(UTC_TIME_FORMAT),
            'last_modified_ts':
            calendar.timegm(self.last_modified.utctimetuple()),
            'isSelected': False,
            'absoluteUrl': self.get_absolute_url()
        }

    def can_read_or_exception(self, user):
        self.doc.get().can_read_or_exception(user)
Exemple #6
0
class OddRelation2(models.Model):
    name = models.CharField(max_length=100)
    tlinks = generic.GenericRelation(TextLink)
Exemple #7
0
class UserProfile(models.Model, ExtendedAttributesManager):
    user = models.ForeignKey(User, unique=True, related_name='profile')
    hidden_status = models.BooleanField(default=False)
    hidden_email = models.BooleanField(default=False)
    rating_total = models.IntegerField(default=0)
    signature = models.TextField(blank=True)
    secret_question = models.TextField(blank=True)
    secret_answer = models.TextField(blank=True)
    short_desc = models.CharField(max_length=255, blank=True)
    long_desc = models.TextField(blank=True)
    custom_nick_display = models.TextField(blank=True)
    auto_login = models.BooleanField(blank=True)
    back_to_topic = models.BooleanField(blank=True)
    auto_quote = models.BooleanField(blank=True)
    link_source_post = models.BooleanField(blank=True)
    always_preview = models.BooleanField(blank=True)
    #    mod_denied = models.BooleanField(blank = True)
    #    can_modify_profile_own = models.BooleanField(blank = True)
    #    can_change_custom_nick_display = models.BooleanField(blank = True)
    #    can_change_short_desc = models.BooleanField(blank = True)
    show_ruler = models.BooleanField(blank=True)
    save_password = models.BooleanField(blank=True)
    contributor = models.BooleanField(blank=True)
    is_alias = models.BooleanField(blank=True)
    post_per_page = models.SmallIntegerField(blank=True, default=30)
    min_rating = models.SmallIntegerField(blank=True, default=2)
    mana = models.IntegerField(default=0)
    last_post = models.ForeignKey("Post",
                                  blank=True,
                                  null=True,
                                  related_name="posted_by",
                                  editable=False)
    posts_count = models.IntegerField(blank=True, default=0, editable=False)
    _extended_attributes = generic.GenericRelation("ExtendedAttributeValue")
    ignores = generic.GenericRelation(Ignore)
    _replies = generic.GenericRelation("Post", editable=False)
    _last_reply_id = models.PositiveIntegerField(default=0,
                                                 blank=True,
                                                 editable=False)
    #    reverse_timestamp = models.PositiveIntegerField(default = 0)
    timestamp = models.PositiveIntegerField(blank=True,
                                            default=0,
                                            db_index=True,
                                            editable=False)
    replies_count = models.IntegerField(
        default=0, editable=False)  #This should be a denorm.
    last_page_url = models.CharField(max_length=255,
                                     blank=True,
                                     default='',
                                     editable=False)
    last_page_time = models.DateTimeField(default=datetime.datetime.now(),
                                          db_index=True,
                                          editable=False)

    def __unicode__(self):
        return self.user.username

    @models.permalink
    def get_absolute_url(self):
        #        name=name+'\x01' if name.endswith('.') else name
        return ('profiles_profile_detail', (), {
            'username': iri_to_uri(self.user.username)
        })

    @models.permalink
    def get_replies_url(self):
        return ('board_profile_view_replies', (), {
            'username': iri_to_uri(self.user.username)
        })

    @property
    def replies(self):
        return self._replies.filter(is_active=True).select_related('postdata')

    @property
    def last_reply(
            self
    ):  #TODO: Check if we want to have this return the actual object?
        return self._last_reply_id

    @property
    def posts(self):
        return self.user._posts.select_related('user', 'postdata').order_by(
            '-pk')  #IGNORE:W0212

    @property
    def interactions(self):
        return Interaction.objects.filter(user=self)

    @property
    def favorites(self):
        faves = Fave.objects.get_for_user(self.user)
        post_ct = ContentType.objects.get_for_model(Post).pk
        tag_ct = ContentType.objects.get_for_model(Tag).pk
        #        userprofile_ct = ContentType.objects.get_for_model(UserProfile).pk
        userpost_ct = ContentType.objects.get_for_model(User).pk

        favorites_list = {
            post_ct: [],
            tag_ct: [],
            #           userprofile_ct:[],
            userpost_ct: [],
        }
        itypes = InteractionType.objects.filter(
            name='read',
            content_type__in=favorites_list).values('content_type_id', 'pk')
        ctypes = dict((i["pk"], i["content_type_id"]) for i in itypes)
        for f in faves:
            favorites_list[f.content_type_id].append(f.object_id)
        fave_list = dict(
            (i["pk"], favorites_list[i["content_type_id"]]) for i in itypes)
        q = Q()
        for itype, f in fave_list.iteritems():
            q = q | (Q(interaction_type=itype) & Q(object_id__in=f))

        last_interactions = {}
        for li in self.interactions.filter(q):
            try:
                ct = ctypes[li.interaction_type_id]
                if not last_interactions.has_key(ct):
                    last_interactions[ct] = {}
                last_interactions[ct][li.object_id] = li
            except KeyError:
                pass

        faved_objects = {}
        faved_objects[post_ct] = dict((o.pk, {
            'last': o.last_reply,
            'obj': o,
            'type': 'post'
        }) for o in Post.objects.filter(pk__in=favorites_list[post_ct]))
        faved_objects[tag_ct] = dict((o.pk, {
            'last': o.timestamp,
            'obj': o,
            'type': 'tag'
        }) for o in Tag.objects.filter(pk__in=favorites_list[tag_ct]))
        #        faved_objects[userprofile_ct] = dict((o.pk, {'last':o.last_reply, 'obj':o, 'type':'userprofile'}) for o in UserProfile.objects.filter(pk__in = favorites_list[userprofile_ct]))
        faved_objects[userpost_ct] = dict((o.pk, {
            'last': o.get_profile().last_post_id,
            'obj': o.get_profile(),
            'type': 'user'
        }) for o in User.objects.filter(pk__in=favorites_list[userpost_ct]))

        link_prefix = {
            post_ct: '&para;',
            tag_ct: '.',
            userpost_ct: '@',
            #           userpost_ct:'by: ',
        }

        for f in faves:
            ct = f.content_type_id
            oid = f.object_id
            fo = faved_objects[ct][oid]
            obj = fo['obj']
            try:  #TODO: Should we link to the last interaction or to the starting point?
                f.link_start = int(
                    last_interactions[ct][oid].value.split(';')[0])
            except KeyError:  #This shouldn't actually ever happen, because there _should_ be an interaction of sorts.
                f.link_start = 0

            f.link_href = obj.get_absolute_url()
            f.link_title = link_prefix[ct] + getattr(obj, 'title',
                                                     obj.__unicode__())
            f.current = fo['last']
            f.fresh = fo.get('op', operator.lt)(f.link_start, f.current)
            f.remove = reverse('unfave_object',
                               kwargs={
                                   'fave_type_slug': 'star',
                                   'content_type_id': ct,
                                   'object_id': oid
                               })
        return faves

    def save(self, *args, **kwargs):  #IGNORE:W0221
        if not bool(self._last_reply_id):
            self._last_reply_id = self.pk
        super(UserProfile,
              self).save(*args, **kwargs)  # Call the "real" save() method.

    class Meta:  #IGNORE:W0232
        app_label = 'board'
        permissions = (
            ("set_nick_display", "Can change nick display"),
            ("change_short_desc", "Can change short desc"),
            ("edit_profile_own", "Can edit own profile"),
            ("become_mod", "Can become mod"),
        )
Exemple #8
0
class Document2(models.Model):

  HOME_DIR = ''
  TRASH_DIR = '.Trash'
  EXAMPLES_DIR = 'examples'

  owner = models.ForeignKey(auth_models.User, db_index=True, verbose_name=_t('Owner'), help_text=_t('Creator.'), related_name='doc2_owner')
  name = models.CharField(default='', max_length=255)
  description = models.TextField(default='')
  uuid = models.CharField(default=uuid_default, max_length=36, db_index=True)
  type = models.CharField(default='', max_length=32, db_index=True, help_text=_t('Type of document, e.g. Hive query, Oozie workflow, Search Dashboard...'))

  data = models.TextField(default='{}')
  extra = models.TextField(default='')
  search = models.TextField(blank=True, null=True, help_text=_t('Searchable text for the document.'))
  # settings = models.TextField(default='{}') # Owner settings like, can other reshare, can change access

  last_modified = models.DateTimeField(auto_now=True, db_index=True, verbose_name=_t('Time last modified'))
  version = models.SmallIntegerField(default=1, verbose_name=_t('Document version'), db_index=True)
  is_history = models.BooleanField(default=False, db_index=True)

  dependencies = models.ManyToManyField('self', symmetrical=False, related_name='dependents', db_index=True)

  parent_directory = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)

  doc = generic.GenericRelation(Document, related_name='doc_doc') # Compatibility with Hue 3

  objects = Document2Manager()

  class Meta:
    unique_together = ('uuid', 'version', 'is_history')
    ordering = ["-last_modified", "name"]

  def __str__(self):
    res = '%s - %s - %s' % (force_unicode(self.name), self.owner, self.uuid)
    return force_unicode(res)

  @property
  def data_dict(self):
    if not self.data:
      self.data = json.dumps({})
    data_python = json.loads(self.data)
    return data_python

  @property
  def path(self):
    if self.parent_directory:
      return '%s/%s' % (self.parent_directory.path, self.name)
    else:
      return self.name

  @property
  def dirname(self):
    return os.path.dirname(self.path) or '/'

  @property
  def is_directory(self):
    return self.type == 'directory'

  @property
  def is_home_directory(self):
    return self.is_directory and self.parent_directory == None and self.name == self.HOME_DIR

  @property
  def is_trash_directory(self):
    return self.is_directory and self.name == self.TRASH_DIR

  def natural_key(self):
    return (self.uuid, self.version, self.is_history)

  def copy(self, name, owner, description=None):
    copy_doc = self

    copy_doc.pk = None
    copy_doc.id = None
    copy_doc.uuid = uuid_default()
    copy_doc.name = name
    copy_doc.owner = owner
    if description:
      copy_doc.description = description
    copy_doc.save()
    return copy_doc

  def update_data(self, post_data):
    data_dict = self.data_dict
    data_dict.update(post_data)
    self.data = json.dumps(data_dict)

  def get_absolute_url(self):
    url = None
    try:
      if self.type == 'oozie-coordinator2':
        url = reverse('oozie:edit_coordinator') + '?coordinator=' + str(self.id)
      elif self.type == 'oozie-bundle2':
        url = reverse('oozie:edit_bundle') + '?bundle=' + str(self.id)
      elif self.type.startswith('query'):
        url = reverse('notebook:editor') + '?editor=' + str(self.id)
      elif self.type == 'directory':
        url = '/home2' + '?uuid=' + self.uuid
      elif self.type == 'notebook':
        url = reverse('notebook:notebook') + '?notebook=' + str(self.id)
      elif self.type == 'search-dashboard':
        url = reverse('search:index') + '?collection=' + str(self.id)
      elif self.type == 'link-pigscript':
        url = reverse('pig:index') + '#edit/%s' % self.data_dict.get('object_id', '')
      elif self.type == 'link-workflow':
        url = '/jobsub/#edit-design/%s' % self.data_dict.get('object_id', '')
      else:
        url = reverse('oozie:edit_workflow') + '?workflow=' + str(self.id)
    except NoReverseMatch, e:
      LOG.warn('Could not perform reverse lookup for type %s, app may be blacklisted.' % self.type)
    return url
Exemple #9
0
class ShippingMethod(models.Model):
    """Decides how bought products are delivered to the customer.

    Instance variables:

    - name
       The name of the shipping method. This is displayed to the customer to 
       choose the shipping method.
    - description
       A longer description of the shipping method. This could be displayed to 
       the customer to describe the shipping method in detail.
    - note
       This is displayed to the customer within the checkout process and should
       contain a short note about the shipping method.
    - priority
       The order in which the shipping methods are displayed to the customer.
    - image
       An image of the shipping method, which is displayed to customer within 
       the checkout process.
    - active
       A flag which decides whether a shipping method is displayed to the 
       customer or not.
    - tax
       The tax of the shipping method.
    - price
       The default price of the shipping method. This is taken if the shipping
       method either has no additional prices or if none of he additional prices
       is valid.
    - criteria_objects
       A shipping method may have several criteria which decide whether the
       shipping method is valid. It is valid if all criteria are true. Only 
       active and valid shipping methods are provided to the shop customer.
       
    - delivery_time
       Reference to a delivery_time   
    """
    name = models.CharField(_(u"Name"), max_length=50)
    description = models.TextField(_(u"Description"), blank=True)
    note = models.TextField(_(u"Note"), blank=True)
    priority = models.IntegerField(_(u"Priority"), default=0)
    image = models.ImageField(_(u"Image"),
                              upload_to="images",
                              blank=True,
                              null=True)
    active = models.BooleanField(_(u"Active"), default=False)
    tax = models.ForeignKey(Tax, verbose_name=_(u"Tax"), blank=True, null=True)
    price = models.FloatField(_(u"Price"), default=0.0)
    delivery_time = models.ForeignKey(DeliveryTime,
                                      verbose_name=_(u"Delivery time"),
                                      blank=True,
                                      null=True)

    criteria_objects = generic.GenericRelation(
        CriteriaObjects,
        object_id_field="content_id",
        content_type_field="content_type")

    objects = ActiveShippingMethodManager()

    class Meta:
        ordering = ("priority", )

    def __unicode__(self):
        return self.name

    def is_valid(self, request, product=None):
        """The shipping method is valid if it has no criteria or if all assigned
        criteria are true.
        
        If product is given the product is tested otherwise the whole cart.
        """
        from lfs.criteria import utils as criteria_utils
        return criteria_utils.is_valid(self, request, product)
Exemple #10
0
class UserProfile(caching.base.CachingMixin, models.Model):
    """Definition of UserProfile Model."""
    user = models.OneToOneField(User)
    registration_complete = models.BooleanField(default=False)
    date_joined_program = models.DateField(blank=True)
    date_left_program = models.DateField(blank=True, null=True)
    local_name = models.CharField(max_length=100, blank=True, default='')
    birth_date = models.DateField(validators=[_validate_birth_date],
                                  blank=True,
                                  null=True)
    city = models.CharField(max_length=50, blank=False, default='')
    region = models.CharField(max_length=50, blank=False, default='')
    country = models.CharField(max_length=50, blank=False, default='')
    lon = models.FloatField(blank=False, null=True)
    lat = models.FloatField(blank=False, null=True)
    display_name = models.CharField(
        max_length=DISPLAY_NAME_MAX_LENGTH,
        blank=True,
        default='',
        unique=True,
        validators=[
            RegexValidator(regex=r'("")|(^[A-Za-z0-9_]+$)',
                           message='Please only A-Z characters, numbers and '
                           'underscores.')
        ])
    private_email = models.EmailField(blank=False, null=True, default='')
    mozillians_profile_url = models.URLField(validators=[
        RegexValidator(regex=r'^http(s)?://(www\.)?mozillians.org/',
                       message='Please provide a valid Mozillians url.')
    ])
    twitter_account = models.CharField(
        max_length=16,
        default='',
        blank=True,
        validators=[
            RegexValidator(regex=r'("^$")|(^[A-Za-z0-9_]+$)',
                           message='Please provide a valid Twitter handle.')
        ])
    jabber_id = models.CharField(max_length=50, blank=True, default='')
    irc_name = models.CharField(max_length=50, blank=False, default='')
    irc_channels = models.TextField(blank=True, default='')
    linkedin_url = models.URLField(
        blank=True,
        null=False,
        default='',
        validators=[
            RegexValidator(regex=r'("^$")|(^http(s)?://(.*?)linkedin.com/)',
                           message='Please provide a valid LinkedIn url.')
        ])
    facebook_url = models.URLField(
        blank=True,
        null=False,
        default='',
        validators=[
            RegexValidator(regex=r'("^$")|(^http(s)?://(.*?)facebook.com/)',
                           message='Please provide a valid Facebook url.')
        ])
    diaspora_url = models.URLField(blank=True, null=False, default='')
    personal_website_url = models.URLField(blank=True, null=False, default='')
    personal_blog_feed = models.URLField(blank=True, null=False, default='')
    wiki_profile_url = models.URLField(
        blank=True,
        null=False,
        default='',
        validators=[
            RegexValidator(regex=r'^http(s)?://wiki.mozilla.org/User:'******'Please provide a valid wiki url.')
        ])
    added_by = models.ForeignKey(User,
                                 null=True,
                                 blank=True,
                                 related_name='users_added')
    bio = models.TextField(blank=True, default='')
    gender = models.NullBooleanField(choices=((None, 'Gender'),
                                              (True, 'Female'), (False,
                                                                 'Male')),
                                     default=None)
    mentor = models.ForeignKey(User,
                               null=True,
                               blank=True,
                               related_name='mentees',
                               validators=[_validate_mentor],
                               on_delete=models.SET_NULL)
    functional_areas = models.ManyToManyField(FunctionalArea,
                                              related_name='users_matching')
    tracked_functional_areas = models.ManyToManyField(
        FunctionalArea, related_name='users_tracking')
    receive_email_on_add_comment = models.BooleanField(null=False,
                                                       blank=True,
                                                       default=True)
    receive_email_on_add_event_comment = models.BooleanField(null=False,
                                                             blank=True,
                                                             default=True)
    receive_email_on_add_voting_comment = models.BooleanField(null=False,
                                                              blank=True,
                                                              default=True)
    mozillian_username = models.CharField(blank=True,
                                          default='',
                                          max_length=40)
    current_streak_start = models.DateField(null=True, blank=True)
    longest_streak_start = models.DateField(null=True, blank=True)
    longest_streak_end = models.DateField(null=True, blank=True)
    first_report_notification = models.DateField(null=True, blank=True)
    second_report_notification = models.DateField(null=True, blank=True)
    timezone = models.CharField(max_length=100, blank=True, default='')
    unavailability_task_id = models.CharField(max_length=256,
                                              blank=True,
                                              null=True,
                                              editable=False,
                                              default='')
    is_rotm_nominee = models.BooleanField(default=False)
    rotm_nominated_by = models.ForeignKey(User,
                                          null=True,
                                          blank=True,
                                          related_name='rotm_nominations',
                                          validators=[_validate_mentor],
                                          on_delete=models.SET_NULL)
    action_items = generic.GenericRelation('dashboard.ActionItem')

    objects = caching.base.CachingManager()

    class Meta:
        permissions = (('create_user', 'Can create new user'),
                       ('can_edit_profiles', 'Can edit profiles'),
                       ('can_delete_profiles', 'Can delete profiles'))

    def get_absolute_url(self):
        return reverse('remo.profiles.views.view_profile',
                       kwargs={'display_name': self.display_name})

    @property
    def get_age(self):
        """Return the age of the user as an integer.

        Age gets calculated from birth_date variable.
        Snippet from http://djangosnippets.org/snippets/557/

        """
        d = timezone.now().date()
        age = ((d.year - self.birth_date.year) - int(
            (d.month, d.day) < (self.birth_date.month, self.birth_date.day)))
        return age

    def clean(self, *args, **kwargs):
        """Ensure that added_by variable does not have the same value as
        user variable.

        """
        if self.added_by == self.user:
            raise ValidationError('Field added_by cannot be the same as user.')

        return super(UserProfile, self).clean(*args, **kwargs)

    def get_action_items(self):
        """Return a list of Action Items relevant to this model."""

        today = timezone.now().date()
        due_date = datetime.date(today.year, today.month, NOMINATION_END_DAY)
        name = u'{0} {1}'.format(NOMINATION_ACTION_ITEM, today.strftime('%B'))
        priority = ActionItem.NORMAL
        action_item = Item(name, self.user, priority, due_date)

        return [action_item]
Exemple #11
0
class UserStory(NeighborsMixin, WatchedMixin, BlockedMixin, models.Model):
    ref = models.BigIntegerField(db_index=True,
                                 null=True,
                                 blank=True,
                                 default=None,
                                 verbose_name=_("ref"))
    milestone = models.ForeignKey("milestones.Milestone",
                                  null=True,
                                  blank=True,
                                  default=None,
                                  related_name="user_stories",
                                  on_delete=models.SET_NULL,
                                  verbose_name=_("milestone"))
    project = models.ForeignKey("projects.Project",
                                null=False,
                                blank=False,
                                related_name="user_stories",
                                verbose_name=_("project"))
    owner = models.ForeignKey(settings.AUTH_USER_MODEL,
                              null=True,
                              blank=True,
                              related_name="owned_user_stories",
                              verbose_name=_("owner"),
                              on_delete=models.SET_NULL)
    status = models.ForeignKey("projects.UserStoryStatus",
                               null=True,
                               blank=True,
                               related_name="user_stories",
                               verbose_name=_("status"),
                               on_delete=models.SET_NULL)
    is_closed = models.BooleanField(default=False)
    points = models.ManyToManyField("projects.Points",
                                    null=False,
                                    blank=False,
                                    related_name="userstories",
                                    through="RolePoints",
                                    verbose_name=_("points"))
    order = models.PositiveSmallIntegerField(null=False,
                                             blank=False,
                                             default=100,
                                             verbose_name=_("order"))
    created_date = models.DateTimeField(auto_now_add=True,
                                        null=False,
                                        blank=False,
                                        verbose_name=_("created date"))
    modified_date = models.DateTimeField(auto_now=True,
                                         null=False,
                                         blank=False,
                                         verbose_name=_("modified date"))
    finish_date = models.DateTimeField(null=True,
                                       blank=True,
                                       verbose_name=_("finish date"))
    subject = models.CharField(max_length=500,
                               null=False,
                               blank=False,
                               verbose_name=_("subject"))
    description = models.TextField(null=False,
                                   blank=True,
                                   verbose_name=_("description"))
    assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL,
                                    blank=True,
                                    null=True,
                                    default=None,
                                    related_name="userstories_assigned_to_me",
                                    verbose_name=_("assigned to"))
    watchers = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                      null=True,
                                      blank=True,
                                      related_name="watched_user_stories",
                                      verbose_name=_("watchers"))
    client_requirement = models.BooleanField(
        default=False,
        null=False,
        blank=True,
        verbose_name=_("is client requirement"))
    team_requirement = models.BooleanField(
        default=False,
        null=False,
        blank=True,
        verbose_name=_("is team requirement"))
    tags = PickledObjectField(null=False, blank=True, verbose_name=_("tags"))
    attachments = generic.GenericRelation("attachments.Attachment")
    generated_from_issue = models.ForeignKey(
        "issues.Issue",
        null=True,
        blank=True,
        related_name="generated_user_stories",
        verbose_name=_("generated from issue"))

    notifiable_fields = [
        "subject", "milestone", "owner", "assigned_to", "finish_date",
        "client_requirement", "team_requirement", "status", "points", "tags",
        "description", "is_blocked", "blocked_comment", "generated_from_isssue"
    ]

    class Meta:
        verbose_name = "user story"
        verbose_name_plural = "user stories"
        ordering = ["project", "order", "ref"]
        unique_together = ("ref", "project")
        permissions = (("view_userstory", "Can view user story"), )

    def __str__(self):
        return "({1}) {0}".format(self.ref, self.subject)

    def __repr__(self):
        return "<UserStory %s>" % (self.id)

    def _get_prev_neighbor_filters(self, queryset):
        conds = [{
            "order__lt": "{obj.order}"
        }, {
            "order__lte": "{obj.order}",
            "ref__lt": "{obj.ref}"
        }]
        return conds

    def _get_next_neighbor_filters(self, queryset):
        conds = [{
            "order__gt": "{obj.order}"
        }, {
            "order__gte": "{obj.order}",
            "ref__gt": "{obj.ref}"
        }]
        return conds

    def get_role_points(self):
        return self.role_points

    def get_total_points(self):
        total = 0.0
        for rp in self.role_points.select_related("points"):
            if rp.points.value:
                total += rp.points.value

        return total

    def get_notifiable_assigned_to_display(self, value):
        if not value:
            return _("Unassigned")
        return value.get_full_name()

    def get_notifiable_tags_display(self, value):
        if type(value) is list:
            return ", ".join(value)
        return value

    def get_notifiable_points_display(self, value):
        if isinstance(value, models.manager.Manager):
            return ", ".join([
                "{}: {}".format(rp.role.name, rp.points.name)
                for rp in self.role_points.all().order_by("role")
            ])

        return None

    def _get_watchers_by_role(self):
        return {
            "owner": self.owner,
            "assigned_to": self.assigned_to,
            "suscribed_watchers": self.watchers.all(),
            "project": self.project,
        }
Exemple #12
0
class RelayDomain(AdminObject):
    """Relay domain.

    A relay domain differs from a usual domaine because its final
    destination is not reached yet. It must be accepted by the MTA but
    it will then be transfered to another one.
    """
    name = models.CharField(ugettext_lazy('name'),
                            max_length=100,
                            unique=True,
                            help_text=ugettext_lazy('The domain name'))
    target_host = models.CharField(
        ugettext_lazy('target host'),
        max_length=255,
        help_text=ugettext_lazy('Remote destination of this domain'))
    service = models.ForeignKey(Service, default='relay')
    enabled = models.BooleanField(
        ugettext_lazy('enabled'),
        help_text=ugettext_lazy('Check to activate this domain'))
    verify_recipients = models.BooleanField(
        ugettext_lazy('verify recipients'),
        help_text=ugettext_lazy('Check for valid recipients'))

    owners = generic.GenericRelation(ObjectAccess)

    objects = RelayDomainManager()

    class Meta:
        ordering = ['name']

    @property
    def tags(self):
        return [{
            "name": "relaydomain",
            "label": _("Relay Domain"),
            "type": "dom"
        }, {
            "name": self.service.name,
            "label": "%s:" % self.service.name,
            "type": "srv",
            "color": "info"
        }]

    @property
    def aliases(self):
        return self.relaydomainalias_set

    def __str__(self):
        return self.name

    def to_csv(self, csvwriter):
        """Export this relay domain to CSV.

        :param csvwriter:
        """
        csvwriter.writerow([
            "relaydomain", self.name, self.target_host, self.service.name,
            self.enabled, self.verify_recipients
        ])
        for rdalias in self.relaydomainalias_set.all():
            rdalias.to_csv(csvwriter)

    def from_csv(self, user, row):
        """Import a relay domain from CSV.

        :param user: user importing the relay domain
        :param str row: relay domain definition
        """
        if len(row) != 6:
            raise BadRequest(_("Invalid line"))
        self.name = row[1].strip()
        self.target_host = row[2].strip()
        self.service, created = Service.objects.get_or_create(
            name=row[3].strip())
        self.enabled = (row[4].strip() == 'True')
        self.verify_recipients = (row[5].strip() == 'True')
        self.save(creator=user)

    def post_create(self, creator):
        """Post creation actions.

        :param ``User`` creator: user whos created this relay domain
        """
        super(RelayDomain, self).post_create(creator)
        for rdomalias in self.relaydomainalias_set.all():
            rdomalias.post_create(creator)
Exemple #13
0
class SavedQuery(models.Model):
    """
  Stores the query that people have save or submitted.

  Note that this used to be called QueryDesign. Any references to 'design'
  probably mean a SavedQuery.
  """
    DEFAULT_NEW_DESIGN_NAME = _('My saved query')
    AUTO_DESIGN_SUFFIX = _(' (new)')
    TYPES = QUERY_TYPES
    TYPES_MAPPING = {
        'beeswax': HQL,
        'hql': HQL,
        'impala': IMPALA,
        'rdbms': RDBMS,
        'spark': SPARK
    }

    type = models.IntegerField(null=False)
    owner = models.ForeignKey(User, db_index=True)
    # Data is a json of dictionary. See the beeswax.design module.
    data = models.TextField(max_length=65536)
    name = models.CharField(max_length=80)
    desc = models.TextField(max_length=1024)
    mtime = models.DateTimeField(auto_now=True)
    # An auto design is a place-holder for things users submit but not saved.
    # We still want to store it as a design to allow users to save them later.
    is_auto = models.BooleanField(default=False, db_index=True)
    is_trashed = models.BooleanField(default=False,
                                     db_index=True,
                                     verbose_name=_t('Is trashed'),
                                     help_text=_t('If this query is trashed.'))

    is_redacted = models.BooleanField(default=False)

    doc = generic.GenericRelation(Document, related_name='hql_doc')

    class Meta:
        ordering = ['-mtime']

    def get_design(self):
        try:
            return HQLdesign.loads(self.data)
        except ValueError:
            # data is empty
            pass

    def clone(self, new_owner=None):
        if new_owner is None:
            new_owner = self.owner
        design = SavedQuery(type=self.type, owner=new_owner)
        design.data = self.data
        design.name = self.name
        design.desc = self.desc
        design.is_auto = self.is_auto
        return design

    @classmethod
    def create_empty(cls, app_name, owner, data):
        query_type = SavedQuery.TYPES_MAPPING[app_name]
        design = SavedQuery(owner=owner, type=query_type)
        design.name = SavedQuery.DEFAULT_NEW_DESIGN_NAME
        design.desc = ''

        if global_redaction_engine.is_enabled():
            design.data = global_redaction_engine.redact(data)
        else:
            design.data = data

        design.is_auto = True
        design.save()

        Document.objects.link(design,
                              owner=design.owner,
                              extra=design.type,
                              name=design.name,
                              description=design.desc)
        design.doc.get().add_to_history()

        return design

    @staticmethod
    def get(id, owner=None, type=None):
        """
    get(id, owner=None, type=None) -> SavedQuery object

    Checks that the owner and type match (when given).
    May raise PopupException (type/owner mismatch).
    May raise SavedQuery.DoesNotExist.
    """
        try:
            design = SavedQuery.objects.get(id=id)
        except SavedQuery.DoesNotExist, err:
            msg = _('Cannot retrieve query id %(id)s.') % {'id': id}
            raise err

        if owner is not None and design.owner != owner:
            msg = _('Query id %(id)s does not belong to user %(user)s.') % {
                'id': id,
                'user': owner
            }
            LOG.error(msg)
            raise PopupException(msg)

        if type is not None and design.type != type:
            msg = _('Type mismatch for design id %(id)s (owner %(owner)s) - Expected %(expected_type)s, got %(real_type)s.') % \
                  {'id': id, 'owner': owner, 'expected_type': design.type, 'real_type': type}
            LOG.error(msg)
            raise PopupException(msg)

        return design
Exemple #14
0
class URLPath(MPTTModel):
    """
    Strategy: Very few fields go here, as most has to be managed through an
    article's revision. As a side-effect, the URL resolution remains slim and swift.
    """
    # Tells django-wiki that permissions from a this object's article
    # should be inherited to children's articles. In this case, it's a static
    # property.. but you can also use a BooleanField.
    INHERIT_PERMISSIONS = True

    objects = managers.URLPathManager()
    _default_manager = objects

    articles = generic.GenericRelation(ArticleForObject)

    # Do NOT modify this field - it is updated with signals whenever ArticleForObject is changed.
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        editable=False,
        verbose_name=_(u'Cache lookup value for articles'))

    SLUG_MAX_LENGTH = 50

    slug = models.SlugField(verbose_name=_(u'slug'),
                            null=True,
                            blank=True,
                            max_length=SLUG_MAX_LENGTH)
    site = models.ForeignKey(Site)
    parent = TreeForeignKey('self',
                            null=True,
                            blank=True,
                            related_name='children')

    def __init__(self, *args, **kwargs):
        pass
        # Fixed in django-mptt 0.5.3
        #self._tree_manager = URLPath.objects
        return super(URLPath, self).__init__(*args, **kwargs)

    def __cached_ancestors(self):
        """
        This returns the ancestors of this urlpath. These ancestors are hopefully
        cached from the article path lookup. Accessing a foreign key included in
        add_selecte_related on one of these ancestors will not occur an additional
        sql query, as they were retrieved with a select_related.
        
        If the cached ancestors were not set explicitly, they will be retrieved from
        the database.
        """
        if not self.get_ancestors().exists():
            self._cached_ancestors = []
        if not hasattr(self, "_cached_ancestors"):
            self._cached_ancestors = list(
                self.get_ancestors().select_related_common())

        return self._cached_ancestors

    def __cached_ancestors_setter(self, ancestors):
        self._cached_ancestors = ancestors

    # Python 2.5 compatible property constructor
    cached_ancestors = property(__cached_ancestors, __cached_ancestors_setter)

    def set_cached_ancestors_from_parent(self, parent):
        self.cached_ancestors = parent.cached_ancestors + [parent]

    @property
    def path(self):
        if not self.parent: return ""

        ancestors = filter(lambda ancestor: ancestor.parent is not None,
                           self.cached_ancestors)
        slugs = [obj.slug if obj.slug else "" for obj in ancestors + [self]]

        return "/".join(slugs) + "/"

    def is_deleted(self):
        """
        Returns True if this article or any of its ancestors have been deleted
        """
        return self.first_deleted_ancestor() is not None

    def first_deleted_ancestor(self):
        for ancestor in self.cached_ancestors + [self]:
            if ancestor.article.current_revision.deleted == True:
                return ancestor
        return None

    @transaction.commit_manually
    def delete_subtree(self):
        """
        NB! This deletes this urlpath, its children, and ALL of the related
        articles. This is a purged delete and CANNOT be undone.
        """
        try:
            for descendant in self.get_descendants(
                    include_self=True).order_by("-level"):
                print "deleting ", descendant
                descendant.article.delete()

            transaction.commit()
        except:
            transaction.rollback()
            log.exception("Exception deleting article subtree.")

    @classmethod
    def root(cls):
        site = Site.objects.get_current()
        root_nodes = list(
            cls.objects.root_nodes().filter(site=site).select_related_common())
        # We fetch the nodes as a list and use len(), not count() because we need
        # to get the result out anyway. This only takes one sql query
        no_paths = len(root_nodes)
        if no_paths == 0:
            raise NoRootURL("You need to create a root article on site '%s'" %
                            site)
        if no_paths > 1:
            raise MultipleRootURLs("Somehow you have multiple roots on %s" %
                                   site)
        return root_nodes[0]

    class MPTTMeta:
        pass

    def __unicode__(self):
        path = self.path
        return path if path else ugettext(u"(root)")

    def save(self, *args, **kwargs):
        super(URLPath, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        assert not (self.parent and self.get_children()
                    ), "You cannot delete a root article with children."
        super(URLPath, self).delete(*args, **kwargs)

    class Meta:
        verbose_name = _(u'URL path')
        verbose_name_plural = _(u'URL paths')
        unique_together = ('site', 'parent', 'slug')
        app_label = settings.APP_LABEL

    def clean(self, *args, **kwargs):
        if self.slug and not self.parent:
            raise ValidationError(
                _(u'Sorry but you cannot have a root article with a slug.'))
        if not self.slug and self.parent:
            raise ValidationError(
                _(u'A non-root note must always have a slug.'))
        if not self.parent:
            if URLPath.objects.root_nodes().filter(site=self.site).exclude(
                    id=self.id):
                raise ValidationError(
                    _(u'There is already a root node on %s') % self.site)
        super(URLPath, self).clean(*args, **kwargs)

    @classmethod
    def get_by_path(cls, path, select_related=False):
        """
        Strategy: Don't handle all kinds of weird cases. Be strict.
        Accepts paths both starting with and without '/'
        """

        # TODO: Save paths directly in the model for constant time lookups?

        # Or: Save the parents in a lazy property because the parents are
        # always fetched anyways so it's fine to fetch them here.
        path = path.lstrip("/")
        path = path.rstrip("/")

        # Root page requested
        if not path:
            return cls.root()

        slugs = path.split('/')
        level = 1
        parent = cls.root()
        for slug in slugs:
            if settings.URL_CASE_SENSITIVE:
                child = parent.get_children().select_related_common().get(
                    slug=slug)
                child.cached_ancestors = parent.cached_ancestors + [parent]
                parent = child
            else:
                child = parent.get_children().select_related_common().get(
                    slug__iexact=slug)
                child.cached_ancestors = parent.cached_ancestors + [parent]
                parent = child
            level += 1

        return parent

    def get_absolute_url(self):
        return reverse('wiki:get', kwargs={'path': self.path})

    @classmethod
    def create_root(cls, site=None, title="Root", request=None, **kwargs):
        if not site: site = Site.objects.get_current()
        root_nodes = cls.objects.root_nodes().filter(site=site)
        if not root_nodes:
            # (get_or_create does not work for MPTT models??)
            article = Article()
            revision = ArticleRevision(title=title, **kwargs)
            if request: revision.set_from_request(request)
            article.add_revision(revision, save=True)
            article.save()
            root = cls.objects.create(site=site, article=article)
            article.add_object_relation(root)
        else:
            root = root_nodes[0]
        return root

    @classmethod
    def create_article(cls,
                       parent,
                       slug,
                       site=None,
                       title="Root",
                       article_kwargs={},
                       **kwargs):
        """Utility function:
        Create a new urlpath with an article and a new revision for the article"""
        if not site:
            site = Site.objects.get_current()
        article = Article(**article_kwargs)
        article.add_revision(ArticleRevision(title=title, **kwargs), save=True)
        article.save()
        newpath = cls.objects.create(site=site,
                                     parent=parent,
                                     slug=slug,
                                     article=article)
        article.add_object_relation(newpath)
        return newpath
Exemple #15
0
class Place(models.Model):
    name = models.CharField(max_length=100)
    links = generic.GenericRelation(Link)

    def __str__(self):
        return "Place: %s" % self.name
Exemple #16
0
class Article(TendenciBaseModel):
    CONTRIBUTOR_AUTHOR = 1
    CONTRIBUTOR_PUBLISHER = 2
    CONTRIBUTOR_CHOICES = ((CONTRIBUTOR_AUTHOR, 'Author'),
                           (CONTRIBUTOR_PUBLISHER, 'Publisher'))

    guid = models.CharField(max_length=40)
    slug = SlugField(_('URL Path'), unique=True)
    timezone = TimeZoneField(_('Time Zone'))
    headline = models.CharField(max_length=200, blank=True)
    summary = models.TextField(blank=True)
    body = tinymce_models.HTMLField()
    source = models.CharField(max_length=300, blank=True)
    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), max_length=100, blank=True)
    contributor_type = models.IntegerField(choices=CONTRIBUTOR_CHOICES,
                                           default=CONTRIBUTOR_AUTHOR)
    google_profile = models.URLField(_('Google+ URL'), blank=True)
    phone = models.CharField(max_length=50, blank=True)
    fax = models.CharField(max_length=50, blank=True)
    email = models.CharField(max_length=120, blank=True)
    website = models.CharField(max_length=300, blank=True)
    release_dt = models.DateTimeField(_('Release Date/Time'),
                                      null=True,
                                      blank=True)
    # used for better performance when retrieving a list of released articles
    release_dt_local = models.DateTimeField(null=True, blank=True)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    featured = models.BooleanField()
    design_notes = models.TextField(_('Design Notes'), blank=True)
    group = models.ForeignKey(Group,
                              null=True,
                              default=get_default_group,
                              on_delete=models.SET_NULL)
    tags = TagField(blank=True)

    # for podcast feeds
    enclosure_url = models.CharField(_('Enclosure URL'),
                                     max_length=500,
                                     blank=True)
    enclosure_type = models.CharField(_('Enclosure Type'),
                                      max_length=120,
                                      blank=True)
    enclosure_length = models.IntegerField(_('Enclosure Length'), default=0)

    not_official_content = models.BooleanField(_('Official Content'),
                                               blank=True)

    # html-meta tags
    meta = models.OneToOneField(MetaTags, null=True)

    categories = generic.GenericRelation(CategoryItem,
                                         object_id_field="object_id",
                                         content_type_field="content_type")
    perms = generic.GenericRelation(ObjectPermission,
                                    object_id_field="object_id",
                                    content_type_field="content_type")

    objects = ArticleManager()

    class Meta:
        permissions = (("view_article", "Can view article"), )
        verbose_name = "Article"
        verbose_name_plural = "Articles"

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        methods coupled to this instance.
        """
        return ArticleMeta().get_meta(self, name)

    @models.permalink
    def get_absolute_url(self):
        return ("article", [self.slug])

    @models.permalink
    def get_version_url(self, hash):
        return ("article.version", [hash])

    def __unicode__(self):
        return self.headline

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid1())
        self.assign_release_dt_local()
        super(Article, self).save(*args, **kwargs)

    def assign_release_dt_local(self):
        """
        convert release_dt to the corresponding local time
        
        example:
        
        if
            release_dt: 2014-05-09 03:30:00
            timezone: US/Pacific
            settings.TIME_ZONE: US/Central
        then
            the corresponding release_dt_local will be: 2014-05-09 05:30:00
        """
        now = datetime.now()
        now_with_tz = adjust_datetime_to_timezone(now, settings.TIME_ZONE)
        if self.timezone and self.release_dt and self.timezone.zone != settings.TIME_ZONE:
            time_diff = adjust_datetime_to_timezone(
                now, self.timezone) - now_with_tz
            self.release_dt_local = self.release_dt + time_diff
        else:
            self.release_dt_local = self.release_dt

    def age(self):
        return datetime.now() - self.create_dt

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category__name',
                                                  'parent__name'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    @property
    def has_google_author(self):
        return self.contributor_type == self.CONTRIBUTOR_AUTHOR

    @property
    def has_google_publisher(self):
        return self.contributor_type == self.CONTRIBUTOR_PUBLISHER
Exemple #17
0
class OddRelation1(models.Model):
    name = models.CharField(max_length=100)
    clinks = generic.GenericRelation(CharLink)
Exemple #18
0
class Lot(models.Model):
    # spatial fields
    coord = models.PointField(srid=4326, blank=True)
    bounds = models.MultiPolygonField(srid=4326, blank=True)
    #area = models.FloatField(db_index=True, blank=True)

    address = models.CharField(db_index=True, max_length=255, blank=True)
    city = models.CharField(max_length=255)
    state = models.CharField(max_length=2)
    country = models.CharField(max_length=255)
    code = models.CharField(max_length=10, blank=True)

    # meta fields
    is_visible = models.BooleanField(db_index=True, default=True)
    is_vacant = models.BooleanField(db_index=True, default=False)
    is_public = models.BooleanField(db_index=True, default=False)

    #auto-generated fields
    slug = models.SlugField(max_length=255, editable=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    comments = generic.GenericRelation(Comment)

    objects = PassThroughGeoManager.for_queryset_class(LotQuerySet)()

    class Meta:
        pass

    @property
    def activity_count(self):
        activity = self.comments.count() + self.ideas.count()
        return activity

    @property
    def has_project(self):
        if self.ideas:
            return True
        else:
            return False

    @property
    def has_comment(self):
        if self.comments:
            return True
        else:
            return False

    def get_sqft(self):
        """ 
        Returns the area in sq ft. 
        """
        # Convert our geographic polygons (in WGS84)
        # into a local projection for New York (here EPSG:32118)
        try:
            return self.bounds.transform(102729, clone=True).area
        except Exception:
            return None

    def get_acres(self):
        """ 
        Returns the area in sq ft. 
        """
        # Convert our geographic polygons (in WGS84)
        # into a local projection for New York (here EPSG:32118)
        try:
            return self.bounds.transform(102729,
                                         clone=True).area * 0.00002295684
        except Exception:
            return None

    def __unicode__(self):
        if self.address:
            return u'%s' % (self.address)
        elif self.coord:
            return u'(%s,%s)' % (self.coord.x, self.coord.y)
        else:
            return u'No Address %s' % (self.pk)

    def get_absolute_url(self):
        return reverse('lotxlot_lot_detail', args=[str(self.id)])

    def save(self, *args, **kwargs):
        if not self.pk:
            if self.address:
                slug = '%s %s, %s' % (self.address, self.city, self.state)
            elif self.coord:
                slug = '(%s,%s) %s, %s' % (self.coord.x, self.coord.y,
                                           self.city, self.state)
            else:
                slug = 'No Address %s %s, %s' % (self.pk, self.city,
                                                 self.state)
            self.slug = slugify(slug)
        super(Lot, self).save(*args, **kwargs)
Exemple #19
0
class Contact(models.Model):
    notes = generic.GenericRelation(Note)
Exemple #20
0
class File(TendenciBaseModel):
    file = models.FileField("", max_length=260, upload_to=file_directory)
    guid = models.CharField(max_length=40)
    name = models.CharField(max_length=200, blank=True)
    description = models.TextField(blank=True)
    content_type = models.ForeignKey(ContentType, blank=True, null=True)
    object_id = models.IntegerField(blank=True, null=True)
    is_public = models.BooleanField(default=True)
    group = models.ForeignKey(Group,
                              null=True,
                              default=get_default_group,
                              on_delete=models.SET_NULL)
    tags = TagField(null=True, blank=True)
    categories = generic.GenericRelation(CategoryItem,
                                         object_id_field="object_id",
                                         content_type_field="content_type")

    perms = generic.GenericRelation(ObjectPermission,
                                    object_id_field="object_id",
                                    content_type_field="content_type")

    objects = FileManager()

    class Meta:
        permissions = (("view_file", "Can view file"), )

    @models.permalink
    def get_absolute_url(self):
        return ("file", [self.pk])

    @models.permalink
    def get_absolute_download_url(self):
        return ("file", [self.pk, 'download'])

    def __unicode__(self):
        return self.get_name()

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category__name',
                                                  'parent__name'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = unicode(uuid.uuid1())

        super(File, self).save(*args, **kwargs)

        if self.is_public_file():
            set_s3_file_permission(self.file, public=True)
        else:
            set_s3_file_permission(self.file, public=False)

        cache_set = cache.get("files_cache_set.%s" % self.pk)
        if cache_set is not None:
            # TODO remove cached images
            cache.delete_many(cache.get("files_cache_set.%s" % self.pk))
            cache.delete("files_cache_set.%s" % self.pk)

    def delete(self, *args, **kwargs):
        # Related objects
        # Import related objects here to prevent circular references
        from tendenci.apps.pages.models import Page
        from tendenci.addons.events.models import Event
        from tendenci.apps.stories.models import Story
        pages = Page.objects.filter(header_image=self.pk)
        events = Event.objects.filter(image=self.pk)
        stories = Story.objects.filter(image=self.pk)
        # Set foreign key of related objects to None
        for page in pages:
            page.header_image = None
            page.save()
        for event in events:
            event.image = None
            event.save()
        for story in stories:
            story.image = None
            story.save()

        # roll back the transaction to fix the error for postgresql
        #"current transaction is aborted, commands ignored until
        # end of transaction block"
        connection._rollback()

        # delete actual file; do not save() self.instance
        self.file.delete(save=False)

        # delete database record
        super(File, self).delete(*args, **kwargs)

    def basename(self):
        return os.path.basename(unicode(self.file.name))

    def ext(self):
        return os.path.splitext(self.basename())[-1]

    def get_name(self):
        return self.name or os.path.splitext(self.basename())[0]

    def get_name_ext(self):
        return "%s%s" % (self.get_name(), self.ext())

    def type(self):
        ext = self.ext().lower()

        # map file-type to extension
        types = {
            'image':
            ('.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff', '.bmp'),
            'text': ('.txt', '.doc', '.docx'),
            'spreadsheet': ('.csv', '.xls', '.xlsx'),
            'powerpoint': ('.ppt', '.pptx'),
            'pdf': ('.pdf'),
            'video': ('.wmv', '.mov', '.mpg', '.mp4', '.m4v'),
            'zip': ('.zip'),
        }

        # if file ext. is recognized
        # return icon
        for type in types:
            if ext in types[type]:
                return type

        return None

    def mime_type(self):
        types = {  # list of uncommon mimetypes
            'application/msword': ('.doc', '.docx'),
            'application/ms-powerpoint': ('.ppt', '.pptx'),
            'application/ms-excel': ('.xls', '.xlsx'),
            'video/x-ms-wmv': ('.wmv'),
        }
        # add mimetypes
        for type in types:
            for ext in types[type]:
                mimetypes.add_type(type, ext)
        # guess mimetype
        mimetype = mimetypes.guess_type(self.file.name)[0]
        return mimetype

    def icon(self):

        # if we don't know the type
        # we can't find an icon [to represent the file]
        if not self.type():
            return None

        # assign icons directory
        icons_dir = os.path.join(settings.LOCAL_STATIC_URL, 'images/icons')

        # map file-type to image file
        icons = {
            'text': 'icon-ms-word-2007.gif',
            'spreadsheet': 'icon-ms-excel-2007.gif',
            'powerpoint': 'icon-ms-powerpoint-2007.gif',
            'image': 'icon-ms-image-2007.png',
            'pdf': 'icon-pdf.png',
            'video': 'icon-wmv.png',
            'zip': 'icon-zip.gif',
        }

        # return image path
        return icons_dir + '/' + icons[self.type()]

    def get_file_from_remote_storage(self):
        return cStringIO.StringIO(default_storage.open(self.file.name).read())

    def image_dimensions(self):
        try:
            if hasattr(settings, 'USE_S3_STORAGE') and settings.USE_S3_STORAGE:
                im = Image.open(self.get_file_from_remote_storage())
            else:
                im = Image.open(self.file.path)
            return im.size
        except Exception:
            return (0, 0)

    def read(self):
        """Returns a file's text data
        For now this only considers pdf files.
        if the file cannot be read this will return an empty string.
        """

        if not settings.USE_S3_STORAGE:
            if not os.path.exists(self.file.path):
                return unicode()

        if self.type() == 'pdf':

            try:
                doc = PDF(self.file.file)
            except:
                return unicode()

            return doc.text()

        return unicode()

    def is_public_file(self):
        return all([
            self.is_public, self.allow_anonymous_view, self.status,
            self.status_detail.lower() == "active"
        ])

    def get_file_public_url(self):
        if self.is_public_file():
            if hasattr(settings, 'USE_S3_STORAGE') and settings.USE_S3_STORAGE:
                return self.file.url
            else:
                return "%s%s" % (settings.MEDIA_URL, self.file)
        return None
Exemple #21
0
class PaymentMethodCriterion(models.Model, Criterion):
    """A criterion for the payment method.
    """
    operator = models.PositiveIntegerField(_(u"Operator"), blank=True, null=True, choices=SELECT_OPERATORS)
    payment_methods = models.ManyToManyField(PaymentMethod, verbose_name=_(u"Payment methods"))

    criteria_objects = generic.GenericRelation(CriteriaObjects,
        object_id_field="criterion_id", content_type_field="criterion_type")

    def __unicode__(self):
        values = []
        for value in self.value.all():
            values.append(value.name)

        return "%s %s %s" % ("Payment", self.get_operator_display(), ", ".join(values))

    @property
    def content_type(self):
        """Returns the content_type of the criterion as lower string.

        This is for instance used to select the appropriate form for the
        criterion.
        """
        return u"payment_method"

    @property
    def name(self):
        """Returns the descriptive name of the criterion.
        """
        return _(u"Payment method")

    def is_valid(self, request, product=None):
        """Returns True if the criterion is valid.
        """
        # see ShippingMethodCriterion for what's going on here
        import lfs.shipping.utils
        content_object = self.criteria_objects.filter()[0].content
        if isinstance(content_object, PaymentMethod):
            is_payment_method = True
        else:
            is_payment_method = False

        if not is_payment_method and self.operator == IS:
            payment_method = lfs.payment.utils.get_selected_payment_method(request)
            return payment_method in self.payment_methods.all()
        elif not is_payment_method and self.operator == IS_NOT:
            payment_method = lfs.payment.utils.get_selected_payment_method(request)
            return payment_method not in self.payment_methods.all()
        elif self.operator == IS_VALID:
            for pm in self.payment_methods.all():
                if not lfs.criteria.utils.is_valid(request, pm, product):
                    return False
            return True
        elif self.operator == IS_NOT_VALID:
            for pm in self.payment_methods.all():
                if lfs.criteria.utils.is_valid(request, pm, product):
                    return False
            return True
        else:
            return False

    @property
    def value(self):
        """Returns the value of the criterion.
        """
        return self.payment_methods

    def as_html(self, request, position):
        """Renders the criterion as html in order to be displayed within several
        forms.
        """
        selected_payment_methods = self.payment_methods.all()
        payment_methods = []
        for pm in PaymentMethod.objects.filter(active=True):
            if pm in selected_payment_methods:
                selected = True
            else:
                selected = False

            payment_methods.append({
                "id": pm.id,
                "name": pm.name,
                "selected": selected,
            })

        return render_to_string("manage/criteria/payment_method_criterion.html", RequestContext(request, {
            "id": "ex%s" % self.id,
            "operator": self.operator,
            "value": self.value,
            "position": position,
            "payment_methods": payment_methods,
        }))
Exemple #22
0
class ForumSection(models.Model):
    link = models.CharField('Link', max_length=250)
    title = models.CharField('Title', max_length=250)
    threads = generic.GenericRelation(KongThread)
Exemple #23
0
class Issue(models.Model):
    class Meta:
        app_label = 'gcd'
        ordering = ['series', 'sort_code']
        unique_together = ('series', 'sort_code')

    # Issue identification
    number = models.CharField(max_length=50, db_index=True)
    title = models.CharField(max_length=255, db_index=True)
    no_title = models.BooleanField(default=False, db_index=True)
    volume = models.CharField(max_length=50, db_index=True)
    no_volume = models.BooleanField(default=False, db_index=True)
    display_volume_with_number = models.BooleanField(default=False,
                                                     db_index=True)
    isbn = models.CharField(max_length=32, db_index=True)
    no_isbn = models.BooleanField(default=False, db_index=True)
    valid_isbn = models.CharField(max_length=13, db_index=True)
    variant_of = models.ForeignKey('self',
                                   null=True,
                                   related_name='variant_set')
    variant_name = models.CharField(max_length=255)
    barcode = models.CharField(max_length=38, db_index=True)
    no_barcode = models.BooleanField(default=False)

    # Dates and sorting
    publication_date = models.CharField(max_length=255)
    key_date = models.CharField(max_length=10, db_index=True)
    on_sale_date = models.CharField(max_length=10, db_index=True)
    on_sale_date_uncertain = models.BooleanField(blank=True)
    sort_code = models.IntegerField(db_index=True)
    indicia_frequency = models.CharField(max_length=255)
    no_indicia_frequency = models.BooleanField(default=False, db_index=True)

    # Price, page count and format fields
    price = models.CharField(max_length=255)
    page_count = models.DecimalField(max_digits=10,
                                     decimal_places=3,
                                     null=True)
    page_count_uncertain = models.BooleanField(default=False)

    editing = models.TextField()
    no_editing = models.BooleanField(default=False, db_index=True)
    notes = models.TextField()

    keywords = TaggableManager()

    # Series and publisher links
    series = models.ForeignKey(Series)
    indicia_publisher = models.ForeignKey(IndiciaPublisher, null=True)
    indicia_pub_not_printed = models.BooleanField(default=False)
    image_resources = generic.GenericRelation(Image)

    def _indicia_image(self):
        img = Image.objects.filter(
            object_id=self.id,
            deleted=False,
            content_type=ContentType.objects.get_for_model(self),
            type__id=1)
        if img:
            return img.get()
        else:
            return None

    indicia_image = property(_indicia_image)
    brand = models.ForeignKey(Brand, null=True)
    no_brand = models.BooleanField(default=False, db_index=True)

    def _soo_image(self):
        img = Image.objects.filter(
            object_id=self.id,
            deleted=False,
            content_type=ContentType.objects.get_for_model(self),
            type__id=2)
        if img:
            return img.get()
        else:
            return None

    soo_image = property(_soo_image)

    # In production, this is a tinyint(1) because the set of numbers
    # is very small.  But syncdb produces an int(11).
    is_indexed = models.IntegerField(default=0, db_index=True)

    # Fields related to change management.
    reserved = models.BooleanField(default=False, db_index=True)

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True, db_index=True)

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

    def active_stories(self):
        return self.story_set.exclude(deleted=True)

    def shown_stories(self):
        """ returns cover sequence and story sequences """
        if self.variant_of:
            stories_from = self.variant_of
        else:
            stories_from = self
        stories = list(stories_from.active_stories().order_by(
            'sequence_number').select_related('type', 'migration_status'))
        if self.series.is_comics_publication:
            if (len(stories) > 0):
                cover_story = stories.pop(0)
                if self.variant_of:
                    # can have only one sequence, the variant cover
                    if self.active_stories().count():
                        cover_story = self.active_stories()[0]
            elif self.variant_of and len(list(self.active_stories())):
                cover_story = self.active_stories()[0]
            else:
                cover_story = None
        else:
            cover_story = None
        return cover_story, stories

    def active_covers(self):
        return self.cover_set.exclude(deleted=True)

    def variant_covers(self):
        """ returns the images from the variant issues """
        from cover import Cover
        if self.variant_of:
            variant_issues = list(self.variant_of.variant_set\
                                      .exclude(id=self.id)\
                                      .exclude(deleted=True)\
                                      .values_list('id', flat=True))
        else:
            variant_issues = list(self.variant_set.exclude(deleted=True)\
                                      .values_list('id', flat=True))
        variant_covers = Cover.objects.filter(issue__id__in=variant_issues)\
                                      .exclude(deleted=True)
        if self.variant_of:
            variant_covers |= self.variant_of.active_covers()
        return variant_covers

    def shown_covers(self):
        return self.active_covers(), self.variant_covers()

    def has_covers(self):
        return self.series.is_comics_publication and \
               self.active_covers().count() > 0

    def other_variants(self):
        if self.variant_of:
            variants = self.variant_of.variant_set.exclude(id=self.id)
        else:
            variants = self.variant_set.all()
        return list(variants.exclude(deleted=True))

    def _display_number(self):
        if self.title and self.series.has_issue_title:
            title = " - " + self.title
        else:
            title = ""
        if self.display_volume_with_number:
            return u'v%s#%s%s' % (self.volume, self.number, title)
        return self.number + title

    display_number = property(_display_number)

    # determine and set whether something has been indexed at all or not
    def set_indexed_status(self):
        from story import StoryType
        is_indexed = INDEXED['skeleton']
        if self.page_count > 0:
            total_count = self.active_stories()\
                              .aggregate(Sum('page_count'))['page_count__sum']
            if total_count > 0 and total_count >= Decimal(
                    '0.4') * self.page_count:
                is_indexed = INDEXED['full']
        if is_indexed != INDEXED['full'] and self.active_stories()\
          .filter(type=StoryType.objects.get(name='comic story')).count() > 0:
            is_indexed = INDEXED['partial']

        if self.is_indexed != is_indexed:
            self.is_indexed = is_indexed
            self.save()
        return self.is_indexed

    def index_status_name(self):
        """
        Text form of status.  If clauses arranged in order of most
        likely case to least.
        """
        if self.reserved:
            active = self.revisions.get(changeset__state__in=states.ACTIVE)
            return states.CSS_NAME[active.changeset.state]
        elif self.is_indexed == INDEXED['full']:
            return 'approved'
        elif self.is_indexed == INDEXED['partial']:
            return 'partial'
        else:
            return 'available'

    def get_prev_next_issue(self):
        """
        Find the issues immediately before and after the given issue.
        """

        prev_issue = None
        next_issue = None

        earlier_issues = self.series.active_base_issues()\
                             .filter(sort_code__lt=self.sort_code)
        earlier_issues = earlier_issues.order_by('-sort_code')
        if earlier_issues:
            prev_issue = earlier_issues[0]

        later_issues = self.series.active_base_issues()\
                           .filter(sort_code__gt=self.sort_code)
        later_issues = later_issues.order_by('sort_code')
        if later_issues:
            next_issue = later_issues[0]

        return [prev_issue, next_issue]

    def delete(self):
        self.deleted = True
        self.reserved = False
        self.save()

    def has_reprints(self):
        from story import STORY_TYPES
        """Simplifies UI checks for conditionals.  notes and reprint fields"""
        return self.from_reprints.count() or \
               self.to_reprints.exclude(target__type__id=STORY_TYPES['promo']).count() or \
               self.from_issue_reprints.count() or \
               self.to_issue_reprints.count()

    def deletable(self):
        if self.cover_revisions.filter(changeset__state__in=states.ACTIVE)\
                                   .count() > 0:
            return False
        if self.variant_set.filter(deleted=False).count() > 0:
            return False
        if self.has_reprints():
            return False
        for story in self.active_stories():
            if story.has_reprints(notes=False):
                return False
        return True

    def can_upload_variants(self):
        if self.has_covers():
            return self.revisions.filter(changeset__state__in=states.ACTIVE,
                                         deleted=True).count() == 0
        else:
            return False

    def get_absolute_url(self):
        return urlresolvers.reverse('show_issue', kwargs={'issue_id': self.id})

    def full_name(self, variant_name=True):
        if variant_name and self.variant_name:
            return u'%s #%s [%s]' % (self.series.full_name(),
                                     self.display_number, self.variant_name)
        else:
            return u'%s #%s' % (self.series.full_name(), self.display_number)

    def short_name(self):
        if self.variant_name:
            return u'%s #%s [%s]' % (self.series.name, self.display_number,
                                     self.variant_name)
        else:
            return u'%s #%s' % (self.series.name, self.display_number)

    def __unicode__(self):
        if self.variant_name:
            return u'%s #%s [%s]' % (self.series, self.display_number,
                                     self.variant_name)
        else:
            return u'%s #%s' % (self.series, self.display_number)
Exemple #24
0
class ForumSubSection(models.Model):
    forum_section = models.ForeignKey(ForumSection)
    link = models.CharField('Link', max_length=250)
    title = models.CharField('Title', max_length=250)
    threads = generic.GenericRelation(KongThread)
Exemple #25
0
class Discount(models.Model):
    """A discount which is given to the customer if several criteria
    fullfilled.

    **Attributes:**

    name
        The name of the discount. This can be displayed to the customer.

    value
        The value of the discount, can be absolute or percentage dependend on
        the type of the discount.

    type
        The type of the discount. Absolute or percentage.

    tax
        The included tax within the discount.

    sku
        The SKU of the discount.

    criteria_objects
        Criteria which must all valid to make the discount happen.

    """
    name = models.CharField(_(u"Name"), max_length=100)
    value = models.FloatField(_(u"Value"))
    type = models.PositiveSmallIntegerField(_(u"Type"), choices=DISCOUNT_TYPE_CHOICES, default=DISCOUNT_TYPE_ABSOLUTE)
    tax = models.ForeignKey(Tax, verbose_name=_(u"Tax"), blank=True, null=True)
    sku = models.CharField(_(u"SKU"), blank=True, max_length=50)
    criteria_objects = generic.GenericRelation(CriteriaObjects,
        object_id_field="content_id", content_type_field="content_type")

    def __unicode__(self):
        return self.name

    def is_valid(self, request, product=None):
        """The shipping method is valid if it has no criteria or if all assigned
        criteria are true.

        If product is given the product is tested otherwise the whole cart.
        """
        return lfs.criteria.utils.is_valid(request, self, product)

    def get_tax(self, request, product=None):
        """Returns the absolute tax of the voucher.
        """
        price_gross = self.get_price_gross(request, product)
        if self.tax:
            return price_gross * (self.tax.rate / (100 + self.tax.rate))
        else:
            if self.type == DISCOUNT_TYPE_ABSOLUTE:
                return 0.0
            else:
                cart = lfs.cart.utils.get_cart(request)
                return cart.get_tax(request) * (self.value / 100)

    def get_price_net(self, request, product=None):
        """Returns the net price of the discount.
        """
        return self.get_price_gross(request, product) - self.get_tax(request, product)

    def get_price_gross(self, request, product=None):
        """Returns the gross price of the discount.
        """
        if self.type == DISCOUNT_TYPE_ABSOLUTE:
            return self.value

        cart = lfs.cart.utils.get_cart(request)

        if cart is not None:
            return cart.get_price_gross(request) * (self.value / 100)
        elif product is not None:
            return product.get_price_gross(request) * (self.value / 100)

        return 0.0
Exemple #26
0
class HasLinks(models.Model):
    links = generic.GenericRelation(Link)

    class Meta:
        abstract = True
Exemple #27
0
                site_id=settings.SITE_ID)
        c.save()
        return c


class TestCaseEmailSettings(models.Model):
    case = models.OneToOneField(TestCase, related_name='email_settings')
    notify_on_case_update = models.BooleanField(default=False)
    notify_on_case_delete = models.BooleanField(default=False)
    auto_to_case_author = models.BooleanField(default=False)
    auto_to_case_tester = models.BooleanField(default=False)
    auto_to_run_manager = models.BooleanField(default=False)
    auto_to_run_tester = models.BooleanField(default=False)
    auto_to_case_run_assignee = models.BooleanField(default=False)

    cc_list = generic.GenericRelation(Contact, object_id_field='object_pk')

    class Meta:
        pass

    def add_cc(self, email_addrs):
        '''Add email addresses to CC list

        Arguments:
        - email_addrs: str or list, holding one or more email addresses
        '''

        emailaddr_list = []
        if not isinstance(email_addrs, list):
            emailaddr_list.append(email_addrs)
        else:
Exemple #28
0
class B(models.Model):
    a = generic.GenericRelation(A)

    class Meta:
        ordering = ('id', )
Exemple #29
0
class Page(ModelBase):
    """Placeholder model for pages."""
    object_type = object_types['article']

    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=110)
    sub_header = models.CharField(max_length=150, blank=True, null=True)
    content = RichTextField(config_name='rich', blank='False')
    author = models.ForeignKey('users.UserProfile', related_name='pages')
    last_update = models.DateTimeField(auto_now_add=True,
                                       default=datetime.datetime.now)
    project = models.ForeignKey('projects.Project', related_name='pages')
    listed = models.BooleanField(default=True)
    minor_update = models.BooleanField(default=True)
    collaborative = models.BooleanField(default=True)
    index = models.IntegerField()
    deleted = models.BooleanField(default=False)

    comments = generic.GenericRelation(PageComment,
                                       content_type_field='page_content_type',
                                       object_id_field='page_id')

    # Badges to which the user can submit their work to.
    # Used to facilitate both posting a comment to the task with
    # a link to the work they did on the task and apply for skills badges
    badges_to_apply = models.ManyToManyField(
        'badges.Badge',
        null=True,
        blank=False,
        related_name='tasks_accepting_submissions')

    def __unicode__(self):
        return self.title

    @models.permalink
    def get_absolute_url(self):
        return ('page_show', (), {
            'slug': self.project.slug,
            'page_slug': self.slug,
        })

    def friendly_verb(self, verb):
        if verbs['post'] == verb:
            return _('added')

    def save(self):
        """Make sure each page has a unique url."""
        count = 1
        if not self.slug:
            slug = slugify(self.title)
            self.slug = slug
            while True:
                existing = Page.objects.filter(project__slug=self.project.slug,
                                               slug=self.slug)
                if len(existing) == 0:
                    break
                self.slug = "%s-%s" % (slug, count + 1)
                count += 1
        if not self.index:
            if self.listed:
                max_index = Page.objects.filter(project=self.project,
                                                listed=True).aggregate(
                                                    Max('index'))['index__max']
                self.index = max_index + 1 if max_index else 1
            else:
                self.index = 0
        super(Page, self).save()

    def get_next_page(self):
        if self.listed and not self.deleted:
            try:
                return self.project.pages.filter(deleted=False,
                                                 index__gt=self.index,
                                                 listed=True)[0]
            except IndexError:
                pass
        return None

    def get_next_badge_can_apply(self, profile):
        next_badges = self.badges_to_apply.order_by('id')
        next_badges_can_apply = []
        for badge in next_badges:
            awarded = Award.objects.filter(user=profile, badge=badge).exists()
            applied = Submission.objects.filter(author=profile,
                                                badge=badge).exists()
            elegible = badge.is_eligible(profile.user)
            if not awarded and not applied and elegible:
                next_badges_can_apply.append(badge)
            if len(next_badges_can_apply) > 1:
                break
        next_badge = next_badges_can_apply[0] if next_badges_can_apply else None
        is_last_badge = not next_badges_can_apply[1:]
        return next_badge, is_last_badge

    def can_edit(self, user):
        if self.project.is_organizing(user):
            return True
        if self.collaborative:
            return self.project.is_participating(user)
        return False

    def first_level_comments(self):
        return self.comments.filter(
            reply_to__isnull=True).order_by('-created_on')

    def can_comment(self, user, reply_to=None):
        return self.project.is_participating(user)

    def get_comment_url(self, comment, user):
        comment_index = 0
        abs_reply_to = comment.abs_reply_to or comment
        for first_level_comment in self.first_level_comments():
            if abs_reply_to.id == first_level_comment.id:
                break
            comment_index += 1
        items_per_page = settings.PAGINATION_DEFAULT_ITEMS_PER_PAGE
        page = (comment_index / items_per_page) + 1
        url = self.get_absolute_url()
        return url + '?pagination_page_number=%s#%s' % (page, comment.id)

    def comments_fire_activity(self):
        return True

    def comment_notification_recipients(self, comment):
        from users.models import UserProfile
        participants = self.project.participants()
        from_organizer = self.project.organizers().filter(
            user=comment.author).exists()
        if from_organizer:
            participants = participants.filter(
                no_organizers_content_updates=False)
        else:
            participants = participants.filter(
                no_participants_content_updates=False)
        return UserProfile.objects.filter(
            id__in=participants.values('user__id'))

    def recent_activity(self, min_count=2):
        comments = self.comments.filter(deleted=False)
        today = datetime.date.today()
        day = today.day
        month = today.month
        year = today.year
        # get today's commments count
        today_comments_count = comments.filter(created_on__day=day,
                                               created_on__month=month,
                                               created_on__year=year).count()
        if today_comments_count >= min_count:
            return today_comments_count, _('today')
        # get this week comments count
        week = today.isocalendar()[1]
        first_day = datetime.date(year, 1, 1)
        delta_days = first_day.isoweekday() - 1
        delta_weeks = week
        if year == first_day.isocalendar()[0]:
            delta_weeks -= 1
        week_start_delta = datetime.timedelta(days=-delta_days,
                                              weeks=delta_weeks)
        week_start = first_day + week_start_delta
        week_end_delta = datetime.timedelta(days=7 - delta_days,
                                            weeks=delta_weeks)
        week_end = first_day + week_end_delta
        this_week_comments_count = comments.filter(
            created_on__gte=week_start, created_on__lt=week_end).count()
        if this_week_comments_count >= min_count:
            return this_week_comments_count, _('this week')
        # get this month comments count
        this_month_comments_count = comments.filter(
            created_on__month=month, created_on__year=year).count()
        return this_month_comments_count, _('this month')
Exemple #30
0
class UserProfile(models.Model):
    '''
	'''
    user = models.OneToOneField(User)
    username = models.CharField(max_length=30)

    columns = generic.GenericRelation(Column)

    username_change_time = models.DateTimeField(blank=True, null=True)
    avatar = models.ForeignKey(Avatar, blank=True, null=True)
    avatar_change_time = models.DateTimeField(blank=True, null=True)
    name = models.CharField(max_length=NAME_MAX_LEN, blank=True)
    name_change_time = models.DateTimeField(blank=True, null=True)

    website = models.URLField(blank=True)
    signature = models.CharField(max_length=SIGNATURE_MAX_LEN, blank=True)
    detail = models.TextField(blank=True)

    def get_name(self):
        if self.name:
            return self.name
        else:
            return self.username

    def __unicode__(self):
        return self.get_name()

    def is_can_change_name(self):
        if not self.name_change_time:
            return True
        can_change_days = timedelta(days=PROFILE_NAME_CHANGE_DAYS)
        can_change_time = self.name_change_time + can_change_days

        if now() > can_change_time:
            return True
        else:
            return False

    def change_name(self, name):
        if self.is_can_change_name() and name:
            self.name = name
            self.name_change_time = now()
            self.save()
            return True
        else:
            return False

    def detail_change(self, data):
        if self.signature != data['signature']:
            self.signature = data['signature']
        if self.detail != data['detail']:
            self.detail = data['detail']
        self.save()
        return True

    def get_absolute_url(self):
        return '/people/' + self.username + '/'

    def get_column(self):
        try:
            return self.columns.all()[0]
        except:
            return create_column(self)