<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

import hashlib

from blinker import Signal
from flask import url_for
from mongoengine.signals import pre_save, post_save

from udata.core.storages import images, default_image_basename
from udata.i18n import lazy_gettext as _
from udata.models import db, WithMetrics, Issue, Follow
from udata.utils import hash_url

__all__ = ('Reuse', 'REUSE_TYPES', 'ReuseIssue', 'FollowReuse')


REUSE_TYPES = {
    'api': _('API'),
    'application': _('Application'),
    'idea': _('Idea'),
    'news_article': _('News Article'),
    'paper': _('Paper'),
    'post': _('Post'),
    'visualization': _('Visualization'),
}


IMAGE_SIZES = [100, 50, 25]
IMAGE_MAX_SIZE = 800


class ReuseQuerySet(db.BaseQuerySet):
    def visible(self):
        return self(private__ne=True, datasets__0__exists=True, deleted=None)

    def hidden(self):
        return self(db.Q(private=True) | db.Q(datasets__0__exists=False) | db.Q(deleted__ne=None))

    def owned_by(self, *owners):
        Qs = db.Q()
        for owner in owners:
            Qs |= db.Q(owner=owner) | db.Q(organization=owner)
        return self(Qs)


class Reuse(db.Datetimed, WithMetrics, db.Document):
    title = db.StringField(max_length=255, required=True)
    slug = db.SlugField(max_length=255, required=True, populate_from='title', update=True)
    description = db.StringField(required=True)
    type = db.StringField(required=True, choices=REUSE_TYPES.keys())
    url = db.StringField(required=True)
    urlhash = db.StringField(required=True, unique=True)
    image_url = db.StringField()
    image = db.ImageField(fs=images, basename=default_image_basename, max_size=IMAGE_MAX_SIZE, thumbnails=IMAGE_SIZES)
    datasets = db.ListField(db.ReferenceField('Dataset', reverse_delete_rule=db.PULL))
    tags = db.ListField(db.StringField())

    private = db.BooleanField()
    owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
    organization = db.ReferenceField('Organization', reverse_delete_rule=db.NULLIFY)

    ext = db.MapField(db.GenericEmbeddedDocumentField())
    extras = db.ExtrasField()

    featured = db.BooleanField()
    deleted = db.DateTimeField()

    def __str__(self):
        return self.title or ''

    __unicode__ = __str__

    meta = {
        'allow_inheritance': True,
        'indexes': ['-created_at', 'owner', 'urlhash'],
        'ordering': ['-created_at'],
        'queryset_class': ReuseQuerySet,
    }

    before_save = Signal()
    after_save = Signal()
    on_create = Signal()
    on_update = Signal()
    before_delete = Signal()
    after_delete = Signal()
    on_delete = Signal()

    verbose_name = _('reuse')

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        # Emit before_save
        cls.before_save.send(document)

    @classmethod
    def post_save(cls, sender, document, **kwargs):
        cls.after_save.send(document)
        if kwargs.get('created'):
            cls.on_create.send(document)
        else:
            cls.on_update.send(document)

    @property
    def display_url(self):
        return url_for('reuses.show', reuse=self)

    @property
    def external_url(self):
        return url_for('reuses.show', reuse=self, _external=True)

    @property
    def type_label(self):
        return REUSE_TYPES[self.type]

    def clean(self):
        '''Auto populate urlhash from url'''
        if not self.urlhash or 'url' in self._get_changed_fields():
            self.urlhash = hash_url(self.url)
        super(Reuse, self).clean()

    @classmethod
    def get(cls, id_or_slug):
        obj = cls.objects(slug=id_or_slug).first()
        return obj or cls.objects.get_or_404(id=id_or_slug)

    @classmethod
    def url_exists(cls, url):
        urlhash = hash_url(url)
        return cls.objects(urlhash=urlhash).count() > 0


pre_save.connect(Reuse.pre_save, sender=Reuse)
post_save.connect(Reuse.post_save, sender=Reuse)


class ReuseIssue(Issue):
    subject = db.ReferenceField(Reuse)


class FollowReuse(Follow):
    following = db.ReferenceField(Reuse)
<commit_msg>Added hardware reuse type<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from blinker import Signal
from flask import url_for
from mongoengine.signals import pre_save, post_save

from udata.core.storages import images, default_image_basename
from udata.i18n import lazy_gettext as _
from udata.models import db, WithMetrics, Issue, Follow
from udata.utils import hash_url

__all__ = ('Reuse', 'REUSE_TYPES', 'ReuseIssue', 'FollowReuse')


REUSE_TYPES = {
    'api': _('API'),
    'application': _('Application'),
    'idea': _('Idea'),
    'news_article': _('News Article'),
    'paper': _('Paper'),
    'post': _('Post'),
    'visualization': _('Visualization'),
    'hardware': _('Connected device'),
}


IMAGE_SIZES = [100, 50, 25]
IMAGE_MAX_SIZE = 800


class ReuseQuerySet(db.BaseQuerySet):
    def visible(self):
        return self(private__ne=True, datasets__0__exists=True, deleted=None)

    def hidden(self):
        return self(db.Q(private=True) | db.Q(datasets__0__exists=False) | db.Q(deleted__ne=None))

    def owned_by(self, *owners):
        Qs = db.Q()
        for owner in owners:
            Qs |= db.Q(owner=owner) | db.Q(organization=owner)
        return self(Qs)


class Reuse(db.Datetimed, WithMetrics, db.Document):
    title = db.StringField(max_length=255, required=True)
    slug = db.SlugField(max_length=255, required=True, populate_from='title', update=True)
    description = db.StringField(required=True)
    type = db.StringField(required=True, choices=REUSE_TYPES.keys())
    url = db.StringField(required=True)
    urlhash = db.StringField(required=True, unique=True)
    image_url = db.StringField()
    image = db.ImageField(fs=images, basename=default_image_basename, max_size=IMAGE_MAX_SIZE, thumbnails=IMAGE_SIZES)
    datasets = db.ListField(db.ReferenceField('Dataset', reverse_delete_rule=db.PULL))
    tags = db.ListField(db.StringField())

    private = db.BooleanField()
    owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
    organization = db.ReferenceField('Organization', reverse_delete_rule=db.NULLIFY)

    ext = db.MapField(db.GenericEmbeddedDocumentField())
    extras = db.ExtrasField()

    featured = db.BooleanField()
    deleted = db.DateTimeField()

    def __str__(self):
        return self.title or ''

    __unicode__ = __str__

    meta = {
        'allow_inheritance': True,
        'indexes': ['-created_at', 'owner', 'urlhash'],
        'ordering': ['-created_at'],
        'queryset_class': ReuseQuerySet,
    }

    before_save = Signal()
    after_save = Signal()
    on_create = Signal()
    on_update = Signal()
    before_delete = Signal()
    after_delete = Signal()
    on_delete = Signal()

    verbose_name = _('reuse')

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        # Emit before_save
        cls.before_save.send(document)

    @classmethod
    def post_save(cls, sender, document, **kwargs):
        cls.after_save.send(document)
        if kwargs.get('created'):
            cls.on_create.send(document)
        else:
            cls.on_update.send(document)

    @property
    def display_url(self):
        return url_for('reuses.show', reuse=self)

    @property
    def external_url(self):
        return url_for('reuses.show', reuse=self, _external=True)

    @property
    def type_label(self):
        return REUSE_TYPES[self.type]

    def clean(self):
        '''Auto populate urlhash from url'''
        if not self.urlhash or 'url' in self._get_changed_fields():
            self.urlhash = hash_url(self.url)
        super(Reuse, self).clean()

    @classmethod
    def get(cls, id_or_slug):
        obj = cls.objects(slug=id_or_slug).first()
        return obj or cls.objects.get_or_404(id=id_or_slug)

    @classmethod
    def url_exists(cls, url):
        urlhash = hash_url(url)
        return cls.objects(urlhash=urlhash).count() > 0


pre_save.connect(Reuse.pre_save, sender=Reuse)
post_save.connect(Reuse.post_save, sender=Reuse)


class ReuseIssue(Issue):
    subject = db.ReferenceField(Reuse)


class FollowReuse(Follow):
    following = db.ReferenceField(Reuse)

{'fraction_non_alphanumeric': 0.12562023478155634, 'fraction_numerical': 0.0060510710395740045, 'mean_word_length': 3.5456545654565454, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4709149', 'n_tokens_mistral': 2810, 'n_tokens_neox': 2708, 'n_words': 544}