src/iconolab/models.py
author Alexandre Segura <mex.zktk@gmail.com>
Fri, 19 May 2017 16:05:10 +0200
changeset 514 accd1fded1a5
parent 507 1bae3da99830
child 519 fb295acc6c3c
permissions -rw-r--r--
Improve homepage. - Add best contributors - Add latest annotations - Add most accurate tags
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     1
import json
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     2
import logging
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     3
import re
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     4
import urllib
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     5
import uuid
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     6
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
     7
import requests
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
     8
from django.conf import settings
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
     9
from django.contrib.auth.models import User
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    10
from django.contrib.contenttypes.fields import GenericRelation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    11
from django.contrib.contenttypes.models import ContentType
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
    12
from django.db import models, transaction
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
    13
from django.utils.text import slugify
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    14
from django_comments_xtd.models import XtdComment
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
    15
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    16
import iconolab.signals.handlers as iconolab_signals
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    17
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    18
logger = logging.getLogger(__name__)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    19
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    20
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    21
class Collection(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    22
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    23
        Collection objects are the thematic item repositories in Iconolab
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    24
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    25
            name: the name displayed in the url and also used to identify the collection
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    26
            verbose_name: the name displayed in the text of the pages
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    27
            description: the short description of the collection that will be
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    28
                displayed by default in pages
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    29
            complete_description: the complete description that will be shown
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    30
                with a "view more" button/link
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    31
            image/height/width: the collection image that will be shown in the
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    32
                collection description
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    33
            show_image_on_home: if True, the collection will appear by default
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    34
                on the homepage as one of the bigger images
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    35
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    36
    name = models.SlugField(max_length=50, unique=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    37
    verbose_name = models.CharField(max_length=50, null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    38
    description = models.TextField(null=True, blank=True, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    39
    complete_description = models.TextField(null=True, blank=True, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    40
    image = models.ImageField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    41
        upload_to='uploads/', height_field='height', width_field='width', null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    42
    height = models.IntegerField(null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    43
    width = models.IntegerField(null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    44
    show_image_on_home = models.BooleanField(default=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    45
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    46
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    47
        return self.name
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    48
416
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    49
class Folder(models.Model):
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    50
    """
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    51
        Some items may belong to a "folder". This is actually a physical folder
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    52
    """
464
655136b09cf3 Introduce more fields in Folder model.
Alexandre Segura <mex.zktk@gmail.com>
parents: 416
diff changeset
    53
    folder_guid = models.UUIDField(default=uuid.uuid4, editable=False)
655136b09cf3 Introduce more fields in Folder model.
Alexandre Segura <mex.zktk@gmail.com>
parents: 416
diff changeset
    54
    collection = models.ForeignKey(Collection, related_name="folders")
416
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    55
    name = models.TextField(null=False, blank=False)
464
655136b09cf3 Introduce more fields in Folder model.
Alexandre Segura <mex.zktk@gmail.com>
parents: 416
diff changeset
    56
    description = models.TextField(null=True, blank=True)
655136b09cf3 Introduce more fields in Folder model.
Alexandre Segura <mex.zktk@gmail.com>
parents: 416
diff changeset
    57
    original_id = models.CharField(max_length=256, null=True, blank=True)
484
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    58
    display_image = models.ImageField(blank=True, null=True, upload_to='uploads/')
416
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    59
471
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    60
    @property
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    61
    def items(self):
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    62
        return Item.objects.filter(folders=self)
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    63
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    64
    @property
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    65
    def items_count(self):
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    66
        return self.items.count()
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    67
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    68
    @property
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    69
    def image(self):
484
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    70
        if self.display_image:
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    71
            return self.display_image
471
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    72
        first_item = self.items.first()
484
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    73
        if not first_item:
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    74
            return None
471
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    75
        images = Image.objects.filter(item=first_item)
484
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    76
        first_image = images.first()
6d46a199d5db add image override for folders
ymh <ymh.work@gmail.com>
parents: 471
diff changeset
    77
        return first_image.media if first_image else None
471
d80f62757142 Display image & item count for folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 464
diff changeset
    78
416
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    79
    def __str__(self):
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    80
        return 'Folder ' + self.name
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    81
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    82
class Item(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    83
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    84
        Item objects belong to a collection, are linked to a metadata item, and
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    85
        to one or more images
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    86
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    87
    collection = models.ForeignKey(Collection, related_name="items")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    88
    item_guid = models.UUIDField(default=uuid.uuid4, editable=False)
416
5daa15b87404 Introduce folders.
Alexandre Segura <mex.zktk@gmail.com>
parents: 337
diff changeset
    89
    folders = models.ManyToManyField('Folder')
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    90
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    91
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    92
        return str(self.item_guid) + ":from:" + self.collection.name
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    93
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    94
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    95
    def images_sorted_by_name(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    96
        return self.images.order_by("-name").all()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    97
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    98
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
    99
class ItemMetadata(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   100
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   101
        Metadata object for the item class. Each field represents what we can
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   102
        import from the provided .csv files
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   103
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   104
    item = models.OneToOneField('Item', related_name='metadatas')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   105
    authors = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   106
    school = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   107
    field = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   108
    designation = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   109
    datation = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   110
    technics = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   111
    measurements = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   112
    create_or_usage_location = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   113
    discovery_context = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   114
    conservation_location = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   115
    photo_credits = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   116
    inventory_number = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   117
    joconde_ref = models.CharField(max_length=255, default="")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   118
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   119
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   120
    def get_joconde_url(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   121
        return settings.JOCONDE_NOTICE_BASE_URL + self.joconde_ref.rjust(11, '0')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   122
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   123
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   124
        return "metadatas:for:" + str(self.item.item_guid)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   125
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   126
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   127
class Image(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   128
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   129
        Each image object is linked to one item, users can create annotations on images
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   130
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   131
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   132
    image_guid = models.UUIDField(default=uuid.uuid4, editable=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   133
    name = models.CharField(max_length=200)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   134
    media = models.ImageField(upload_to='uploads/',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   135
                              height_field='height', width_field='width')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   136
    item = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   137
        'Item', related_name='images', null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   138
    height = models.IntegerField(null=False, blank=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   139
    width = models.IntegerField(null=False, blank=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   140
    created = models.DateTimeField(auto_now_add=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   141
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   142
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   143
        return str(self.image_guid) + ":" + self.name
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   144
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   145
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   146
    def wh_ratio(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   147
        return self.width / self.height
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   148
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   149
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   150
    def collection(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   151
        return self.item.collection.name
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   152
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   153
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   154
    def title(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   155
        return self.item.metadatas.designation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   156
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   157
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   158
    def authors(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   159
        return self.item.metadatas.authors
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   160
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   161
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   162
    def school(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   163
        return self.item.metadatas.school
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   164
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   165
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   166
    def designation(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   167
        return self.item.metadatas.designation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   168
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   169
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   170
    def datation(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   171
        return self.item.metadatas.datation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   172
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   173
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   174
    def technics(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   175
        return self.item.metadatas.technics
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   176
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   177
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   178
    def measurements(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   179
        return self.item.metadatas.measurements
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   180
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   181
    @property
323
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   182
    def latest_annotations(self):
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   183
        return self.annotations.all().order_by('-created')
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   184
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   185
    @property
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   186
    def tag_labels(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   187
        tag_list = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   188
        for annotation in self.annotations.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   189
            revision_tags = json.loads(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   190
                annotation.current_revision.get_tags_json())
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   191
            tag_list += [tag_infos['tag_label']
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   192
                         for tag_infos in revision_tags if tag_infos.get('tag_label') is not None]  # deal with
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   193
        return tag_list
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   194
507
1bae3da99830 Display bookmarked images.
Alexandre Segura <mex.zktk@gmail.com>
parents: 506
diff changeset
   195
    def is_bookmarked_by(self, user):
1bae3da99830 Display bookmarked images.
Alexandre Segura <mex.zktk@gmail.com>
parents: 506
diff changeset
   196
        return Bookmark.objects.filter(image=self, category__user=user).count() > 0
1bae3da99830 Display bookmarked images.
Alexandre Segura <mex.zktk@gmail.com>
parents: 506
diff changeset
   197
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   198
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   199
class ImageStats(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   200
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   201
        Stats objects for a given image, keep count of several values to be
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   202
        displayed in image and item pages
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   203
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   204
    image = models.OneToOneField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   205
        'Image', related_name='stats', blank=False, null=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   206
    views_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   207
    annotations_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   208
    submitted_revisions_count = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   209
        blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   210
    comments_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   211
    folders_inclusion_count = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   212
        blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   213
    tag_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   214
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   215
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   216
        return "stats:for:" + str(self.image.image_guid)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   217
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   218
    def set_tags_stats(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   219
        self.tag_count = Tag.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   220
            tagginginfo__revision__annotation__image=self.image).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   221
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   222
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   223
    def update_stats(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   224
        self.annotations_count = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   225
        self.submitted_revisions_count = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   226
        self.comments_count = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   227
        image_annotations = Annotation.objects.filter(image=self.image)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   228
        # views_count - Can't do much about views count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   229
        # annotations_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   230
        self.annotations_count = image_annotations.count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   231
        # submitted_revisions_count & comment_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   232
        for annotation in image_annotations.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   233
            annotation_revisions = annotation.revisions
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   234
            self.submitted_revisions_count += annotation_revisions.count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   235
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   236
            self.comments_count += XtdComment.objects.for_app_models("iconolab.annotation").filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   237
                object_pk=annotation.pk,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   238
            ).count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   239
        # tag_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   240
        self.tag_count = Tag.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   241
            tagginginfo__revision__annotation__image=self.image).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   242
        self.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   243
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   244
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   245
class AnnotationManager(models.Manager):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   246
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   247
        Manager class for annotation, it handles annotation creation (with initial revision creation, and
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   248
        has methods to get a list of annotation commented for a given user, and a list of annotations contributed for a
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   249
        given user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   250
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   251
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   252
    def create_annotation(self, author, image, title='', description='', fragment='', tags_json='[]'):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   253
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   254
            Creates a new Annotation with its associated AnnotationStats and initial AnnotationRevision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   255
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   256
        # Create annotation object
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   257
        new_annotation = Annotation(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   258
            image=image,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   259
            author=author
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   260
        )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   261
        new_annotation.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   262
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   263
        # Create initial revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   264
        initial_revision = AnnotationRevision(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   265
            annotation=new_annotation,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   266
            author=author,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   267
            title=title,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   268
            description=description,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   269
            fragment=fragment,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   270
            state=AnnotationRevision.ACCEPTED
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   271
        )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   272
        initial_revision.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   273
        initial_revision.set_tags(tags_json)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   274
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   275
        # Create stats object
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   276
        new_annotation_stats = AnnotationStats(annotation=new_annotation)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   277
        new_annotation_stats.set_tags_stats()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   278
        new_annotation_stats.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   279
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   280
        # Link everything to parent
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   281
        new_annotation.current_revision = initial_revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   282
        new_annotation.stats = new_annotation_stats
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   283
        new_annotation.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   284
        iconolab_signals.revision_created.send(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   285
            sender=AnnotationRevision, instance=initial_revision)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   286
        return new_annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   287
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   288
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   289
    def get_annotations_contributed_for_user(self, user):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   290
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   291
            user is the user whom we want to get the contributed annotations
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   292
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   293
            Returns the list of all the annotations on which the user submitted
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   294
            a revision but did not create the annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   295
            List of dict in the format:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   296
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   297
            {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   298
                "annotation_obj": annotation object,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   299
                "revisions_count": revisions count for user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   300
                "awaiting_count": awaiting revisions for user on this annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   301
                "accepted_count": accepted revisions for user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   302
                "latest_submitted_revision": date of the latest submitted revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   303
                    from user on annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   304
            }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   305
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   306
        latest_revision_on_annotations = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   307
        user_contributed_annotations = Annotation.objects.filter(revisions__author=user).exclude(author=user).prefetch_related(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   308
            'current_revision',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   309
            'revisions',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   310
            'image',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   311
            'image__item',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   312
            'image__item__collection').distinct()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   313
        for annotation in user_contributed_annotations.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   314
            latest_revision_on_annotations.append(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   315
                annotation.revisions.filter(author=user).latest(field_name="created"))
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   316
        contributed_list = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   317
        if latest_revision_on_annotations:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   318
            latest_revision_on_annotations.sort(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   319
                key=lambda item: item.created, reverse=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   320
            contributed_list = [
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   321
                {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   322
                    "annotation_obj": revision.annotation,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   323
                    "revisions_count": revision.annotation.revisions.filter(author=user).count(),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   324
                    "awaiting_count": revision.annotation.revisions.filter(author=user, state=AnnotationRevision.AWAITING).count(),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   325
                    "accepted_count": revision.annotation.revisions.filter(author=user, state=AnnotationRevision.ACCEPTED).count(),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   326
                    "latest_submitted_revision": revision.created
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   327
                }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   328
                for revision in latest_revision_on_annotations
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   329
            ]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   330
        return contributed_list
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   331
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   332
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   333
    def get_annotations_commented_for_user(self, user, ignore_revisions_comments=True):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   334
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   335
            user is the user for which we want to get the commented annotations
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   336
            ignore_revisions_comment allows to filter comments that are associated with a revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   337
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   338
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   339
            Returns a list of all annotations on which a given user commented
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   340
            with user-comments-related data
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   341
            List of dict in the format:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   342
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   343
            {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   344
                "annotation_obj": annotation object,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   345
                "comment_count": comment count for user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   346
                "latest_comment_date": date of the latest comment from user on annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   347
            }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   348
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   349
        user_comments = IconolabComment.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   350
            user=user, content_type__app_label='iconolab', content_type__model='annotation').order_by('-submit_date')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   351
        if ignore_revisions_comments:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   352
            user_comments = user_comments.filter(revision__isnull=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   353
        all_user_comments_data = [
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   354
            (comment.object_pk, comment.submit_date) for comment in user_comments]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   355
        unique_ordered_comments_data = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   356
        for (id, submit_date) in all_user_comments_data:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   357
            if id not in [item["annotation_id"] for item in unique_ordered_comments_data]:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   358
                unique_ordered_comments_data.append(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   359
                    {"annotation_id": id, "latest_comment_date": submit_date})
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   360
        commented_annotations = Annotation.objects.filter(id__in=[item["annotation_id"] for item in unique_ordered_comments_data]).prefetch_related(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   361
            'current_revision',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   362
            'revisions',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   363
            'image',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   364
            'image__item',
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   365
            'image__item__collection'
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   366
        ).distinct()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   367
        sorted_annotations_list = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   368
        for comment_data in unique_ordered_comments_data:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   369
            annotation_obj = commented_annotations.get(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   370
                id=comment_data["annotation_id"])
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   371
            sorted_annotations_list.append(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   372
                {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   373
                    "annotation_obj": annotation_obj,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   374
                    "comment_count_for_user": user_comments.filter(object_pk=annotation_obj.id).count(),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   375
                    "latest_comment_date": comment_data["latest_comment_date"]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   376
                }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   377
            )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   378
        return sorted_annotations_list
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   379
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   380
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   381
class Annotation(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   382
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   383
        Annotation objects are created on a given image, each annotation have a
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   384
        list of revisions to keep track of its history, the latest revision is
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   385
        the 'current revision' that will be displayed by default in most pages.
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   386
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   387
        Annotation data (title, description, fragment) is thus stored in the revision.
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   388
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   389
        Annotations can be considered validated or not depending on the metacategories
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   390
        posted in their comments through the attribute validation_state. Their
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   391
        validation state can also be overriden and in such case we can use
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   392
        validation_state_overriden attribute to remember it in the model (so for
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   393
        instance if an admin un-validates an annotation we could block it from
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   394
        being validated again)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   395
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   396
    UNVALIDATED = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   397
    VALIDATED = 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   398
    VALIDATION_STATES = (
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   399
        (UNVALIDATED, 'unvalidated'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   400
        (VALIDATED, 'validated'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   401
    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   402
    annotation_guid = models.UUIDField(default=uuid.uuid4, editable=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   403
    image = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   404
        'Image', related_name='annotations', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   405
    source_revision = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   406
        'AnnotationRevision', related_name='source_related_annotation', blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   407
    current_revision = models.OneToOneField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   408
        'AnnotationRevision', related_name='current_for_annotation', blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   409
    author = models.ForeignKey(User, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   410
    created = models.DateTimeField(auto_now_add=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   411
    comments = GenericRelation(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   412
        'IconolabComment', content_type_field='content_type_id', object_id_field='object_pk')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   413
    validation_state = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   414
        choices=VALIDATION_STATES, default=UNVALIDATED)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   415
    validation_state_overriden = models.BooleanField(default=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   416
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   417
    objects = AnnotationManager()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   418
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   419
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   420
        return str(self.annotation_guid) + ":" + self.current_revision.title
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   421
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   422
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   423
    def awaiting_revisions_count(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   424
        return self.revisions.filter(state=AnnotationRevision.AWAITING).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   425
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   426
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   427
    def accepted_revisions_count(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   428
        return self.revisions.filter(state=AnnotationRevision.ACCEPTED).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   429
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   430
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   431
    def rejected_revisions_count(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   432
        return self.revisions.filter(state=AnnotationRevision.REJECTED).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   433
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   434
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   435
    def studied_revisions_count(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   436
        return self.revisions.filter(state=AnnotationRevision.STUDIED).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   437
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   438
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   439
    def total_revisions_count(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   440
        return self.revisions.distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   441
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   442
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   443
    def collection(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   444
        return self.image.collection
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   445
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   446
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   447
    def tag_labels(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   448
        current_revision_tags = json.loads(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   449
            self.current_revision.get_tags_json())
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   450
        return [tag_infos['tag_label'] for tag_infos in current_revision_tags if tag_infos.get('tag_label') is not None]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   451
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   452
    def latest_revision_for_user(self, user):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   453
        user_revisions = self.revisions.filter(creator=user)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   454
        if user_revisions.exists():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   455
            return user_revisions.filter(creator=author).order_by("-created").first()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   456
        return None
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   457
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   458
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   459
    def make_new_revision(self, author, title, description, fragment, tags_json):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   460
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   461
            Called to create a new revision, potentially from a merge
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   462
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   463
        if author == self.author:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   464
            # We're creating an automatically accepted revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   465
            new_revision_state = AnnotationRevision.ACCEPTED
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   466
        else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   467
            # Revision will require validation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   468
            new_revision_state = AnnotationRevision.AWAITING
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   469
        new_revision = AnnotationRevision(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   470
            annotation=self,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   471
            parent_revision=self.current_revision,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   472
            title=title,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   473
            description=description,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   474
            author=author,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   475
            fragment=fragment,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   476
            state=new_revision_state
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   477
        )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   478
        new_revision.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   479
        new_revision.set_tags(tags_json)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   480
        if new_revision.state == AnnotationRevision.ACCEPTED:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   481
            self.current_revision = new_revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   482
            self.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   483
        iconolab_signals.revision_created.send(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   484
            sender=AnnotationRevision, instance=new_revision)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   485
        return new_revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   486
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   487
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   488
    def validate_existing_revision(self, revision_to_validate):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   489
        """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   490
            Called when we're validating an awaiting revision whose parent is
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   491
            the current revision AS IT WAS CREATED
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   492
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   493
        if revision_to_validate.parent_revision == self.current_revision and revision_to_validate.state == AnnotationRevision.AWAITING:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   494
            self.current_revision = revision_to_validate
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   495
            revision_to_validate.state = AnnotationRevision.ACCEPTED
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   496
            revision_to_validate.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   497
            self.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   498
            iconolab_signals.revision_accepted.send(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   499
                sender=AnnotationRevision, instance=revision_to_validate)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   500
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   501
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   502
    def reject_existing_revision(self, revision_to_reject):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   503
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   504
             Called when we reject a revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   505
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   506
        if revision_to_reject.state == AnnotationRevision.AWAITING:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   507
            revision_to_reject.state = AnnotationRevision.REJECTED
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   508
            revision_to_reject.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   509
            iconolab_signals.revision_rejected.send(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   510
                sender=AnnotationRevision, instance=revision_to_reject)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   511
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   512
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   513
    def merge_existing_revision(self, title, description, fragment, tags, revision_to_merge):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   514
        """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   515
            Called when we're validating an awaiting revision whose parent isn't
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   516
            the current revision or if the awaiting revision was modified by the annotation author
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   517
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   518
        merged_revision = self.make_new_revision(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   519
            author=self.author, title=title, description=description, fragment=fragment, tags_json=tags)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   520
        merged_revision.merge_parent_revision = revision_to_merge
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   521
        merged_revision.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   522
        revision_to_merge.state = AnnotationRevision.STUDIED
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   523
        revision_to_merge.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   524
        iconolab_signals.revision_accepted.send(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   525
            sender=AnnotationRevision, instance=revision_to_merge)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   526
        self.current_revision = merged_revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   527
        self.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   528
        return merged_revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   529
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   530
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   531
class AnnotationStats(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   532
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   533
        Stats objects for a given annotation, keep count of several values to be
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   534
        displayed in annotation pages
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   535
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   536
    annotation = models.OneToOneField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   537
        'Annotation', related_name='stats', blank=False, null=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   538
    submitted_revisions_count = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   539
        blank=True, null=True, default=1)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   540
    awaiting_revisions_count = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   541
        blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   542
    accepted_revisions_count = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   543
        blank=True, null=True, default=1)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   544
    contributors_count = models.IntegerField(blank=True, null=True, default=1)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   545
    views_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   546
    comments_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   547
    tag_count = models.IntegerField(blank=True, null=True, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   548
    metacategories = models.ManyToManyField(
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   549
        'MetaCategory',
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   550
        through='MetaCategoriesCountInfo',
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   551
        through_fields=('annotation_stats_obj', 'metacategory')
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   552
    )
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   553
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   554
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   555
        return "stats:for:" + str(self.annotation.annotation_guid)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   556
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   557
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   558
    def contributors(self):
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   559
        user_ids_list = self.annotation.revisions.filter(
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   560
            state__in=[AnnotationRevision.ACCEPTED, AnnotationRevision.STUDIED]
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   561
        ).values_list("author__id", flat=True)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   562
        return User.objects.filter(id__in=user_ids_list).distinct()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   563
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   564
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   565
    def commenters(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   566
        user_ids_list = IconolabComment.objects.filter(
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   567
            content_type__app_label="iconolab",
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   568
            content_type__model="annotation",
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   569
            object_pk=self.annotation.id
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   570
        ).values_list("user__id", flat=True)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   571
        return User.objects.filter(id__in=user_ids_list).distinct()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   572
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   573
    def set_tags_stats(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   574
        self.tag_count = Tag.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   575
            tagginginfo__revision=self.annotation.current_revision).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   576
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   577
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   578
    def relevant_tags_count(self, score=settings.RELEVANT_TAGS_MIN_SCORE):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   579
        return TaggingInfo.objects.filter(revision=self.annotation.current_revision, relevancy__gte=score).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   580
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   581
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   582
    def accurate_tags_count(self, score=settings.ACCURATE_TAGS_MIN_SCORE):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   583
        return TaggingInfo.objects.filter(revision=self.annotation.current_revision, accuracy__gte=score).distinct().count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   584
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   585
    @transaction.atomic
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   586
    def update_stats(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   587
        # views_count - Can't do much about views count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   588
        # submitted_revisions_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   589
        annotation_revisions = self.annotation.revisions
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   590
        self.submitted_revisions_count = annotation_revisions.count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   591
        # aawaiting_revisions_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   592
        self.awaiting_revisions_count = annotation_revisions.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   593
            state=AnnotationRevision.AWAITING).count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   594
        # accepted_revisions_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   595
        self.accepted_revisions_count = annotation_revisions.filter(state=AnnotationRevision.ACCEPTED).count(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   596
        ) + annotation_revisions.filter(state=AnnotationRevision.STUDIED).count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   597
        # comment_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   598
        self.comments_count = XtdComment.objects.for_app_models("iconolab.annotation").filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   599
            object_pk=self.annotation.pk,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   600
        ).count()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   601
        # contributors_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   602
        self.contributors_count = len(self.contributors)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   603
        # tag_count
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   604
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   605
        annotation_comments_with_metacategories = IconolabComment.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   606
            content_type__app_label="iconolab",
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   607
            content_type__model="annotation",
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   608
            object_pk=self.annotation.id,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   609
            metacategories__collection=self.annotation.image.item.collection
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   610
        )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   611
        m2m_objects = MetaCategoriesCountInfo.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   612
            annotation_stats_obj=self)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   613
        for obj in m2m_objects.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   614
            obj.count = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   615
            obj.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   616
        for comment in annotation_comments_with_metacategories.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   617
            for metacategory in comment.metacategories.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   618
                if metacategory not in self.metacategories.all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   619
                    MetaCategoriesCountInfo.objects.create(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   620
                        annotation_stats_obj=self, metacategory=metacategory, count=1)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   621
                else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   622
                    m2m_object = MetaCategoriesCountInfo.objects.filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   623
                        annotation_stats_obj=self, metacategory=metacategory).first()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   624
                    m2m_object.count += 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   625
                    m2m_object.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   626
        self.set_tags_stats()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   627
        self.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   628
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   629
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   630
class MetaCategoriesCountInfo(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   631
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   632
        M2M class to keep a count of a given metacategory on a given annotation.
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   633
        Metacategories are linked to comments, themselve linked to an annotation
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   634
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   635
    annotation_stats_obj = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   636
        'AnnotationStats', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   637
    metacategory = models.ForeignKey('MetaCategory', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   638
    count = models.IntegerField(default=1, blank=False, null=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   639
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   640
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   641
        return "metacategory_count_for:" + self.metacategory.label + ":on:" + str(self.annotation_stats_obj.annotation.annotation_guid)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   642
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   643
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   644
class AnnotationRevision(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   645
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   646
        AnnotationRevisions objects are linked to an annotation and store the data of the annotation at a given time
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   647
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   648
        A revision is always in one out of multiple states:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   649
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   650
        - Awaiting: the revision has been submitted but must be validated by the
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   651
          original author of the related annotation
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   652
        - Accepted: the revision has been accepted *as-is* by the author of the
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   653
          related annotation (this happens automatically if the revision is created
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   654
          by the author of the annotation)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   655
        - Rejected: the revision has been rejected by the author of the related annotation
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   656
        - Studied: the revision has been studied by the author of the related
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   657
          annotation and was either modified or at the very least compared with the current state
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   658
          through the merge interface, thus creating a new revision merging the
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   659
          current state with the proposal. At this point the proposal is flagged
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   660
          as "studied" to show that the author of the original annotation has considered it
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   661
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   662
    AWAITING = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   663
    ACCEPTED = 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   664
    REJECTED = 2
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   665
    STUDIED = 3
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   666
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   667
    REVISION_STATES = (
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   668
        (AWAITING, 'awaiting'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   669
        (ACCEPTED, 'accepted'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   670
        (REJECTED, 'rejected'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   671
        (STUDIED, 'studied'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   672
    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   673
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   674
    revision_guid = models.UUIDField(default=uuid.uuid4)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   675
    annotation = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   676
        'Annotation', related_name='revisions', null=False, blank=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   677
    parent_revision = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   678
        'AnnotationRevision', related_name='child_revisions', blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   679
    merge_parent_revision = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   680
        'AnnotationRevision', related_name='child_revisions_merge', blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   681
    author = models.ForeignKey(User, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   682
    title = models.CharField(max_length=255)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   683
    description = models.TextField(null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   684
    fragment = models.TextField()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   685
    tags = models.ManyToManyField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   686
        'Tag', through='TaggingInfo', through_fields=('revision', 'tag'))
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   687
    state = models.IntegerField(choices=REVISION_STATES, default=AWAITING)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   688
    created = models.DateTimeField(auto_now_add=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   689
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   690
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   691
        return str(self.revision_guid) + ":" + self.title
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   692
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   693
    def set_tags(self, tags_json_string):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   694
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   695
            This method creates tags object and links them to the revision, from a given json that has the following format:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   696
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   697
            [
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   698
                {
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   699
                    "tag_input": the tag string that has been provided. If it is
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   700
                       an http(s?):// pattern, it means the tag is external, else
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   701
                       it means it is a custom tag
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   702
                    "accuracy": the accuracy value provided by the user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   703
                    "relevancy": the relevancy value provided by the user
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   704
                },
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   705
                {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   706
                   ...
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   707
                }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   708
            ]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   709
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   710
        try:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   711
            tags_dict = json.loads(tags_json_string)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   712
        except ValueError:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   713
            pass
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   714
        for tag_data in tags_dict:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   715
            tag_string = tag_data.get("tag_input")
323
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   716
            tag_label = tag_data.get("tag_label")
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   717
            tag_accuracy = tag_data.get("accuracy", 0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   718
            tag_relevancy = tag_data.get("relevancy", 0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   719
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   720
            # check if url
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   721
            if tag_string.startswith("http://") or tag_string.startswith("https://"):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   722
                # check if tag already exists
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   723
                if Tag.objects.filter(link=tag_string).exists():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   724
                    tag_obj = Tag.objects.get(link=tag_string)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   725
                else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   726
                    tag_obj = Tag.objects.create(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   727
                        link=tag_string,
323
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   728
                        label=tag_label
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   729
                    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   730
            else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   731
                new_tag_link = settings.BASE_URL + '/' + slugify(tag_string)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   732
                if Tag.objects.filter(link=new_tag_link).exists():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   733
                    # Somehow we received a label for an existing tag
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   734
                    tag_obj = Tag.objects.get(link=new_tag_link)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   735
                else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   736
                    tag_obj = Tag.objects.create(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   737
                        label=tag_string,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   738
                        label_slug=slugify(tag_string),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   739
                        description="",
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   740
                        link=settings.INTERNAL_TAGS_URL +
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   741
                        '/' + slugify(tag_string),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   742
                        collection=self.annotation.image.item.collection
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   743
                    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   744
            tag_info = TaggingInfo.objects.create(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   745
                tag=tag_obj,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   746
                revision=self,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   747
                accuracy=tag_accuracy,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   748
                relevancy=tag_relevancy
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   749
            )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   750
323
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   751
    # FIXME Avoid calling DBPedia all the time
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   752
    def get_tags_json(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   753
        """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   754
            This method returns the json data that will be sent to the js to display
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   755
            tags for the revision.
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   756
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   757
            The json data returned will be of the following format:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   758
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   759
            [
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   760
                {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   761
                        "tag_label": the tag label for display purposes,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   762
                        "tag_link": the link of the tag, for instance for dbpedia links,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   763
                        "accuracy": the accuracy value of the tag,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   764
                        "relevancy": the relevancy value of the tag,
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   765
                        "is_internal": will be True if the tag is 'internal',
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   766
                          meaning specific to Iconolab and
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   767
                        not an external tag like a dbpedia reference for instance
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   768
                },
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   769
                {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   770
                    ...
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   771
                }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   772
            ]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   773
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   774
        def fetch_from_dbpedia(uri, lang, source):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   775
            sparql_template = 'select distinct * where { <<%uri%>> rdfs:label ?l FILTER( langMatches( lang(?l), "<%lang%>" ) ) }'
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   776
            sparql_query = re.sub("<%uri%>", uri, re.sub(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   777
                "<%lang%>", lang, sparql_template))
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   778
            sparql_query_url = source + 'sparql'
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   779
            try:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   780
                dbpedia_resp = requests.get(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   781
                    sparql_query_url,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   782
                    params={
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   783
                        "query": sparql_query,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   784
                        "format": "json"
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   785
                    }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   786
                )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   787
            except:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   788
                # dbpedia is down, will be handled with database label
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   789
                pass
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   790
            try:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   791
                results = json.loads(dbpedia_resp.text).get("results", {})
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   792
            except:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   793
                # if error with json, results is empty
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   794
                results = {}
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   795
            variable_bindings = results.get("bindings", None)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   796
            label_data = {}
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   797
            if variable_bindings:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   798
                label_data = variable_bindings.pop()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   799
            return label_data.get("l", {"value": False}).get("value")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   800
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   801
        final_list = []
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   802
        for tagging_info in self.tagginginfo_set.select_related("tag").all():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   803
            if tagging_info.tag.is_internal():
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   804
                final_list.append({
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   805
                    "tag_label": tagging_info.tag.label,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   806
                    "tag_link": tagging_info.tag.link,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   807
                    "accuracy": tagging_info.accuracy,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   808
                    "relevancy": tagging_info.relevancy,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   809
                    "is_internal": tagging_info.tag.is_internal()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   810
                })
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   811
            else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   812
                tag_link = tagging_info.tag.link
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   813
                # import label from external
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   814
                externaL_repos_fetch_dict = {
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   815
                    "http://dbpedia.org/": fetch_from_dbpedia,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   816
                    "http://fr.dbpedia.org/": fetch_from_dbpedia
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   817
                }
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   818
                try:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   819
                    (source, fetch_label) = next(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   820
                        item for item in externaL_repos_fetch_dict.items() if tag_link.startswith(item[0]))
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   821
                    tag_label = fetch_label(tag_link, "fr", source)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   822
                    if not tag_label:  # Error happened and we got False as a fetch return
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   823
                        tag_label = tagging_info.tag.label
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   824
                    else:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   825
                        tagging_info.tag.label = tag_label
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   826
                        tagging_info.tag.save()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   827
                    final_list.append({
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   828
                        "tag_label": tag_label,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   829
                        "tag_link": tag_link,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   830
                        "accuracy": tagging_info.accuracy,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   831
                        "relevancy": tagging_info.relevancy,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   832
                        "is_internal": tagging_info.tag.is_internal()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   833
                    })
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   834
                except StopIteration:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   835
                    pass
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   836
        return json.dumps(final_list)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   837
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   838
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   839
class Tag(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   840
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   841
        Tag objects that are linked to revisions.
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   842
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   843
        Each tag is linked to a specific collection, this is important for internal tags
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   844
        so each collection can build its own vocabulary
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   845
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   846
    label = models.CharField(max_length=255, blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   847
    label_slug = models.SlugField(blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   848
    link = models.URLField(unique=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   849
    description = models.CharField(max_length=255, blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   850
    collection = models.ForeignKey('Collection', blank=True, null=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   851
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   852
    def is_internal(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   853
        return self.link.startswith(settings.INTERNAL_TAGS_URL)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   854
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   855
    def __str__(self):
514
accd1fded1a5 Improve homepage.
Alexandre Segura <mex.zktk@gmail.com>
parents: 507
diff changeset
   856
        return "Tag:" + str(self.label)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   857
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   858
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   859
class TaggingInfo(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   860
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   861
        M2M object for managing tag relation to a revision with its associated
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   862
        relevancy and accuracy
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   863
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   864
    revision = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   865
        'AnnotationRevision', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   866
    tag = models.ForeignKey('Tag', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   867
    accuracy = models.IntegerField()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   868
    relevancy = models.IntegerField()
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   869
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   870
    def __str__(self):
323
55c024fc7c60 Roughly implement annotation navigator.
Alexandre Segura <mex.zktk@gmail.com>
parents: 299
diff changeset
   871
        return str(str(self.tag.label) + ":to:" + str(self.revision.revision_guid))
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   872
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   873
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   874
class IconolabComment(XtdComment):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   875
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   876
        Comment objects that extends XtdComment model, itself extending the
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   877
        django-contrib-comments model.
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   878
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   879
        Each comment can have 0 or 1 revision, if it is a comment created alongside a revision
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   880
        Each comment can have a set of metacategories
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   881
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   882
    revision = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   883
        'AnnotationRevision', related_name='creation_comment', null=True, blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   884
    metacategories = models.ManyToManyField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   885
        'MetaCategory', through='MetaCategoryInfo', through_fields=('comment', 'metacategory'))
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   886
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   887
    objects = XtdComment.objects
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   888
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   889
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   890
        return str(self.id)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   891
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   892
    class Meta:
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   893
        ordering = ["thread_id", "id"]
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   894
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   895
    @property
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   896
    def annotation(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   897
        if self.content_type.app_label == "iconolab" and self.content_type.model == "annotation":
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   898
            return Annotation.objects.get(pk=self.object_pk)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   899
        return None
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   900
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   901
    def get_comment_page(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   902
        """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   903
            Shortcut function to get page for considered comment, with
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   904
            COMMENTS_PER_PAGE_DEFAULT comments per page, used for notifications links generation
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   905
        """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   906
        return (IconolabComment.objects.for_app_models("iconolab.annotation").filter(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   907
            object_pk=self.object_pk,
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   908
        ).filter(thread_id__gte=self.thread_id).filter(order__lte=self.order).count() + 1) // settings.COMMENTS_PER_PAGE_DEFAULT + 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   909
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   910
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   911
class MetaCategory(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   912
    """
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   913
        Metacategories are objects that can be linked to a comment to augment it
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   914
        with meaning (depending on the metacategories defined for a given collection)
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   915
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   916
        Metacategories can trigger notifications when they are linked to a given
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   917
        coment depending on their trigger_notifications property:
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   918
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   919
            - NONE : Notifies nobody
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   920
            - CONTRIBUTORS : Notifies contributors (revision owners) on target annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   921
            - COMMENTERS : Notifies commenters (contributors + comment owners) on target annotation
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   922
            - COLLECTION_ADMINS : Notifies collection admins
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   923
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   924
        Metacategories can be used to consider an annotation as "validated" if a
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   925
        certain agreement threshold is reached using their validation_value property
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   926
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   927
            - NEUTRAL : The metacategory doesn't affect the validation state
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   928
            - AGREEMENT : The metacategory can be used to validate the annotation
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   929
              when linked to a comment on said annotation
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   930
            - DISAGREEMENT : The metacategory can be used to unvalidate the annotation
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
   931
              when linked to a comment on said annotation
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   932
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   933
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   934
    NONE = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   935
    CONTRIBUTORS = 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   936
    COMMENTERS = 2
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   937
    COLLECTION_ADMINS = 3
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   938
    NOTIFIED_USERS = (
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   939
        (NONE, 'none'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   940
        (CONTRIBUTORS, 'contributors'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   941
        (COMMENTERS, 'commenters'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   942
        (COLLECTION_ADMINS, 'collection admins'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   943
    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   944
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   945
    NEUTRAL = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   946
    AGREEMENT = 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   947
    DISAGREEMENT = 2
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   948
    VALIDATION_VALUES = (
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   949
        (NEUTRAL, 'neutral'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   950
        (AGREEMENT, 'agreement'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   951
        (DISAGREEMENT, 'disagreement'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   952
    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   953
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   954
    collection = models.ForeignKey(Collection, related_name="metacategories")
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   955
    label = models.CharField(max_length=255)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   956
    triggers_notifications = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   957
        choices=NOTIFIED_USERS, default=NONE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   958
    validation_value = models.IntegerField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   959
        choices=VALIDATION_VALUES, default=NEUTRAL)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   960
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   961
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   962
        return self.label + ":" + self.collection.name
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   963
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   964
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   965
class MetaCategoryInfo(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   966
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   967
        M2M class linking comments and metacategories
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   968
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   969
    comment = models.ForeignKey('IconolabComment', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   970
    metacategory = models.ForeignKey('MetaCategory', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   971
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   972
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   973
        return "metacategory:" + self.metacategory.label + ":on:" + self.comment.id
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   974
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   975
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   976
class CommentAttachement(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   977
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   978
        This class is supposed to represent added resources to a given comment
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   979
        Not implemented as of v0.0.19
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   980
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   981
    LINK = 0
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   982
    IMAGE = 1
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   983
    PDF = 2
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   984
    COMMENT_CHOICES = (
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   985
        (LINK, 'link'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   986
        (IMAGE, 'image'),
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   987
        (PDF, 'pdf')
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   988
    )
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   989
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   990
    comment = models.ForeignKey(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   991
        'IconolabComment', related_name='attachments', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   992
    attachment_type = models.IntegerField(choices=COMMENT_CHOICES, default=0)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   993
    data = models.TextField(blank=False)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   994
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   995
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   996
class UserProfile(models.Model):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   997
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   998
        UserProfile objects are extensions of user model
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
   999
299
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
  1000
        As of v0.0.19 they are used to define collection admins. Each user can
fb07469bfb55 correct js compilation
ymh <ymh.work@gmail.com>
parents: 298
diff changeset
  1001
        thus managed 0-N collections.
298
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1002
    """
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1003
    user = models.OneToOneField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1004
        User, related_name='profile', on_delete=models.CASCADE)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1005
    managed_collections = models.ManyToManyField(
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1006
        'Collection', related_name='admins', blank=True)
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1007
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1008
    def __str__(self):
97b805fc88f0 force unix line ending
ymh <ymh.work@gmail.com>
parents: 288
diff changeset
  1009
        return "profile:" + self.user.username
506
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1010
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1011
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1012
class BookmarkCategory(models.Model):
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1013
    user = models.ForeignKey(User)
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1014
    name = models.CharField(max_length=255)
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1015
    created = models.DateTimeField(auto_now_add=True)
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1016
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1017
class Bookmark(models.Model):
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1018
    category = models.ForeignKey(BookmarkCategory)
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1019
    image = models.ForeignKey(Image)
4e18e1f69db9 Introduce bookmarks feature.
Alexandre Segura <mex.zktk@gmail.com>
parents: 484
diff changeset
  1020
    created = models.DateTimeField(auto_now_add=True)