Beispiel #1
0
class Now(Func):
    template = 'CURRENT_TIMESTAMP'
    output_field = fields.DateTimeField()

    def as_postgresql(self, compiler, connection):
        # PostgreSQL's CURRENT_TIMESTAMP means "the time at the start of the
        # transaction". Use STATEMENT_TIMESTAMP to be cross-compatible with
        # other databases.
        return self.as_sql(compiler,
                           connection,
                           template='STATEMENT_TIMESTAMP()')
Beispiel #2
0
class RequestAssignment(SafeDeleteModel):
    """
    We will use this to constantly track the progress of an assignment.
    Mostly used for logging, and karma points ?
    """

    class Meta:
        app_label = 'crisis'
        db_table = 'crisis_requestassignment'

    _safedelete_policy = SOFT_DELETE_CASCADE

    STATUS_ASSIGNED = "A"
    STATUS_DROPPED = "D"
    STATUS_COMPLETED = "C"

    TYPE_OF_ASSIGNMENT_STATUSES = [
        (STATUS_ASSIGNED, "Assigned"),
        (STATUS_DROPPED, "Dropped"),
        (STATUS_COMPLETED, "Completed"),
    ]
    status = fields.CharField(choices=TYPE_OF_ASSIGNMENT_STATUSES,
                              max_length=2)
    request = models.ForeignKey(
        "crisis.Request", on_delete=models.CASCADE,
        related_name="related_assignment"
    )
    assignee = models.ForeignKey(
        "management.Participant",
        on_delete=models.CASCADE,
        related_name="created_assignment",
    )
    created_at = fields.DateTimeField(auto_now_add=True)
    modified_at = fields.DateTimeField(auto_now=True)
    did_complete = fields.BooleanField(default=False)

    def __str__(self):
        return (
            f"{self.id}-{self.assignee.user.first_name}-request-"
            f"{self.request.id}-status-{self.get_status_display()}"
        )
Beispiel #3
0
class Event(models.Model):

    title = fields.CharField(max_length=100, verbose_name=_('Title and venue'))
    description = fields.TextField(blank=True,
                                   verbose_name=_('Long description'))
    date = fields.DateTimeField(verbose_name=_('Date of the event'))
    tickets_info = fields.URLField(blank=True,
                                   verbose_name=_('Link to buy tickets'))

    class Meta:
        verbose_name = 'event'
        verbose_name_plural = 'events'
Beispiel #4
0
class GalleryPhoto(models.Model):

    title = fields.CharField(max_length=100,
                             blank=True,
                             null=True,
                             verbose_name=_('Gallery Photo'))
    image = models.ImageField(upload_to='gallery_photos/')
    uploaded_at = fields.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'gallery photo'
        verbose_name_plural = 'gallery photos'
class AdoptedAnimals(models.Model):
    animal_card = models.ForeignKey(AnimalCard,
                                    on_delete=models.PROTECT,
                                    verbose_name='Карта животного')
    parent_card = models.ForeignKey(ParentCard,
                                    on_delete=models.PROTECT,
                                    verbose_name='Карта родителя')
    date_adoption = f.DateTimeField(auto_now_add=True,
                                    verbose_name='Дата усыновления')

    def __str__(self):
        return self.animal_card, self.parent_card
class EpiduralInsertion(models.EpisodeSubrecord):

    insertion_date_time = fields.DateTimeField(
        null=True,
        # default=timezone.now,  (causes an Opal APIerror if uncommented)
        help_text=
        "Date and time of the epidural insertion or epidural insertion attempt",
    )

    # TODO should ideally allow SNOMED codes to be embedded in the text
    insertion_record = fields.TextField(
        null=True,
        max_length=255,
        help_text="Free text clinical record of the intervention",
    )

    # TODO should ideally be SNOMEDized
    indication = fields.CharField(
        null=True,
        max_length=255,
        help_text="Description of the intervention",
    )

    number_of_attempts = fields.PositiveIntegerField(
        default=1,
        help_text="The number of discrete epidural insertion attempts",
    )

    # TODO should ideally be SNOMEDized
    # TODO consider a default value? "no immediate complications"
    complications = fields.CharField(
        blank=True,
        null=True,
        max_length=255,
        help_text="Complications caused by the epidural insertion",
    )

    # TODO should ideally be SNOMEDized
    # TODO any other options @TimCKnowles?
    OUTCOME_CHOICES = (
        ("SUCCESS", "Successful epidural insertion and effective analgesia"),
        ("INEFFECTIVE", "Successful insertion of epidural catheter"),
        ("DURAL PUNCTURE", "Epidural insertion caused dural puncture"),
        ("FAILURE", "Failed epidural insertion"),
    )
    outcome = fields.CharField(
        choices=OUTCOME_CHOICES,
        blank=True,
        null=True,
        help_text="Outcome of the epidural insertion attempt",
        max_length=255,
    )
Beispiel #7
0
class Jog(BasePermissions, models.Model):
    owner = models.ForeignKey('User', on_delete=models.CASCADE)
    date = fields.DateTimeField(null=False, blank=False)
    distance = fields.IntegerField(null=False, blank=False)
    time = fields.DurationField(null=False, blank=False)

    @property
    def average_speed(self):
        """
        Calculates the average speed of the jog.
        :return: The average speed.
        """
        return calculate_speed(self.distance, self.time)
Beispiel #8
0
class UserProfile(models.Model):
    """Model for github user data """
    username = fields.CharField(max_length=512, unique=True)
    image_url = fields.URLField(null=True, blank=True)
    name = fields.CharField(null=True, max_length=127)
    company = fields.CharField(null=True, max_length=127)
    email = fields.CharField(null=True, max_length=127)
    adding_date = fields.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = "GitHub User"

    def __unicode__(self):
        return "{}".format(self.username)
class FileContent(models.Model):
    id = fields.AutoField(primary_key=True)

    create_time = fields.DateTimeField(default=timezone.now)
    file = models.ForeignKey(SomeFile,
                             on_delete=models.CASCADE,
                             blank=True,
                             null=True)

    content = fields.TextField(blank=True, default="")

    def append_string(self, string: str):
        self.content += ('\n' + string.strip())
        self.save()
Beispiel #10
0
class Transaction(models.Model):
    EXPENSE = 'exp'
    INCOME = 'inc'
    CATEGORY_CHOICES = (
        (EXPENSE, 'expense'),
        (INCOME, 'income'),
    )

    title = fields.CharField(max_length=255)
    amount = fields.DecimalField(max_digits=10, decimal_places=2)
    category = fields.CharField(max_length=3, choices=CATEGORY_CHOICES)
    created = fields.DateTimeField(default=timezone.now, editable=False)
    modified = fields.DateTimeField(default=timezone.now)
    active = fields.BooleanField(default=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return "{}".format(self.title)

    def deactivate(self):
        if self.active:
            self.active = False
            self.save()
Beispiel #11
0
class EpiduralRequest(models.EpisodeSubrecord):
    _is_singleton = True

    # this may change if we decide to handle the State of EpiduralRequest differently
    # in the Ruby version this was an Enum
    # Could this be handled as a SNOMED-CT lookuplist?
    epidural_status = fields.PositiveIntegerField(
        null=True,
        help_text="Internal field for managing the state of the epidural request - ordered, in progress, completed, attempted-failed, etc)",
    )

    request_date_time = fields.DateTimeField(
        null=True,
        # default=timezone.now, (causes an Opal APIerror if uncommented)
        help_text="Date and time of the epidural request",)
class Note(models.Model):
    text = f.TextField()
    time_added = f.DateTimeField(auto_now_add=True)
    is_private = f.BooleanField()
    user = models.ForeignKey(auth.models.User, on_delete=models.CASCADE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.id = None

    def __str__(self):
        return self.text

    def get_absolute_url(self):
        return reverse('note-show', kwargs=dict(note_id=self.id))
Beispiel #13
0
class People(models.Model):
    GENDER_MALE = 'Male'
    GENDER_FEMALE = 'Female'
    GENDER_UNDISCLOSED = 'Undisclosed'

    GENDER_CHOICES = (
        (GENDER_MALE, GENDER_MALE),
        (GENDER_FEMALE, GENDER_FEMALE),
        (GENDER_UNDISCLOSED, GENDER_UNDISCLOSED),
    )

    birth_year = fields.CharField(max_length=10)
    eye_color = fields.CharField(max_length=10)
    gender = fields.CharField(choices=GENDER_CHOICES,
                              default=GENDER_UNDISCLOSED,
                              max_length=15)
    height = fields.IntegerField()
    mass = fields.IntegerField()
    name = fields.CharField(max_length=20, db_index=True)
    created = fields.DateTimeField(auto_created=True, auto_now_add=True)
    edited = fields.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'People'
Beispiel #14
0
class Violation(_Model):
    employee = _related.ForeignKey(
        'holding.Employee',
        on_delete=_deletion.SET_NULL,
        null=True,
        blank=False,  # For admin panel?
        related_name="violations",
    )

    when = _field.DateTimeField("Когда")

    title = _field.CharField(
        verbose_name="Название нарушения",
        null=False,
        blank=False,
        max_length=128,
    )

    description = _field.TextField(
        verbose_name="Описание нарушения",
        null=True,
        blank=True,
    )

    timezone = _timezone.TimeZoneField(
        verbose_name="Временная зона",
        null=True,
        blank=True,
    )

    @property
    def employee_fullname(self):
        return "%s %s" % (self.employee.first_name, self.employee.last_name)

    employee_fullname.fget.short_description = "Сотрудник"

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if self.timezone is None:
            self.timezone = self.employee.company.timezone

        return super(Violation, self).save(force_insert, force_update, using, update_fields)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = "Нарушение"
        verbose_name_plural = "Нарушения"
class ParentCard(models.Model):
    fio = f.CharField(max_length=100, verbose_name='ФИО')
    address = f.CharField(max_length=100, verbose_name='Адрес')
    phone_number = PhoneNumberField(null=False,
                                    unique=True,
                                    verbose_name='Номер телефона')
    gender = f.CharField(max_length=7,
                         choices=GENDER_CHOICES,
                         verbose_name='Пол')
    date_of_birth = f.DateTimeField(verbose_name='Дата рождения',
                                    blank=True,
                                    null=True)
    email = f.EmailField(verbose_name='E-mail')

    def __str__(self):
        return self.fio
Beispiel #16
0
class ExchangeRate(models.Model):
    # NOTE: again, there is a lot of ways to implement a table for exchange rate montiring
    primary = CurrencyField()
    secondary = CurrencyField()

    rate = fields.FloatField(null=False, blank=False)

    last_update_date_time = fields.DateTimeField(null=False,
                                                 blank=False,
                                                 auto_now=True)

    class Meta:
        constraints = (models.UniqueConstraint(
            fields=('primary', 'secondary'),
            name='db_exchange_rate_primary_secondary_unique'), )
        index_together = ('primary', 'secondary')
Beispiel #17
0
class EpiduralRequest(models.EpisodeSubrecord):

    # this may change if we decide to handle the State of EpiduralRequest differently
    # in the Ruby version this was an Enum
    # Could this be handled as a SNOMED-CT lookuplist?
    epidural_status = fields.PositiveIntegerField(
        null=True,
        help_text=
        "Internal field for managing the state of the epidural request - ordered, in progress, completed, attempted-failed, etc)",
    )

    history = fields.TextField(
        null=True,
        help_text=
        "Focused summary of the relevant history. Use this area to let the amaesthetist know about any relevant hazards ar special circumstances",
    )

    cannula_in_situ = fields.BooleanField(
        help_text="Does the patient have a peripheral venous cannula in situ?",
    )

    anticoagulants = fields.BooleanField(
        help_text=
        "Is the patient currently taking anticolagulants, antiplatelet agents, or any other medication that 'thins' blood or affects coagulation?",
    )

    pyrexia = fields.BooleanField(
        help_text="Does the patient have a recent history of pyrexia?",
        # TODO definition of pyrexia should be explicitly stated (temp, duration, what is 'recent' etc)
    )

    hypertension = fields.BooleanField(
        help_text="Does the patient have pregnancy-induced hypertension (PIH)?",
    )

    # TODO this field could be autopopulated from the lab, also needs a timestamp to give meaning to 'latest'
    platelet_count = fields.CharField(
        null=True,
        max_length=20,
        help_text="Patient's latest Platelet count",
    )

    request_date_time = fields.DateTimeField(
        null=True,
        # default=timezone.now, (causes an Opal APIerror if uncommented)
        help_text="Date and time of the epidural request",
    )
class Collection(HasLinkedSequenceMixin, models.Model):
    """Set of Activities (problems) for a module."""

    name = fields.CharField(max_length=255)
    owner = models.ForeignKey(BridgeUser, on_delete=models.CASCADE)
    metadata = fields.CharField(max_length=255, blank=True, null=True)
    strict_forward = fields.BooleanField(default=True)
    updated_at = fields.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('owner', 'name')

    def __str__(self):
        return '<Collection: {}>'.format(self.name)

    def save(self, *args, **kwargs):
        """Extension cover method with logging."""
        initial_id = self.id
        super().save(*args, **kwargs)
        tasks.sync_collection_engines.apply_async(
            kwargs={
                'collection_id': self.id,
                'created_at': self.updated_at
            },
            countdown=settings.CELERY_DELAY_SYNC_TASK,
        )

        if initial_id:
            Log.objects.create(log_type=Log.ADMIN,
                               action=Log.COLLECTION_UPDATED,
                               data={'collection_id': self.id})
        else:
            Log.objects.create(log_type=Log.ADMIN,
                               action=Log.COLLECTION_CREATED,
                               data={'collection_id': self.id})

    def get_absolute_url(self):
        return reverse('module:collection-list')

    def get_launch_url(self, group):
        return "{}{}".format(
            settings.BRIDGE_HOST,
            reverse("lti:launch",
                    kwargs={
                        'collection_id': self.id,
                        'group_slug': group.slug
                    }))
Beispiel #19
0
class CreatedStump(__Model):
    from django.db.models import fields as _field

    created_at = _field.DateTimeField('Date record created',
                                      auto_now_add=True,
                                      null=True)

    def update(self, data, nullable=True):
        if nullable:
            [self.__setattr__(k, v) for k, v in data.items()]
        else:
            [self.__setattr__(k, v) for k, v in data.items() if v is not None]

        self.save(force_update=True)

    class Meta:
        abstract = True
Beispiel #20
0
class Collection(models.Model):
    """Set of Activities (problems) for a module."""

    name = fields.CharField(max_length=255)
    slug = AutoSlugField(
        populate_from='name',
        unique=True,
        db_index=True,
        help_text=
        "Add the slug for the collection. If field empty slug will be created automatically.",
        verbose_name='slug id')
    owner = models.ForeignKey(BridgeUser, on_delete=models.CASCADE)
    metadata = fields.CharField(max_length=255, blank=True, null=True)
    updated_at = fields.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('owner', 'name')

    def __str__(self):
        return '<Collection: {}>'.format(self.name)

    def save(self, *args, **kwargs):
        """Extension cover method with logging."""
        initial_id = self.id
        super().save(*args, **kwargs)
        tasks.sync_collection_engines.apply_async(
            kwargs={
                'collection_slug': self.slug,
                'created_at': self.updated_at
            },
            countdown=settings.CELERY_DELAY_SYNC_TASK,
        )

        if initial_id:
            Log.objects.create(log_type=Log.ADMIN,
                               action=Log.COLLECTION_UPDATED,
                               data={'collection_slug': self.slug})
        else:
            Log.objects.create(log_type=Log.ADMIN,
                               action=Log.COLLECTION_CREATED,
                               data={'collection_slug': self.slug})

    def get_absolute_url(self):
        return reverse('module:collection-list')
Beispiel #21
0
class Transaction(Model):
    account = ForeignKey(Account, on_delete=CASCADE)
    date = fields.DateTimeField('date')
    label = fields.CharField(max_length=1000)
    value = fields.FloatField()
    category = ForeignKey(Category, null=True)

    def categorize(self, category_matching):
        for m, c in category_matching:
            if m in self.label:
                self.category = c
                self.save()
                break

    class Meta:
        unique_together = (('account', 'date', 'label', 'value'), )

    def __str__(self):
        return 'Transaction: {date} {value} {label}'.format(date=self.date,
                                                            label=self.label,
                                                            value=self.value)
Beispiel #22
0
class BlockModel(Model):
    """
    Abstract Block Model
    Blocks have a type, and - apart from some status info - contain a JSON field

    """
    type = "base"
    is_active = fields.BooleanField()
    context = fields.TextField()
    updated_at = fields.DateTimeField(auto_now=True)

    def get_context_data(self):
        pass

    @property
    def context_data(self):
        """
        Return the block context as a string

        :return: dict
        """
        try:
            context = json.loads(self.context)
            if not context:
                context = {}
        except (ValueError, TypeError):
            context = {}
        return context

    def clean_context(self):
        """
        Return the context, see if it's valid JSON.

        :return:
        """
        pass

    class Meta:
        abstract = True
Beispiel #23
0
 def _resolve_output_field(self):
     if isinstance(self.value, str):
         return fields.CharField()
     if isinstance(self.value, bool):
         return fields.BooleanField()
     if isinstance(self.value, int):
         return fields.IntegerField()
     if isinstance(self.value, float):
         return fields.FloatField()
     if isinstance(self.value, datetime.datetime):
         return fields.DateTimeField()
     if isinstance(self.value, datetime.date):
         return fields.DateField()
     if isinstance(self.value, datetime.time):
         return fields.TimeField()
     if isinstance(self.value, datetime.timedelta):
         return fields.DurationField()
     if isinstance(self.value, Decimal):
         return fields.DecimalField()
     if isinstance(self.value, bytes):
         return fields.BinaryField()
     if isinstance(self.value, UUID):
         return fields.UUIDField()
Beispiel #24
0
class EpiduralFollowUp(models.EpisodeSubrecord):
    _is_singleton = True
    time_of_follow_up = fields.DateTimeField(
        blank=True, null=True
    )
    performed_by = fields.TextField(
        null=True,
        blank=True,

    )
    headache = fields.BooleanField(default=False)
    has_not_mobilised = fields.BooleanField(default=False)
    weakness = fields.BooleanField(default=False)
    sensory_disturbance = fields.BooleanField(default=False)
    back_pain = fields.BooleanField(default=False)
    has_not_passed_urine = fields.BooleanField(default=False)
    itu_admission = fields.BooleanField(default=False)
    general_anaesthesia = fields.BooleanField(default=False)
    home_before_follow_up = fields.BooleanField(default=False)
    post_natal_appointment_required = fields.BooleanField(default=False)
    other = fields.TextField(
        null=True,

    )
def update(**kwargs):
    import datetime
    import json
    import os
    import subprocess
    from collections import defaultdict

    from elasticsearch_dsl import Search
    from django.db.models import Q, F, ExpressionWrapper, fields, Value
    from django.utils import timezone
    from mainapp.models import ScrapRules, Document, Source, Author
    from nlpmonitor.settings import ES_CLIENT, ES_INDEX_DOCUMENT

    from util.constants import BASE_DAG_DIR

    import logging
    es_logger = logging.getLogger('elasticsearch')
    es_logger.setLevel(logging.ERROR)

    # Init
    start = kwargs['start']
    end = kwargs['end']
    now = timezone.now()

    print("!!!", "Getting documents URLs", datetime.datetime.now())
    sources = Source.objects.filter(
        Q(scraprules__type=6) | Q(scraprules__type=8)).only(
            'id')  # Has rules for num_views or num_comments
    scrap_rules = ScrapRules.objects.filter(source__in=sources,
                                            type__in=[6, 8])
    scrap_rules_dict = defaultdict(defaultdict)
    for rule in scrap_rules:
        scrap_rules_dict[rule.source.id][rule.type] = rule.selector
    qs = Document.objects.filter(source__in=sources).only(
        'id', 'num_views', 'num_comments', 'url', 'datetime',
        'datetime_created', 'datetime_activity_parsed')
    qs = qs.exclude(url=None)
    qs = qs.annotate(days_since_publication=ExpressionWrapper(
        Value(now, fields.DateTimeField()) - F('datetime'),
        output_field=fields.DurationField()))
    qs = qs.annotate(days_update_to_publication=ExpressionWrapper(
        F('datetime_activity_parsed') - F('datetime'),
        output_field=fields.DurationField()))
    qg7 = Q(days_since_publication__gte=datetime.timedelta(days=7))
    ql7 = Q(days_update_to_publication__lte=datetime.timedelta(days=7)) | Q(
        datetime_activity_parsed=None)
    qg30 = Q(days_since_publication__gte=datetime.timedelta(days=30))
    ql30 = Q(days_update_to_publication__lte=datetime.timedelta(days=30)) | Q(
        datetime_activity_parsed=None)
    qs = qs.filter((qg7 & ql7) | (qg30 & ql30))
    number_of_documents = qs.count()
    if number_of_documents == 0:
        return "Nothing to update"
    qs = qs.order_by('id')[int(start / 100 *
                               number_of_documents):int(end / 100 *
                                                        number_of_documents) +
                           1]
    number_of_documents = qs.count()
    print("!!!", number_of_documents, "to process", datetime.datetime.now())

    filename_suffix = f"{now.date()}_{start}_{end}"
    url_filename = f"url_list_update_{filename_suffix}.txt"
    if not os.path.exists(os.path.join(BASE_DAG_DIR, "tmp")):
        os.mkdir(os.path.join(BASE_DAG_DIR, "tmp"))
    url_path = os.path.join(BASE_DAG_DIR, "tmp", url_filename)
    with open(url_path, "w", encoding='utf-8') as f:
        for doc in qs:
            f.write(f"{doc.id}\n"
                    f"{doc.url}\n"
                    f"{scrap_rules_dict[doc.source.id].get(6, None)}\n"
                    f"{scrap_rules_dict[doc.source.id].get(8, None)}\n")

    # Scrap
    print("!!!", "Start scraping", datetime.datetime.now())
    os.chdir(os.path.join(BASE_DAG_DIR, "dags", "scraper", "scrapy_project"))
    filename = f"activity_update_{filename_suffix}.json"
    run_args = ["scrapy", "crawl", "activity_update_spider", "-o", filename]
    run_args.append("-a")
    run_args.append(f"url_filename={url_path}")
    run_args.append("-s")
    run_args.append(f"CLOSESPIDER_TIMEOUT={24*60*60}")
    try:
        print(f"Run command: {run_args}")
    except:
        pass
    output = subprocess.run(run_args, universal_newlines=True)
    print("!!!", "Output:", output.stdout)
    print("!!!", "Output Error:", output.stderr)

    # Write to DB
    print("!!!", "Writing to DB", datetime.datetime.now())
    filename = os.path.join(BASE_DAG_DIR, "dags", "scraper", "scrapy_project",
                            filename)
    news_updated = 0
    news_skipped = 0
    to_udpate_es = []
    try:
        with open(filename, "r", encoding='utf-8') as f:
            news = json.loads(f.read())
        news_update_dict = dict((int(new['id']), {
            "num_views": new.get('num_views', None),
            "num_comments": new.get('num_comments', None),
        }) for new in news)
        for doc in qs:
            if doc.id not in news_update_dict:
                news_skipped += 1
                continue
            doc.datetime_activity_parsed = now
            is_updated = False
            if news_update_dict[doc.id]['num_views'] is not None:
                is_updated = True
                doc.num_views = news_update_dict[doc.id]['num_views']
            if news_update_dict[doc.id]['num_comments'] is not None:
                is_updated = True
                doc.num_comments = news_update_dict[doc.id]['num_comments']
            if is_updated:
                to_udpate_es.append({
                    "id":
                    doc.id,
                    "num_views":
                    news_update_dict[doc.id]['num_views'],
                    "num_comments":
                    news_update_dict[doc.id]['num_comments'],
                })
                news_updated += 1
            if news_updated % 1000 == 0:
                print(f"Updated {news_updated}, currently id={doc.id}")
        Document.objects.bulk_update(
            qs,
            fields=['datetime_activity_parsed', 'num_views', 'num_comments'])
    except Exception as e:
        print("!!!!!!", "Updating DB exception", e)
    finally:
        os.remove(filename)
        os.remove(url_path)

    # Write to ES
    print("!!!", "Writing to ES", datetime.datetime.now())
    for i, doc in enumerate(to_udpate_es):
        update_body = {}
        if doc['num_views'] is not None:
            update_body['num_views'] = doc['num_views']
        if doc['num_comments'] is not None:
            update_body['num_comments'] = doc['num_comments']
        s = Search(using=ES_CLIENT,
                   index=ES_INDEX_DOCUMENT).filter("term", id=str(doc['id']))
        _ids = (hit.meta.id for hit in s.execute())
        for _id in _ids:
            ES_CLIENT.update(index=ES_INDEX_DOCUMENT,
                             id=_id,
                             body={"doc": update_body})
        if i % 1000 == 0:
            print(f"Writing {i}, current id={doc['id']}")
    return f"Parse complete, {news_updated} updated, {news_skipped} skipped"
Beispiel #26
0
class Request(SafeDeleteModel):
    class Meta:
        app_label = "crisis"
        db_table = "crisis_request"

    _safedelete_policy = SOFT_DELETE_CASCADE

    TYPE_OF_REQUEST = [("G", "Grocery"), ("M", "Medicine"), ("O", "Other")]
    STATUS_PENDING = "P"
    STATUS_TRANSIT = "T"
    STATUS_FINISHED = "F"
    STATUS_CANCELLED = "C"
    UNFINISHED_STATUSES = [STATUS_PENDING, STATUS_TRANSIT]
    FINISHED_STATUSES = [STATUS_FINISHED, STATUS_CANCELLED]
    TYPE_OF_REQUEST_STATUSES = [
        (STATUS_PENDING, "Pending"),
        (STATUS_TRANSIT, "Transit"),
        (STATUS_FINISHED, "Finished"),
        (STATUS_CANCELLED, "Cancelled"),
    ]
    owner = models.ForeignKey(
        "management.Participant",
        related_name="created_request",
        on_delete=models.CASCADE,
    )
    assignee = models.ForeignKey(
        "management.Participant",
        related_name="assigned_request",
        null=True,
        blank=True,
        on_delete=models.DO_NOTHING,
    )

    status = fields.CharField(choices=TYPE_OF_REQUEST_STATUSES, max_length=2)
    created_at = fields.DateTimeField(auto_now_add=True)
    modified_at = fields.DateTimeField(auto_now=True)
    type = models.CharField(choices=TYPE_OF_REQUEST, max_length=2, default="O")
    deadline = models.DateTimeField(null=True)
    description = models.TextField()
    bounty_amount_offered_to_volunteer = fields.DecimalField(max_digits=6,
                                                             decimal_places=2,
                                                             default=0.0)

    @property
    def related_request_assignment(self):
        return RequestAssignment.objects.get(assignee=self.assignee,
                                             request=self)

    def clean(self):
        if self.status in ["T"] and not self.assignee:
            raise ValidationError(
                "Assignee missing while changing status to assigned.")

    def __str__(self):
        return (f"{self.id}-{self.owner.user.first_name}"
                f"-{self.get_type_display()}-deadline-{self.deadline}")

    def assign_user(self, assignee_participant):
        self.status = self.STATUS_TRANSIT
        self.assignee = assignee_participant
        request_assignment = RequestAssignment.objects.create(
            status=RequestAssignment.STATUS_ASSIGNED,
            request=self,
            assignee=assignee_participant,
        )
        # Notify the original dude here ?
        self.save()
        self.refresh_from_db()
        self.notify_request_owner_about_assignment(
            request_assignment=request_assignment)

    def notify_request_owner_about_assignment(self, request_assignment):
        """
        I can send the whole request object to the template and fill up
        things there. Easy.
        :return:
        """
        return EmailPusher.send_email_to_af_user_on_assignment_by_hl(
            request=self, request_assignment=request_assignment)

    def notify_request_owner_about_assignment_drop(self):
        # @TODO
        pass

    def notify_request_owner_about_assignment_finish(self):
        # @TODO
        pass

    def resolve_request_from_assignee(self, status=STATUS_FINISHED):
        """
        Called when an asignee updates the status of a request. Depending on the
         status, we have to update the related RequestAssignment model too.
        :param status:
        :return:
        """
        related_assignment = self.related_request_assignment

        if status == self.STATUS_FINISHED:
            related_assignment.status = RequestAssignment.STATUS_COMPLETED
            related_assignment.did_complete = True

        related_assignment.save()
        return

    def drop_request_from_assignee(self):
        related_assignment = self.related_request_assignment

        if self.status == Request.STATUS_FINISHED:
            raise Exception("Cannot update this request at this point. Sorry.")
        related_assignment.status = RequestAssignment.STATUS_DROPPED
        related_assignment.save()
        self.status = self.STATUS_PENDING
        self.save()
        self.notify_request_owner_about_assignment_drop()
        return
Beispiel #27
0
def _front_page(paging_size=settings.PAGING_SIZE,
                page=0,
                add_filter={},
                add_q=[],
                as_of=None,
                days_back=50):
    # TODO: weighting https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d
    # (P-1) / (T+2)^G
    if as_of is None:
        now = timezone.now()
    else:
        now = as_of
    if connection.vendor == 'postgresql':
        now_value = Value(now, output_field=fields.DateTimeField())
        submission_age_float = ExpressionWrapper(
            (now_value - F('created_at')), output_field=fields.DurationField())
        submission_age_hours = ExpressionWrapper(
            Extract(F('tf'), 'epoch') / 60 / 60 + 2.1,
            output_field=fields.FloatField())
        real_p = ExpressionWrapper(F('points') - 1,
                                   output_field=fields.FloatField())
        formula = ExpressionWrapper(F('p') / (Power(F('tfh'), F('g')) + 0.001),
                                    output_field=fields.FloatField())
        return Story.objects.select_related('user')\
                .filter(duplicate_of__isnull=True)\
                .filter(points__gte=1) \
                .filter(created_at__gte=now - datetime.timedelta(days=days_back)) \
                .filter(created_at__lte=now) \
                .filter(**add_filter) \
                .annotate(tf=submission_age_float) \
                .annotate(tfh=submission_age_hours) \
                .annotate(p=real_p) \
                .annotate(g=Value(1.8, output_field=fields.FloatField())) \
                .annotate(formula=formula) \
                .order_by('-formula')[(page*paging_size):(page+1)*(paging_size)]
    elif connection.vendor == 'sqlite':
        now_value = Value(now, output_field=fields.DateTimeField())
        submission_age_float = ExpressionWrapper(
            (now_value - F('created_at')), output_field=fields.FloatField())
        submission_age_hours = ExpressionWrapper(
            F('tf') / 60 / 60 / 1000000 + 2.1,
            output_field=fields.FloatField())
        real_p = ExpressionWrapper(F('points') - 1,
                                   output_field=fields.FloatField())
        formula = ExpressionWrapper(F('p') / (Power(F('tfh'), F('g')) + 0.001),
                                    output_field=fields.FloatField())
        return Story.objects.select_related('user')\
                .filter(duplicate_of__isnull=True)\
                .filter(points__gte=1) \
                .filter(created_at__gte=now - datetime.timedelta(days=days_back)) \
                .filter(created_at__lte=now) \
                .filter(**add_filter) \
                .annotate(tf=submission_age_float) \
                .annotate(tfh=submission_age_hours) \
                .annotate(p=real_p) \
                .annotate(g=Value(1.8, output_field=fields.FloatField())) \
                .annotate(formula=formula) \
                .order_by('-formula')[(page*paging_size):(page+1)*(paging_size)]
    else:
        raise NotImplementedError(
            "No frontpage magic for database engine %s implemented" %
            (connection.vendor))
Beispiel #28
0
 def __init__(self, output_field=None, **extra):
     if output_field is None:
         output_field = fields.DateTimeField()
     super(Now, self).__init__(output_field=output_field, **extra)
Beispiel #29
0
class Participant(SafeDeleteModel):
    _safedelete_policy = HARD_DELETE_NOCASCADE
    """
    This is a participant for a crisis
    """

    TYPE_OF_PARTICIPANT = [
        ("HL", "Helper"),
        ("AF", "Affected"),
        ("AU", "Authorities"),
        ("TP", "Third Parties"),
    ]
    user = models.OneToOneField(User,
                                on_delete=models.CASCADE,
                                related_name="related_participant")
    type = fields.CharField(max_length=2, choices=TYPE_OF_PARTICIPANT)
    crisis = models.ForeignKey(Crisis, on_delete=models.DO_NOTHING)
    first_line_of_address = fields.CharField(max_length=255)
    second_line_of_address = fields.CharField(max_length=255, default="")
    country = CountryField(blank_label="(select country)")
    currency = fields.CharField(verbose_name="Default Currency",
                                default="SEK",
                                blank=True,
                                max_length=3)
    place_id = fields.CharField(verbose_name="Place id from Google",
                                max_length=150)

    position = PointField(null=True, blank=True, geography=True)
    post_code = fields.CharField(verbose_name="Postal code", max_length=10)
    city = fields.CharField(verbose_name="City", max_length=40)
    phone = PhoneField(blank=True, help_text="Contact phone number")
    metadata = JSONField(blank=True, default=dict)

    objects = manager.Manager()
    helpers = HelperParticipantManager()
    affected = AffectedParticipantManager()

    created_at = fields.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.id}-{self.user.first_name}-({self.get_type_display()})"

    @property
    def location(self):
        address = f"{self.first_line_of_address}"
        if self.second_line_of_address:
            address = f"{address}, {self.second_line_of_address}"
        return f"{address}, {self.city}, {self.country}, {self.post_code}"

    @property
    def contact_details(self):
        return f"Phone: {self.phone}, Email: {self.user.email}"

    def create_sample_request(self):
        from crisis.models import Request

        random_request_type = random.choice(["G", "M"])
        deadline = datetime.utcnow() + timedelta(days=10)
        request = Request(
            owner=self,
            status=Request.STATUS_PENDING,
            type=random_request_type,
            deadline=deadline,
            description="Dummy request created through bulk script",
        )
        request.save()
Beispiel #30
0
 def __init__(self, col, lookup_type, tzname):
     super(DateTime, self).__init__(output_field=fields.DateTimeField())
     self.col = col
     self.lookup_type = lookup_type
     self.tzname = tzname