コード例 #1
0
ファイル: models.py プロジェクト: ikhanal/django-model-utils
class SoftDeletableModel(models.Model):
    """
    An abstract base class model with a ``is_removed`` field that
    marks entries that are not going to be used anymore, but are
    kept in db for any reason.
    Default manager returns only not-removed entries.
    """

    is_removed = models.BooleanField(default=False)

    class Meta:
        abstract = True

    objects = SoftDeletableManager(_emit_deprecation_warnings=True)
    available_objects = SoftDeletableManager()
    all_objects = models.Manager()

    def delete(self, using=None, soft=True, *args, **kwargs):
        """
        Soft delete object (set its ``is_removed`` field to True).
        Actually delete object if setting ``soft`` to False.
        """
        if soft:
            self.is_removed = True
            self.save(using=using)
        else:
            return super().delete(using=using, *args, **kwargs)
コード例 #2
0
ファイル: models.py プロジェクト: MusaZhou/muslim_app
class PDFDoc(CommonApprovableModel):
    title = models.CharField(verbose_name=_('Title'), max_length=200, unique=True)
    description = models.TextField(verbose_name=_('Description'), blank=True, null=True)
    download_count = models.PositiveIntegerField(null=True, verbose_name=_('Download Count'), default=0)
    author = models.CharField(max_length=100, null=True, blank=True, verbose_name=_('Author'))
    publish_year = models.DateField(null=True, blank=True, verbose_name=_('Publish Year'))
    
    objects = models.Manager()
    exist_objects = SoftDeletableManager()
    approved_pdf = ApprovedManager()
    
    class Meta:
        ordering = ["-upload_time"]
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title, allow_unicode=True)
        super(PDFDoc, self).save(*args, **kwargs)
    
    def canShow(self):
        return self.approve_status == 'approved'
    
    def get_absolute_url(self):
        return reverse('showcase:detail_pdf', args=[self.slug])
    
    @property
    def user_link(self):
        return self.get_absolute_url()
    
    def __str__(self):
        return self.title
コード例 #3
0
class ApiKey(TimeStampedModel, SoftDeletableModel):
    api_key = models.CharField(max_length=50,
                               null=False,
                               blank=True,
                               unique=True)

    live = ApiKeyManager()

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    @ecached_property('is_expire:{self.id}', 60)
    def is_expire(self):
        try:
            info = blockcypher.get_token_info(self.api_key)
            limits = info.get('limits', None)
            hits_history = info.get('hits_history', None)
            if not limits:
                return True
            if not hits_history:
                return False
            else:
                current_api_hour = sum(
                    [i['api/hour'] for i in hits_history if 'api/hour' in i])
                current_hooks_hour = sum([
                    i['hooks/hour'] for i in hits_history if 'hooks/hour' in i
                ])
                if current_api_hour < limits['api/hour'] and \
                   current_hooks_hour < limits['hooks/hour']:
                    return False
        except:
            return True

    def __str__(self):
        return self.api_key
コード例 #4
0
ファイル: models.py プロジェクト: MusaZhou/muslim_app
class VideoAlbum(ApprovableModel, SoftDeletableModel):
    title = models.CharField(max_length=100, verbose_name=_('Title'), unique=True) 
    description = models.TextField(blank=True, null=True, verbose_name=_('Description'))
    slug = models.CharField(unique=True, null=True, blank=True, db_index=True, max_length=100, \
                            validators=[validators.validate_unicode_slug])
    images = GenericRelation(Image, related_query_name='imaged_video_album', verbose_name=_('Public Image'))
    
    objects = models.Manager()
    exist_objects = SoftDeletableManager()
    approved_albums = ApprovedManager()
    
    class Meta:
        ordering = ["-upload_time"]
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title, allow_unicode=True)
        super(VideoAlbum, self).save(*args, **kwargs)
            
    def __str__(self):
        return self.title
    
    def get_image(self):
        return self.images.last()
    
    def exist_videos(self):
        return self.album_videos.filter(is_removed=0)
コード例 #5
0
ファイル: models.py プロジェクト: gregseb/davisluton.com
class BaseModel(TimeStampedModel, StatusModel, SoftDeletableModel):
    STATUS = Choices('draft', 'published')

    objects = SoftDeletableManager()

    class Meta:
        abstract = True
コード例 #6
0
ファイル: models.py プロジェクト: horosin/mcod-backend
class License(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (update_related_datasets, ),
        'published': (update_related_datasets, ),
        'restored': (update_related_datasets, ),
        'removed': (null_in_related_datasets, ),
    }
    name = models.CharField(max_length=200, verbose_name=_('Name'))
    title = models.CharField(max_length=250, verbose_name=_('Title'))
    url = models.URLField(blank=True, null=True, verbose_name=_('URL'))

    def __str__(self):
        return self.title

    i18n = TranslationField(fields=("name", "title"))
    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()
    tracker = FieldTracker()
    slugify_field = 'name'

    @classmethod
    def accusative_case(cls):
        return _("acc: License")

    class Meta:
        verbose_name = _('License')
        verbose_name_plural = _('Licenses')
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=["i18n"]),
        ]
コード例 #7
0
ファイル: models.py プロジェクト: mugadza/grecerola
class Transaction(TimeStampedModel, SoftDeletableModel):
    reference = models.CharField(max_length=255)

    wallet = models.ForeignKey('wallet.Wallet',
                               related_name='transactions',
                               on_delete=models.PROTECT)

    currency = models.CharField(
        max_length=settings.DEFAULT_CURRENCY_CODE_LENGTH,
        default=settings.DEFAULT_CURRENCY,
    )

    transaction_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
    )
    amount = MoneyField(amount_field="transaction_amount",
                        currency_field="currency")

    is_pending = models.BooleanField(default=False)

    confirmed_at = models.DateTimeField(null=True, blank=True)

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        ordering = ['wallet']

    def __str__(self):
        return '({})'.format(self.wallet)
コード例 #8
0
ファイル: models.py プロジェクト: MusaZhou/muslim_app
class AppVersion(SoftDeletableModel):
    version_number = models.CharField(max_length=10,
                                      validators=[validators.RegexValidator("[a-zA-Z0-9\.]*")],
                                      verbose_name=_('Version No.'))
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Created Time'), db_index=True)
    approve_status = models.CharField(max_length=10,
                                      choices=APPROVE_CHOICES,
                                      default='new', verbose_name=_('Approve Status'))
    approved_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                    on_delete=models.CASCADE,
                                    null=True, blank=True, verbose_name=_('Approved By'))
    approved_time = models.DateTimeField(null=True, blank=True, verbose_name=_('Approved Time'))
    mobile_app = models.ForeignKey(MobileApp, on_delete=models.CASCADE, blank=True,
                                   null=True, verbose_name=_('Application'), related_name='versions')
    whats_new = models.TextField(blank=True, null=True, verbose_name=_("What's New"))
    translator = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Translator"))
    android_version = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Supported Android Version"))
    remark = models.CharField(max_length=200, null=True, blank=True, verbose_name=_("Remark"))
    
    objects = models.Manager()
    exist_objects = SoftDeletableManager()
    approved_manager = ApprovedManager()
    
    class Meta:
        ordering = ["-created_time"]
        unique_together = (('mobile_app', 'version_number'),)
        get_latest_by = "created_time"
    
    def __str__(self):
        return self.version_number
コード例 #9
0
ファイル: models.py プロジェクト: MusaZhou/muslim_app
class InspiredVideo(CommonApprovableModel):
    video = GenericRelation(Video, related_query_name='video_controller', verbose_name=_('video'))
    title = models.CharField(max_length=100, verbose_name=_('title'), unique=True)
    description = models.TextField(blank=True, null=True, verbose_name=_('description'))
    album = models.ForeignKey(VideoAlbum, null=True, blank=True, verbose_name=_("Album"),on_delete=models.CASCADE,\
                              related_name='album_videos')
    view_count = models.PositiveIntegerField(verbose_name=_("View Count"), default=0)
    images = GenericRelation(Image, related_query_name='thumnail_video')
    
    objects = models.Manager()
    exist_objects = SoftDeletableManager()
    approved_videos = ApprovedManager()
    shown_videos = ShownInspiredVideoManager()
    
    class Meta:
        ordering = ["-upload_time"]
        
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title, allow_unicode=True)
    
        super(InspiredVideo, self).save(*args, **kwargs)
        
    def latest_valid_video(self):
        return self.video.exclude(file__isnull=True).exclude(file__exact='').last()
    
    def thumbnail(self):
        return self.images.last()
    
    def thumbnail_path(self):
        return str(self.thumbnail() or '')
    
    def __str__(self):
        return self.title
    
    @property
    def userLink(self):
        return reverse('showcase:detail_inspired_video', args=[self.slug])
    
    @property
    def user_link_mobile(self):
        return reverse('showcase:detail_inspired_video', args=[self.slug])

    def video_duration(self):
        latest_video = self.latest_valid_video()
        return latest_video.duration if latest_video else 0
    
    @property
    def video_duration_str(self):
        seconds = self.video_duration()
        return str(datetime.timedelta(seconds=seconds))
    
    def get_absolute_url(self):
        return reverse('showcase:detail_inspired_video', args=[self.slug])
コード例 #10
0
class ArticleCategory(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (update_related_articles, ),
        'published': (update_related_articles, ),
        'restored': (update_related_articles, ),
        'removed': (update_related_articles, ),
    }

    name = models.CharField(max_length=100,
                            unique=True,
                            verbose_name=_("name"))
    description = models.CharField(max_length=500,
                                   blank=True,
                                   verbose_name=_("Description"))

    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='article_categories_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='article_categories_modified')

    def __str__(self):
        return self.name_i18n

    i18n = TranslationField(fields=("name", "description"))
    tracker = FieldTracker()
    slugify_field = 'name'

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    class Meta:
        verbose_name = _("Article Category")
        verbose_name_plural = _("Article Categories")
        db_table = "article_category"
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=['i18n']),
        ]
コード例 #11
0
class Category(StatusModel, SoftDeletableModel, TimeStampedModel):
    STATUS = Choices(*STATUS_CHOICES)
    slug = models.SlugField(max_length=100, unique=True)
    # TODO: change to VarChar(100)
    title = models.TextField(verbose_name=_("Title"))
    description = models.TextField(null=True, verbose_name=_("Description"))
    color = models.CharField(max_length=20,
                             default="#000000",
                             null=True,
                             verbose_name=_("Color"))
    image = models.ImageField(max_length=200,
                              storage=storages.get_storage('common'),
                              upload_to='',
                              blank=True,
                              null=True,
                              verbose_name=_("Image URL"))
    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='categories_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='categories_modified')

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    class Meta:
        db_table = "category"
        verbose_name = _("Category")
        verbose_name_plural = _("Categories")
        default_manager_name = "objects"

    @classmethod
    def accusative_case(cls):
        return _("acc: Category")

    def __str__(self):
        return self.slug
コード例 #12
0
class BasePage(SoftDeletableModel):
    title = models.CharField(max_length=50)
    content = RichTextField(blank=True)
    creator = models.ForeignKey(Account)
    creation_date = models.DateTimeField(auto_now_add=True)
    group_id = models.UUIDField(primary_key=False, default=uuid.uuid4, editable=False)
    version = models.IntegerField()
    changelog = models.CharField(max_length=50, blank=True)

    objects = Manager()
    active_pages = SoftDeletableManager()

    class Meta:
        abstract = True

    @property
    def category(self):
        return self.__class__.__name__
コード例 #13
0
class SoftDeletableModel(models.Model):
    """
    An abstract base class model with a ``is_removed`` field that
    marks entries that are not going to be used anymore, but are
    kept in db for any reason.
    Default manager returns only not-removed entries.
    """
    is_removed = models.BooleanField(default=False)

    class Meta:
        abstract = True

    objects = SoftDeletableManager()

    def delete(self, using=None, keep_parents=False):
        """
        Soft delete object (set its ``is_removed`` field to True)
        """
        self.is_removed = True
        self.save()
コード例 #14
0
ファイル: models.py プロジェクト: mugadza/grecerola
class Bank(TimeStampedModel, SoftDeletableModel):
    ACCOUNT_TYPE = Choices(('Savings', _('Savings')), ('Check', _('Check')))

    uuid = ShortUUIDField(max_length=8,
                          unique=True,
                          editable=False,
                          verbose_name='Public identifier')
    account_name = models.CharField(max_length=256, blank=True)
    account_holder_name = models.CharField(max_length=256, blank=True)
    bank_name = models.CharField(max_length=256, blank=True)
    account_number = models.PositiveIntegerField(
        unique=True,
        validators=[MinValueValidator(10000),
                    MaxValueValidator(999999999999)])
    account_type = models.CharField(choices=ACCOUNT_TYPE,
                                    default=ACCOUNT_TYPE.Savings,
                                    max_length=20)
    bank_branch_code = models.PositiveIntegerField(
        unique=False,
        validators=[MinValueValidator(1000),
                    MaxValueValidator(99999999)])
    user = models.OneToOneField(settings.AUTH_USER_MODEL,
                                related_name='bank',
                                unique=True,
                                on_delete=models.PROTECT)

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        ordering = ['account_number']

    @property
    def account_reference_id(self):
        start_index = int(str(self.account_number)[4])
        account_reference = "ACC-" + str(
            self.account_number) + "-" + self.uuid[start_index:start_index + 4]
        return account_reference.upper()

    def __str__(self):
        return '({}) {}'.format(self.account_name.upper(), self.account_number)
コード例 #15
0
class Article(ExtendedModel):
    SIGNALS_MAP = {
        'updated':
        (search_signals.update_document, core_signals.notify_updated),
        'published':
        (search_signals.update_document, core_signals.notify_published),
        'restored':
        (search_signals.update_document, core_signals.notify_restored),
        'removed':
        (search_signals.remove_document, core_signals.notify_removed),
    }

    title = models.CharField(max_length=300, verbose_name=_("Title"))
    notes = RichTextUploadingField(verbose_name=_("Notes"), null=True)
    license_old_id = models.CharField(max_length=20,
                                      blank=True,
                                      null=True,
                                      verbose_name=_("License ID"))
    license = models.ForeignKey('licenses.License',
                                on_delete=models.DO_NOTHING,
                                blank=True,
                                null=True,
                                verbose_name=_("License ID"))
    author = models.CharField(max_length=50,
                              blank=True,
                              null=True,
                              verbose_name=_("Author"))
    category = models.ForeignKey(ArticleCategory,
                                 on_delete=models.PROTECT,
                                 verbose_name=_('Category'))
    tags = models.ManyToManyField('tags.Tag',
                                  db_table='article_tag',
                                  blank=True,
                                  verbose_name=_("Tags"),
                                  related_name='articles',
                                  related_query_name="article")
    datasets = models.ManyToManyField('datasets.Dataset',
                                      db_table='article_dataset',
                                      verbose_name=_('Datasets'),
                                      related_name='articles',
                                      related_query_name="article")

    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='articles_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='articles_modified')

    @classmethod
    def accusative_case(cls):
        return _("acc: Article")

    def __str__(self):
        return self.title

    def published_datasets(self):
        return self.datasets.filter(status='published')

    @property
    def tags_list(self):
        return [tag.name_translated for tag in self.tags.all()]

    i18n = TranslationField(fields=("title", "notes"))
    tracker = FieldTracker()
    slugify_field = 'title'

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    class Meta:
        verbose_name = _("Article")
        verbose_name_plural = _("Articles")
        db_table = "article"
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=["i18n"]),
        ]
コード例 #16
0
class Organization(ExtendedModel):
    SIGNALS_MAP = {
        'removed':
        (remove_related_datasets, search_signals.remove_document_with_related,
         core_signals.notify_removed),
    }

    title = models.CharField(max_length=100, verbose_name=_('Title'))
    description = models.TextField(blank=True,
                                   null=True,
                                   verbose_name=_('Description'))
    image = models.ImageField(max_length=254,
                              storage=storages.get_storage('organizations'),
                              upload_to='%Y%m%d',
                              blank=True,
                              null=True,
                              verbose_name=_('Image URL'))
    postal_code = models.CharField(max_length=6,
                                   null=True,
                                   verbose_name=_('Postal code'))
    city = models.CharField(max_length=200, null=True, verbose_name=_("City"))
    street_type = models.CharField(max_length=50,
                                   null=True,
                                   verbose_name=_("Street type"))
    street = models.CharField(max_length=200,
                              null=True,
                              verbose_name=_("Street"))
    street_number = models.CharField(max_length=200,
                                     null=True,
                                     blank=True,
                                     verbose_name=_("Street number"))
    flat_number = models.CharField(max_length=200,
                                   null=True,
                                   blank=True,
                                   verbose_name=_("Flat number"))

    email = models.CharField(max_length=300,
                             null=True,
                             verbose_name=_("Email"))
    epuap = models.CharField(max_length=500,
                             null=True,
                             verbose_name=_("EPUAP"))
    fax = models.CharField(max_length=50, null=True, verbose_name=_("Fax"))
    fax_internal = models.CharField(max_length=20,
                                    null=True,
                                    blank=True,
                                    verbose_name=_('int.'))

    institution_type = models.CharField(max_length=50,
                                        choices=INSTITUTION_TYPE_CHOICES,
                                        default=INSTITUTION_TYPE_CHOICES[1][0],
                                        verbose_name=_("Institution type"))
    regon = models.CharField(max_length=20, null=True, verbose_name=_("REGON"))
    tel = models.CharField(max_length=50, null=True, verbose_name=_("Phone"))
    tel_internal = models.CharField(max_length=20,
                                    null=True,
                                    blank=True,
                                    verbose_name=_('int.'))
    website = models.CharField(max_length=200,
                               null=True,
                               verbose_name=_("Website"))

    i18n = TranslationField(fields=('title', 'description', 'slug'))

    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='organizations_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='organizations_modified')

    def __str__(self):
        if self.title:
            return self.title
        return self.slug

    def get_url_path(self):
        if self.id:
            try:
                return reverse("admin:applications_application_change",
                               kwargs={"object_id": self.id})
            except NoReverseMatch:
                return ""
        return ""

    @property
    def image_url(self):
        try:
            return self.image.url
        except ValueError:
            return ''

    @property
    def short_description(self):
        clean_text = ""
        if self.description:
            clean_text = ''.join(
                BeautifulSoup(self.description,
                              "html.parser").stripped_strings)
        return clean_text

    @property
    def api_url(self):
        return '/institutions/{}'.format(self.id)

    @property
    def description_html(self):
        return format_html(self.description)

    @property
    def datasets_count(self):
        return self.datasets.count()

    @classmethod
    def accusative_case(cls):
        return _("acc: Institution")

    @property
    def published_datasets(self):
        return self.datasets.filter(status='published')

    @property
    def address_display(self):
        city = ' '.join(i.strip() for i in [self.postal_code, self.city] if i)
        if not city:
            return None
        number = '/'.join(i.strip()
                          for i in [self.street_number, self.flat_number] if i)
        addres_line = city
        if self.street:
            street = ' '.join(i.strip()
                              for i in [self.street_type, self.street, number]
                              if i)
            addres_line = ', '.join(i for i in [addres_line, street] if i)

        return addres_line

    @property
    def phone_display(self):
        if not self.tel:
            return None
        try:
            p = phonenumbers.parse(self.tel, 'PL')
            phone = phonenumbers.format_number(
                p, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
        except phonenumbers.phonenumberutil.NumberParseException:
            return None
        return _(' int. ').join(i.strip() for i in [phone, self.tel_internal]
                                if i)

    @property
    def fax_display(self):
        if not self.fax:
            return None
        try:
            p = phonenumbers.parse(self.fax, 'PL')
            fax = phonenumbers.format_number(
                p, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
        except phonenumbers.phonenumberutil.NumberParseException:
            return None
        return _(' int. ').join(i.strip() for i in [fax, self.fax_internal]
                                if i)

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    tracker = FieldTracker()
    slugify_field = 'title'

    short_description.fget.short_description = _("Description")

    class Meta:
        db_table = "organization"
        verbose_name = _("Institution")
        verbose_name_plural = _("Institutions")
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=["i18n"]),
        ]
コード例 #17
0
ファイル: models.py プロジェクト: horosin/mcod-backend
class Resource(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (
            revalidate_resource,
            search_signals.update_document_with_related,
            core_signals.notify_updated
        ),
        'published': (
            revalidate_resource,
            search_signals.update_document_with_related,
            core_signals.notify_published
        ),
        'restored': (
            revalidate_resource,
            search_signals.update_document_with_related,
            core_signals.notify_restored
        ),
    }
    file = models.FileField(verbose_name=_("File"), storage=storages.get_storage('resources'),
                            upload_to='%Y%m%d',
                            max_length=2000, blank=True, null=True)
    packed_file = models.FileField(verbose_name=_("Packed file"), storage=storages.get_storage('resources'),
                                   upload_to='%Y%m%d',
                                   max_length=2000, blank=True, null=True)
    file_info = models.TextField(blank=True, null=True, editable=False, verbose_name=_("File info"))
    file_encoding = models.CharField(max_length=150, null=True, blank=True, editable=False,
                                     verbose_name=_("File encoding"))
    link = models.URLField(verbose_name=_('Resource Link'), max_length=2000, blank=True, null=True)
    title = models.CharField(max_length=500, verbose_name=_("title"))
    description = models.TextField(blank=True, null=True, verbose_name=_("Description"))
    position = models.IntegerField(default=1, verbose_name=_("Position"))
    dataset = models.ForeignKey('datasets.Dataset', on_delete=models.CASCADE, related_name='resources',
                                verbose_name=_('Dataset'))

    format = models.CharField(max_length=150, blank=True, null=True, verbose_name=_("Format"),
                              choices=supported_formats_choices())
    type = models.CharField(max_length=10, choices=RESOURCE_TYPE, default='file', editable=False,
                            verbose_name=_("Type"))

    openness_score = models.IntegerField(default=0, verbose_name=_("Openness score"),
                                         validators=[MinValueValidator(0), MaxValueValidator(5)])

    created_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Created by"),
        related_name='resources_created'
    )
    modified_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Modified by"),
        related_name='resources_modified'
    )
    link_tasks = models.ManyToManyField('TaskResult', verbose_name=_('Download Tasks'),
                                        blank=True,
                                        related_name='link_task_resources',
                                        )
    file_tasks = models.ManyToManyField('TaskResult', verbose_name=_('Download Tasks'),
                                        blank=True,
                                        related_name='file_task_resources')
    data_tasks = models.ManyToManyField('TaskResult', verbose_name=_('Download Tasks'),
                                        blank=True,
                                        related_name='data_task_resources')

    old_file = models.FileField(verbose_name=_("File"), storage=storages.get_storage('resources'), upload_to='',
                                max_length=2000, blank=True, null=True)
    old_resource_type = models.TextField(verbose_name=_("Data type"), null=True)
    old_format = models.CharField(max_length=150, blank=True, null=True, verbose_name=_("Format"))
    old_customfields = JSONField(blank=True, null=True, verbose_name=_("Customfields"))
    old_link = models.URLField(verbose_name=_('Resource Link'), max_length=2000, blank=True, null=True)
    downloads_count = models.PositiveIntegerField(default=0)

    show_tabular_view = models.BooleanField(verbose_name=_('Tabular view'), default=True)
    tabular_data_schema = JSONField(null=True, blank=True)
    data_date = models.DateField(null=True, verbose_name=_("Data date"))

    verified = models.DateTimeField(blank=True, default=now, verbose_name=_("Update date"))

    def __str__(self):
        return self.title

    @property
    def media_type(self):
        return self.type or ''

    @property
    def category(self):
        return self.dataset.category if self.dataset else ''

    @property
    def link_is_valid(self):
        task = self.link_tasks.last()
        return task.status if task else 'NOT_AVAILABLE'

    @property
    def file_is_valid(self):
        task = self.file_tasks.last()
        return task.status if task else 'NOT_AVAILABLE'

    @property
    def data_is_valid(self):
        task = self.data_tasks.last()
        return task.status if task else 'NOT_AVAILABLE'

    @property
    def file_url(self):
        if self.file:
            _file_url = self.file.url if not self.packed_file else self.packed_file.url
            return '%s%s' % (settings.API_URL, _file_url)
        return ''

    @property
    def file_size(self):
        return self.file.size if self.file else None

    @property
    def download_url(self):
        if self.file:
            return '{}/resources/{}/file'.format(settings.API_URL, self.ident)
        return ''

    @property
    def is_indexable(self):
        if self.type == 'file' and not self.file_is_valid:
            return False

        if self.type in ('api', 'website') and not self.link_is_valid:
            return False

        return True

    @property
    def tabular_data(self):
        if not self._tabular_data:
            if self.format in ('csv', 'tsv', 'xls', 'xlsx', 'ods') and self.file:
                self._tabular_data = TabularData(self)
        return self._tabular_data

    def index_tabular_data(self, force=False):
        self.tabular_data.validate()
        return self.tabular_data.index(force=force)

    def save_file(self, content, filename):
        dt = self.created.date() if self.created else now().date()
        subdir = dt.isoformat().replace("-", "")
        dest_dir = os.path.join(self.file.storage.location, subdir)
        os.makedirs(dest_dir, exist_ok=True)
        file_path = os.path.join(dest_dir, filename)
        with open(file_path, 'wb') as f:
            f.write(content.read())
        return '%s/%s' % (subdir, filename)

    def revalidate(self, **kwargs):
        if not self.link or self.link.startswith(settings.BASE_URL):
            process_resource_file_task.s(self.id, **kwargs).apply_async(countdown=2)
        else:
            process_resource_from_url_task.s(self.id, **kwargs).apply_async(countdown=2)

    @classmethod
    def accusative_case(cls):
        return _("acc: Resource")

    @property
    def _openness_score(self):
        if not self.format:
            return 0
        _, content = content_type_from_file_format(self.format.lower())
        return OPENNESS_SCORE.get(content, 0)

    @property
    def file_size_human_readable(self):
        file_size = self.file_size or 0
        return sizeof_fmt(file_size)

    @property
    def title_truncated(self):
        title = (self.title[:100] + '..') if len(self.title) > 100 else self.title
        return title

    _tabular_data = None

    i18n = TranslationField(fields=("title", "description"))
    tracker = FieldTracker()
    slugify_field = 'title'

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    class Meta:
        verbose_name = _("Resource")
        verbose_name_plural = _("Resources")
        db_table = 'resource'
        default_manager_name = "objects"
        indexes = [GinIndex(fields=["i18n"]), ]
コード例 #18
0
class BaseWallet(TimeStampedModel, SoftDeletableModel):

    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             related_name='%(class)s_wallets',
                             on_delete=models.CASCADE)

    private = models.CharField(max_length=150, unique=True)
    public = models.CharField(max_length=150, unique=True)
    address = models.CharField(max_length=150, unique=True)
    wif = models.CharField(max_length=150, unique=True)

    invoices = GenericRelation(
        'wallets.Invoice',
        content_type_field='wallet_type',
        object_id_field='wallet_id',
    )

    payments = GenericRelation(
        'wallets.Payment',
        content_type_field='wallet_type',
        object_id_field='wallet_id',
    )

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        abstract = True
        ordering = ['id']

    def __str__(self):
        return '({}) {}'.format(self.coin_symbol.upper(), self.address)

    def get_absolute_url(self):
        return reverse('wallets:detail',
                       kwargs={
                           'wallet': self.coin_symbol,
                           'address': self.address
                       })

    @cached_property
    def coin_symbol(self):
        coin_symbol = self.__class__.get_coin_symbol()
        return coin_symbol

    @cached_property
    def coin_name(self):
        coin_name = self.__class__.get_coin_name()
        return coin_name

    def spend(self, addresses: List[str], amounts: List[int]) -> str:
        assert len(addresses) == len(amounts), (
            'The number of addresses and amounts should be the same')
        new_transaction = api.not_simple_spend(from_privkey=self.private,
                                               to_addresses=addresses,
                                               to_satoshis=amounts,
                                               coin_symbol=self.coin_symbol,
                                               api_key=get_api_key())
        return new_transaction

    def spend_with_webhook(self,
                           addresses: List[str],
                           amounts: List[int],
                           invoice: object = None,
                           obj: object = None,
                           event: str = 'tx-confirmation') -> str:
        assert len(addresses) == len(amounts), (
            'The number of addresses and amounts should be the same')

        new_transaction = api.not_simple_spend(from_privkey=self.private,
                                               to_addresses=addresses,
                                               to_satoshis=amounts,
                                               coin_symbol=self.coin_symbol,
                                               api_key=get_api_key())
        self.set_webhook(to_addresses=addresses,
                         transaction=new_transaction,
                         obj=obj,
                         invoice=invoice,
                         event=event)
        return new_transaction

    def set_webhook(self,
                    to_addresses: List[str],
                    transaction: str,
                    obj: object = None,
                    invoice: object = None,
                    event: str = 'tx-confirmation') -> str:
        domain = settings.DOMAIN_NAME
        if obj:
            try:
                obj = signing.dumps({
                    'app_label': obj._meta.app_label,
                    'model': obj._meta.model_name,
                    'id': obj.id
                })
            except Exception:
                obj = None

        signature = signing.dumps({
            'from_address': self.address,
            'to_addresses': to_addresses,
            'symbol': self.coin_symbol,
            'event': event,
            'transaction_id': transaction,
            'invoice_id': invoice.id if invoice else None,
            'content_object': obj
        })
        callback_url = 'https://{}/wallets/webhook/{}/'.format(
            domain, signature)
        webhook = blockcypher.subscribe_to_address_webhook(
            callback_url=callback_url,
            subscription_address=self.address,
            event=event,
            coin_symbol=self.coin_symbol,
            api_key=get_api_key()  # settings.BLOCKCYPHER_API_KEY
        )
        return webhook

    @ecached_property('address_details:{self.id}', 60)
    def address_details(self):
        details = blockcypher.get_address_details(self.address,
                                                  coin_symbol=self.coin_symbol)
        return details

    @ecached_property('overview:{self.id}', 60)
    def overview(self):
        overview = blockcypher.get_address_overview(
            self.address, coin_symbol=self.coin_symbol)
        return overview

    @ecached_property('balance:{self.id}', 60)
    def balance(self):
        overview = blockcypher.get_address_overview(
            self.address, coin_symbol=self.coin_symbol)
        return overview['balance']

    @ecached_property('natural_balance:{self.id}', 60)
    def normal_balance(self):
        return from_satoshi(self.balance)

    @ecached_property('usd_balance:{self.id}', 60)
    def usd_balance(self):
        return round((self.normal_balance * self.__class__.get_rate()), 2)

    @ecached_property('transactions:{self.id}', 60)
    def transactions(self):
        get_address_full = self.address_details
        return get_address_full['txrefs']

    @staticmethod
    def transaction_details(tx_ref: str, coin_symbol='btc') -> dict:
        details = blockcypher.get_transaction_details(tx_ref, coin_symbol)
        return details

    def create_invoice(self, content_object: object, data: list) -> object:
        key_list = ['wallet', 'amount', 'content_object', 'purpose']

        invoice = Invoice.objects.create(wallet=self,
                                         content_object=content_object)
        assign_perm('pay_invoice', self.user, invoice)
        assign_perm('view_invoice', self.user, invoice)

        for item in data:
            if all(key in item for key in key_list):
                payment = Payment(invoice=invoice,
                                  amount=item['amount'],
                                  wallet=item['wallet'],
                                  content_object=item['content_object'],
                                  purpose=item['purpose'])
                payment.save()
                assign_perm('view_payment', self.user, payment)
                assign_perm('view_payment', item['wallet'].user, payment)
        return invoice

    @classmethod
    def _get_coin_symbol_and_name(cls):
        if cls.__name__.lower().startswith('btc'):
            coin_symbol = 'btc'
            coin_name = 'bitcoin'
        elif cls.__name__.lower().startswith('ltc'):
            coin_symbol = 'ltc'
            coin_name = 'litecoin'
        elif cls.__name__.lower().startswith('dash'):
            coin_symbol = 'dash'
            coin_name = 'dash'
        elif cls.__name__.lower().startswith('doge'):
            coin_symbol = 'doge'
            coin_name = 'dogecoin'
        elif cls.__name__.lower().startswith('bcy'):
            coin_symbol = 'bcy'
            coin_name = 'blockcypher'
        return {'coin_symbol': coin_symbol, 'coin_name': coin_name}

    @classmethod
    def get_coin_symbol(cls):
        return cls._get_coin_symbol_and_name()['coin_symbol']

    @classmethod
    def get_coin_name(cls):
        return cls._get_coin_symbol_and_name()['coin_name']

    @classmethod
    def get_rate(cls):
        coin_name = cls.get_coin_name()
        if coin_name == 'blockcypher':
            return 150  # for tests and debug
        try:
            response = requests.get(
                'https://api.coinmarketcap.com/v1/ticker/{}/'.format(
                    coin_name))
            json_response = response.json()
            return float(json_response[0]['price_usd'])
        except Exception:
            return 0
コード例 #19
0
ファイル: models.py プロジェクト: horosin/mcod-backend
class Application(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (generate_thumbnail, core_signals.notify_updated),
        'published': (generate_thumbnail, core_signals.notify_published),
        'restored': (generate_thumbnail, core_signals.notify_restored),
        'removed': (search_signals.remove_document, core_signals.notify_removed),
        'm2m_added': (search_signals.update_document, core_signals.notify_m2m_added,),
        'm2m_removed': (search_signals.update_document, core_signals.notify_m2m_removed,),
        'm2m_cleaned': (search_signals.update_document, core_signals.notify_m2m_cleaned,),
    }
    title = models.CharField(max_length=300, verbose_name=_("Title"))
    notes = models.TextField(verbose_name=_("Notes"), null=True)
    author = models.CharField(max_length=50, blank=True, null=True, verbose_name=_("Author"))
    url = models.URLField(max_length=300, verbose_name=_("App URL"), null=True)
    image = models.ImageField(
        max_length=200, storage=storages.get_storage('applications'),
        upload_to='%Y%m%d', blank=True, null=True, verbose_name=_("Image URL")
    )
    image_thumb = models.ImageField(
        storage=storages.get_storage('applications'),
        upload_to='%Y%m%d', blank=True, null=True
    )

    datasets = models.ManyToManyField('datasets.Dataset',
                                      db_table='application_dataset',
                                      verbose_name=_('Datasets'),
                                      related_name='applications',
                                      related_query_name="application")
    tags = models.ManyToManyField('tags.Tag',
                                  blank=True,
                                  db_table='application_tag',
                                  verbose_name=_('Tag'),
                                  related_name='applications',
                                  related_query_name="application")

    created_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Created by"),
        related_name='applications_created'
    )

    modified_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Modified by"),
        related_name='applications_modified'
    )

    @cached_property
    def image_url(self):
        try:
            return self.image.url
        except ValueError:
            return ''

    @cached_property
    def image_thumb_url(self):
        try:
            return self.image_thumb.url
        except ValueError:
            return ''

    @cached_property
    def tags_list(self):
        return [tag.name_translated for tag in self.tags.all()]

    @cached_property
    def users_following_list(self):
        return [user.id for user in self.users_following.all()]

    def __str__(self):
        return self.title

    @classmethod
    def accusative_case(cls):
        return _("acc: Application")

    def published_datasets(self):
        return self.datasets.filter(status='published')

    i18n = TranslationField(fields=("title", "notes"))
    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()
    tracker = FieldTracker()
    slugify_field = 'title'

    class Meta:
        verbose_name = _("Application")
        verbose_name_plural = _("Applications")
        db_table = "application"
        default_manager_name = "objects"
        indexes = [GinIndex(fields=["i18n"]), ]
コード例 #20
0
ファイル: models.py プロジェクト: horosin/mcod-backend
class Category(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (update_related_datasets, ),
        'published': (update_related_datasets, ),
        'restored': (update_related_datasets, ),
        'removed': (null_in_related_datasets, ),
    }
    title = models.CharField(max_length=100, verbose_name=_("Title"))
    description = models.TextField(null=True, verbose_name=_("Description"))
    color = models.CharField(max_length=20,
                             default="#000000",
                             null=True,
                             verbose_name=_("Color"))
    image = models.ImageField(max_length=200,
                              storage=storages.get_storage('common'),
                              upload_to='',
                              blank=True,
                              null=True,
                              verbose_name=_("Image URL"))
    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='categories_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='categories_modified')

    @classmethod
    def accusative_case(cls):
        return _("acc: Category")

    def __str__(self):
        return self.title_i18n

    @property
    def image_url(self):
        if not self.image or not self.image.url:
            return None
        return '{}{}'.format(settings.BASE_URL, self.image.url)

    i18n = TranslationField(fields=("title", "description"))

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    tracker = FieldTracker()
    slugify_field = 'title'

    class Meta:
        db_table = "category"
        verbose_name = _("Category")
        verbose_name_plural = _("Categories")
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=["i18n"]),
        ]
コード例 #21
0
ファイル: models.py プロジェクト: horosin/mcod-backend
class Tag(ExtendedModel):
    SIGNALS_MAP = {
        'updated': (update_related_datasets,
                    update_related_articles,
                    update_related_applications
                    ),
        'published': (update_related_datasets,
                      update_related_articles,
                      update_related_applications
                      ),
        'restored': (update_related_datasets,
                     update_related_articles,
                     update_related_applications
                     ),
        'removed': (update_related_datasets,
                    update_related_articles,
                    update_related_applications
                    ),
    }

    name = models.CharField(unique=True, max_length=100, verbose_name=_("name"))

    created_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Created by"),
        related_name='tags_created'
    )
    modified_by = models.ForeignKey(
        User,
        models.DO_NOTHING,
        blank=False,
        editable=False,
        null=True,
        verbose_name=_("Modified by"),
        related_name='tags_modified'
    )

    def __str__(self):
        return self.name

    @classmethod
    def accusative_case(cls):
        return _("acc: Tag")

    i18n = TranslationField(fields=("name",), required_languages=("pl",))
    tracker = FieldTracker()
    slugify_field = 'name'

    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()

    class Meta:
        verbose_name = _("Tag")
        verbose_name_plural = _("Tags")
        db_table = 'tag'
        default_manager_name = "objects"
        indexes = [GinIndex(fields=["i18n"]), ]
コード例 #22
0
class Invoice(TimeStampedModel, SoftDeletableModel):

    limit = models.Q(app_label='wallets', model='btc') | \
        models.Q(app_label='wallets', model='ltc') | \
        models.Q(app_label='wallets', model='dash') | \
        models.Q(app_label='wallets', model='doge') | \
        models.Q(app_label='wallets', model='bcy')

    wallet_type = models.ForeignKey(ContentType,
                                    on_delete=models.CASCADE,
                                    limit_choices_to=limit,
                                    related_name='invoices')
    wallet_id = models.PositiveIntegerField()
    wallet = GenericForeignKey('wallet_type', 'wallet_id')

    content_type = models.ForeignKey(ContentType,
                                     on_delete=models.CASCADE,
                                     null=True,
                                     blank=True)
    object_id = models.PositiveIntegerField(null=True, blank=True)
    content_object = GenericForeignKey('content_type', 'object_id')

    tx_ref = models.CharField(max_length=100, null=True, blank=True)
    is_paid = models.BooleanField(default=False)
    expires = models.DateTimeField(default=get_expires_date)

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        ordering = ['id']
        permissions = (
            ('view_invoice', _('Can view invoice')),
            ('pay_invoice', _('Can pay invoice')),
        )

    def __init__(self, *args, **kwargs):
        super(Invoice, self).__init__(*args, **kwargs)
        self.__tracked_fields = ['is_paid']
        self.set_original_values()

    def save(self, *args, **kwargs):
        self.full_clean()
        if self.has_changed():
            if not self.can_be_paid():
                self.reset_original_values()
        self.set_original_values()
        return super(Invoice, self).save(*args, **kwargs)

    def set_original_values(self):
        for field in self.__tracked_fields:
            if getattr(self, field) is 'True':
                setattr(self, '__original_%s' % field, True)
            elif getattr(self, field) is 'False':
                setattr(self, '__original_%s' % field, False)
            else:
                setattr(self, '__original_%s' % field, getattr(self, field))
        return self.__dict__

    def has_changed(self):
        for field in self.__tracked_fields:
            original = '__original_%s' % field
            return getattr(self, original) != getattr(self, field)

    def reset_original_values(self):
        values = {}
        for field in self.__tracked_fields:
            original = '__original_%s' % field
            setattr(self, field, getattr(self, original))
            values[field] = getattr(self, field)
        return values

    @property
    def amount(self):
        return sum([payment.amount for payment in self.payments.all()])

    @property
    def normal_amount(self):
        return format(from_satoshi(self.amount), '.8f')

    @property
    def usd_amount(self):
        return round((self.normal_amount * self.wallet.get_rate()), 2)

    def pay(self):
        if self.wallet.user.has_perm('pay_invoice', self) \
           and not self.is_expired:
            payments = self.payments.all()
            data = [{
                'address': payment.wallet.address,
                'amount': payment.amount
            } for payment in payments]
            tx_ref = self.wallet.spend(
                addresses=[payment['address'] for payment in data],
                amounts=[payment['amount'] for payment in data],
                #invoice=self,
                #obj=self.content_object
            )
            self.tx_ref = tx_ref
            self.save()
            return tx_ref
        return None

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

    @property
    def is_expired(self):
        return timezone.now() > self.expires

    def can_be_paid(self):
        if self.is_expired:
            return False

        details = self.wallet.transaction_details(self.tx_ref,
                                                  self.wallet.coin_symbol)
        if self.amount < details['outputs'][0]['value']:
            logger.error(
                'Invoice can be confirmed, because the amount of all ' +
                'transactions is less than the amount of the invoice.')
            return False

        return True

    @ecached_property('normal_amount:{self.id}', 60 * 5)
    def normal_amount(self):
        return from_satoshi(self.amount)
コード例 #23
0
class Payment(TimeStampedModel, SoftDeletableModel):

    limit = models.Q(app_label='wallets', model='btc') | \
        models.Q(app_label='wallets', model='ltc') | \
        models.Q(app_label='wallets', model='dash') | \
        models.Q(app_label='wallets', model='doge') | \
        models.Q(app_label='wallets', model='bcy')

    invoice = models.ForeignKey(Invoice,
                                on_delete=models.CASCADE,
                                related_name='payments',
                                null=False,
                                blank=True)

    amount = models.BigIntegerField(validators=[MinValueValidator(0)])

    wallet_type = models.ForeignKey(ContentType,
                                    on_delete=models.CASCADE,
                                    limit_choices_to=limit,
                                    related_name='payments')
    wallet_id = models.PositiveIntegerField()
    wallet = GenericForeignKey('wallet_type', 'wallet_id')

    content_type = models.ForeignKey(ContentType,
                                     on_delete=models.CASCADE,
                                     null=True,
                                     blank=True)
    object_id = models.PositiveIntegerField(null=True, blank=True)
    content_object = GenericForeignKey('content_type', 'object_id')

    purpose = models.CharField(max_length=255)

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        ordering = ['id']
        permissions = (('view_payment', _('Can view payment')), )

    @property
    def normal_amount(self):
        return format(from_satoshi(self.amount), '.8f')

    @property
    def usd_amount(self):
        return round((float(self.normal_amount) * self.wallet.get_rate()), 2)

    @property
    def text(self):
        return 'User {user} paid {amount} ($ {usd_amount}) \
                {symbol} for {purpose}'.format(
            user=self.invoice.wallet.user,
            amount=self.amount,
            usd_amount=self.usd_amount,
            symbol=self.invoice.wallet.coin_symbol.upper(),
            purpose=self.purpose,
            #obj=self.content_object.__str__()
        )

    @property
    def html(self):
        try:
            html = format_html(
                'User <a href="{}">{}</a> paid {} {} for' +
                ' {} <a href="{}">({})</a>',
                self.invoice.wallet.user.get_absolute_url(),
                self.invoice.wallet.user, self.amount,
                self.invoice.wallet.coin_symbol.upper(), self.purpose,
                self.content_object.get_absolute_url(),
                self.content_object.__str__())
            return html
        except:
            return ''
コード例 #24
0
ファイル: models.py プロジェクト: mugadza/grecerola
class Wallet(TimeStampedModel, SoftDeletableModel):
    bank = models.OneToOneField('wallet.Bank',
                                related_name='wallet',
                                unique=True,
                                on_delete=models.PROTECT)

    objects = SoftDeletableManager()
    removed = QueryManager(is_removed=True)

    class Meta:
        ordering = ['bank']
        permissions = (('can_view_wallet_report', 'Can view wallet report'), )

    @staticmethod
    def validate_amount(amount):
        if not isinstance(amount, (int, Decimal, str)):
            raise ValueError('Amount need to be a string, integer or Decimal.')
        return Decimal(amount)

    def register_income(self, amount, reference):
        amount = self.validate_amount(amount)
        if amount <= Decimal('0'):
            raise ValueError('Amount need to be positive number, not %s' %
                             amount)

        return self._create_transaction(value, reference)

    def _create_transaction(self, amount, reference):
        return Transaction.objects.create(wallet=self,
                                          reference=reference,
                                          amount=amount)

    def register_expense(self, amount, reference, current_lock=None):
        amount = self.validate_amount(amount)
        if amount >= Decimal('0'):
            raise ValueError('Amount need to be negative number, not %s' %
                             amount)

        if current_lock is not None:
            if current_lock.wallet != self:
                raise ValueError('Lock not for this wallet!')

            if self.balance >= amount:
                return self._create_transaction(amount, reference)
            else:
                raise WalletHasInsufficientFunds(
                    'Not insufficient funds to spend %s' % amount)

        with Locked(self):
            if self.balance >= amount:
                return self._create_transaction(amount, reference)
            else:
                raise WalletHasInsufficientFunds(
                    'Not insufficient funds to spend %s' % amount)

    @property
    def balance(self):
        return self.transactions.aggregate(
            Sum('transaction_amount'))['transaction_amount__sum']

    def __str__(self):
        return '({})'.format(self.bank)
コード例 #25
0
class BaseModel(SoftDeletableModel):
    user = models.ForeignKey(
        User,
        verbose_name="User",
        on_delete=models.CASCADE,
        unique=False
    )

    uuid = UUIDField(
        default=uuid.uuid4,
        editable=False,
        unique=True
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Created at"
    )

    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Updated at"
    )

    deleted_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Deleted at"
    )

    created_by = models.ForeignKey(
        User,
        null=True,
        verbose_name="Created by",
        related_name='%(class)s_created_by',
        on_delete=models.CASCADE
    )

    updated_by = models.ForeignKey(
        User,
        null=True,
        verbose_name="Updated by",
        related_name='%(class)s_updated_by',
        on_delete=models.CASCADE
    )

    deleted_by = models.ForeignKey(
        User,
        null=True,
        blank=True,
        verbose_name="Deleted by",
        related_name='%(class)s_deleted_by',
        on_delete=models.CASCADE
    )

    objects = SoftDeletableManager()

    def __str__(self):
        if hasattr(self, 'name'):
            return "%s" % self.name
        if hasattr(self, 'description'):
            return "%s" % self.description
        if self._meta.verbose_name:
            return "%s" % self._meta.verbose_name

        return self.pk

    @classmethod
    def list(cls, *args, **kwargs):
        return cls.objects.filter(*args, **kwargs)

    @classmethod
    def count(cls, *args, **kwargs):
        return cls.list(*args, **kwargs).count()

    @classmethod
    def create(cls, **kwargs):
        cls.objects.create(**kwargs)

    @classmethod
    def get(cls, *args, **kwargs):
        return cls.list(*args, **kwargs).first()

    @classmethod
    def choices(cls):
        choices = ()

        for model in cls.objects.all():
            choice = (model.pk, model.name if hasattr(model, 'name') else model.pk)
            choices += choice

        return choices

    @classmethod
    def retrieve(cls, **kwargs):
        return cls.list(**kwargs).first()

    class Meta:
        abstract = True
コード例 #26
0
class Dataset(ExtendedModel):
    SIGNALS_MAP = {
        'removed':
        (remove_related_resources, search_signals.remove_document_with_related,
         core_signals.notify_removed),
    }
    title = models.CharField(max_length=300,
                             null=True,
                             verbose_name=_("Title"))
    version = models.CharField(max_length=100,
                               blank=True,
                               null=True,
                               verbose_name=_("Version"))
    url = models.CharField(max_length=1000,
                           blank=True,
                           null=True,
                           verbose_name=_("Url"))
    notes = models.TextField(verbose_name=_("Notes"), null=True, blank=False)

    license_old_id = models.CharField(max_length=20,
                                      blank=True,
                                      null=True,
                                      verbose_name=_("License ID"))
    license = models.ForeignKey('licenses.License',
                                on_delete=models.DO_NOTHING,
                                blank=True,
                                null=True,
                                verbose_name=_("License ID"))

    license_condition_db_or_copyrighted = models.CharField(max_length=300,
                                                           blank=True,
                                                           null=True)
    license_condition_modification = models.NullBooleanField(null=True,
                                                             blank=True,
                                                             default=None)
    license_condition_original = models.NullBooleanField(null=True,
                                                         blank=True,
                                                         default=None)
    license_condition_responsibilities = models.TextField(blank=True,
                                                          null=True)
    license_condition_source = models.NullBooleanField(null=True,
                                                       blank=True,
                                                       default=None)
    license_condition_timestamp = models.NullBooleanField(null=True,
                                                          blank=True)
    organization = models.ForeignKey('organizations.Organization',
                                     on_delete=models.CASCADE,
                                     related_name='datasets',
                                     verbose_name=_('Institution'))
    customfields = JSONField(blank=True,
                             null=True,
                             verbose_name=_("Customfields"))
    update_frequency = models.CharField(max_length=50,
                                        blank=True,
                                        null=True,
                                        verbose_name=_("Update frequency"))
    category = models.ForeignKey('categories.Category',
                                 on_delete=models.SET_NULL,
                                 blank=True,
                                 null=True,
                                 verbose_name=_('Category'))
    tags = models.ManyToManyField('tags.Tag',
                                  db_table='dataset_tag',
                                  blank=False,
                                  verbose_name=_("Tag"),
                                  related_name='datasets',
                                  related_query_name="dataset")

    created_by = models.ForeignKey(User,
                                   models.DO_NOTHING,
                                   blank=False,
                                   editable=False,
                                   null=True,
                                   verbose_name=_("Created by"),
                                   related_name='datasets_created')
    modified_by = models.ForeignKey(User,
                                    models.DO_NOTHING,
                                    blank=False,
                                    editable=False,
                                    null=True,
                                    verbose_name=_("Modified by"),
                                    related_name='datasets_modified')

    verified = models.DateTimeField(blank=True,
                                    default=now,
                                    verbose_name=_("Update date"))

    def __str__(self):
        return self.title

    @property
    def institution(self):
        return self.organization

    @property
    def downloads_count(self):
        return sum(res.downloads_count for res in self.resources.all())

    @property
    def formats(self):
        return list(
            set(res.format for res in self.resources.all()
                if res.format is not None))

    @property
    def openness_scores(self):
        return list(set(res.openness_score for res in self.resources.all()))

    @property
    def tags_list(self):
        return [tag.name_translated for tag in self.tags.all()]

    @property
    def license_name(self):
        return self.license.name if self.license and self.license.name else ''

    @property
    def license_description(self):
        return self.license.title if self.license and self.license.title else ''

    @property
    def last_modified_resource(self):
        return self.resources.all().aggregate(Max('modified'))['modified__max']

    last_modified_resource.fget.short_description = _("modified")

    @property
    def is_license_set(self):
        return any([
            self.license, self.license_condition_db_or_copyrighted,
            self.license_condition_modification,
            self.license_condition_original,
            self.license_condition_responsibilities
        ])

    @property
    def followers_count(self):
        return self.users_following.count()

    @classmethod
    def accusative_case(cls):
        return _("acc: Dataset")

    i18n = TranslationField(fields=("title", "notes"))
    raw = models.Manager()
    objects = SoftDeletableManager()
    deleted = DeletedManager()
    tracker = FieldTracker()
    slugify_field = 'title'
    last_modified_resource.fget.short_description = _("modified")

    class Meta:
        verbose_name = _("Dataset")
        verbose_name_plural = _("Datasets")
        db_table = 'dataset'
        default_manager_name = "objects"
        indexes = [
            GinIndex(fields=["i18n"]),
        ]
コード例 #27
0
ファイル: models.py プロジェクト: MusaZhou/muslim_app
class MobileApp(SoftDeletableModel, OrderedModel, CommonActionModel):
    name = models.CharField(max_length=100,unique=True,
                            db_index=True, verbose_name=_('App Name'))
    description = models.TextField(blank=True, null=True, verbose_name=_('Description'))
    upload_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
                                  verbose_name=_('Uploader'))
    upload_date = models.DateTimeField(auto_now_add=True, verbose_name=_('Upload Time'), db_index=True)
    category = models.ForeignKey(AppCategory, on_delete=models.CASCADE)
    comment_count = models.PositiveIntegerField(null=True, verbose_name=_('Comment Count'), default=0)
    download_count = models.PositiveIntegerField(null=True, verbose_name=_('Download Count'), default=0)
    images = GenericRelation(Image, related_query_name='imaged_app', verbose_name=_('Screenshots'))
    is_active = models.BooleanField(default=False, verbose_name=_('Active Status'))
    icon = models.ImageField(upload_to="icons")
    developer = models.CharField(max_length=100, blank=True, null=True, verbose_name=_("Developer"))
    videos = GenericRelation(Video, related_query_name='video_app', verbose_name=_('Video Show'))
    
    order_with_respect_to = 'category'
    
    objects = models.Manager()
    exist_objects = SoftDeletableManager()
    active_apps = ActiveAppManager()
    shown_apps = ShownAppManager()
    upload_order = UploadOrderManager()
    
    class Meta(OrderedModel.Meta):
        permissions = (("can_approve_app", "Can approve newly uploaded app"),)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name, allow_unicode=True)
    
        super(MobileApp, self).save(*args, **kwargs)
    
    def latest_version(self):
        if self.canShow():
            return self.versions.filter(approve_status='approved').select_related('apk')[0]
        return None
    
    def get_absolute_url(self):
        return reverse('showcase:app', args=[self.slug])
    
    def has_approved_version(self):
        if self.versions.filter(approve_status='approved').exists():
            return True
        return False
    
    def canShow(self):
        return self.is_active and self.has_approved_version()
    
    @property
    def userLink(self):
        return reverse('showcase:app', args=[self.slug])
    
    @property
    def user_link_mobile(self):
        return reverse('mobile:app', args=[self.slug])
    
    @property
    def latestAPK(self):
        latestVersion = self.latest_version()
        if latestVersion is not None:
            return latestVersion.apk.file.url
        return None
    
    def latestTime(self):
        latestVersion = self.latest_version()
        if latestVersion is not None:
            return latestVersion.created_time
        return None
    
    @property
    def avg_rate(self):
        last_rating = self.ratings.last()
        if last_rating is not None:
            return last_rating.average
        return 5.0