Fakultas Ilmu Komputer UI

models.py 9.88 KB
Newer Older
Saul Andre's avatar
Saul Andre committed
1
import random
2
import datetime
3

4
from django.contrib.postgres import search
5
from django.core.exceptions import ValidationError
6
from django.core.validators import MinValueValidator, MaxValueValidator
7
from django.db import models
8
from django.utils import timezone
9

igor lestin sianipar's avatar
igor lestin sianipar committed
10
11
12
from authentication.models import User

VERIFICATION_STATUS = [
13
14
    ("PENDING", "Diproses"),
    ("APPROVE", "Diterima"),
15
    ("DISAPPROVE", "Ditolak"),
16
    ("REVISION", "Perbaikan"),
17
    ("BLOCKED", "Diblokir"),
igor lestin sianipar's avatar
igor lestin sianipar committed
18
]
Samuel Dimas's avatar
Samuel Dimas committed
19

20

Samuel Dimas's avatar
Samuel Dimas committed
21
# Create your models here.
22
23


Saul Andre's avatar
Saul Andre committed
24
25
def getRandomColor():
    color = "%06x" % random.randint(0, 0xFFFFFF)
26
27
    return color

28
29
def current_year():
    return datetime.date.today().year
Saul Andre's avatar
Saul Andre committed
30
31
32

class Category(models.Model):
    name = models.CharField(max_length=20)
33
34
    description = models.TextField(blank=False, default="")
    archived = models.BooleanField(default=False, blank=False)
35
    archived_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
Saul Andre's avatar
Saul Andre committed
36
37
38
39

    def __str__(self):
        return self.name

40

41
class MateriManager(models.Manager):
42
43
44
45
46
47
48
49
    def __init__(self, *args, **kwargs):
        self.alive_only = kwargs.pop('alive_only', True)
        super(MateriManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        if self.alive_only:
            return SoftDeletionQuerySet(self.model).filter(deleted_at=None)
        return SoftDeletionQuerySet(self.model)
50

51
52
53
54
55
56
57
58
59
60
61
62
    def search(self, search_text):
        search_vector = search.SearchVector("title", weight="A")
        search_query = search.SearchQuery(search_text)

        search_rank = search.SearchRank(search_vector, search_query)

        search_result = (
            self.get_queryset().filter(_search_vector=search_query).annotate(rank=search_rank).order_by("-rank")
        )

        return search_result

63
64
65
class SoftDeletionQuerySet(models.query.QuerySet):
    def delete(self):
        return super(SoftDeletionQuerySet, self).update(deleted_at=timezone.now())
66

67
68
69
70
class SoftDeleteModel(models.Model):
    deleted_at = models.DateTimeField(blank=True, null=True)

    all_objects = MateriManager(alive_only=False)
71

72
73
    class Meta:
        abstract = True
74

75
76
77
78
79
    def soft_delete(self):
        self.deleted_at = timezone.now()
        self.save()

class Materi(SoftDeleteModel):
igor lestin sianipar's avatar
igor lestin sianipar committed
80
81
    cover = models.ImageField()
    content = models.FileField()
82
83
    title = models.CharField(max_length=50, default="Judul")
    author = models.CharField(max_length=30, default="Penyusun")
igor lestin sianipar's avatar
igor lestin sianipar committed
84
    uploader = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
85
    publisher = models.CharField(max_length=30, default="Penerbit")
86
    release_year = models.IntegerField(default=current_year)
Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
87
    pages = models.IntegerField(default=0)
88
    descriptions = models.TextField(default="Deskripsi")
89
    status = models.CharField(max_length=30, choices=VERIFICATION_STATUS, default=VERIFICATION_STATUS[0][0])
Saul Andre's avatar
Saul Andre committed
90
    categories = models.ManyToManyField(Category)
91
92
    date_created = models.DateTimeField(default=timezone.now)
    date_modified = models.DateTimeField(auto_now=True)
93
    yt_video_id = models.CharField(max_length=100, blank=True, null=True)
94

95
96
97
98
99
100
101
102
103
104
105
    _search_vector = search.SearchVectorField(null=True, editable=False)

    objects = MateriManager()

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

        if "update_fields" not in kwargs or "_search_vector" not in kwargs["update_fields"]:
            self._search_vector = search.SearchVector("title", weight="A")
            self.save(update_fields=["_search_vector"])

106
107
108
109
    @property
    def is_published(self):
        published = False
        if self.verificationreport_set.exists():
110
111
            report = self.verificationreport_set.latest("timestamp")
            published = True if report.status == "Diterima" else False
112
113
114
115
116
117
        return published

    @property
    def published_date(self):
        published_date = None
        if self.verificationreport_set.exists():
118
119
            report = self.verificationreport_set.latest("timestamp")
            if report.status == "Diterima":
120
121
                published_date = report.timestamp
        return published_date
122

123
124
125
126
    @property
    def like_count(self):
        count = Like.objects.filter(materi=self).count()
        return count
127

128
129
130
131
    @property
    def comment_count(self):
        count = Comment.objects.filter(materi=self).count()
        return count
132

133
134
135
136
137
    @property
    def review_count(self):
        count = Review.objects.filter(materi=self).count()
        return count

138
139
140
141
142
143
    @property
    def is_like(self):
        like = False
        if Like.objects.filter(materi=self).exists():
            like = True

144

145
class Comment(models.Model):
146
147
    username = models.CharField(max_length=100)
    profile = models.CharField(max_length=100, default=getRandomColor)
148
    comment = models.CharField(max_length=240, default="comments")
149
    materi = models.ForeignKey(Materi, models.SET_NULL, null=True)
150
    user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
151
    timestamp = models.DateTimeField(default=timezone.now)
152
153

    def __str__(self):
154
        return self.username
155

156
157
158
159
    @property
    def like_count(self):
        count = LikeComment.objects.filter(comment=self).count()
        return count
160

161
162
163
164
165
    @property
    def dislike_count(self):
        count = DislikeComment.objects.filter(comment=self).count()
        return count

166
167
168
169
170
171
172
173
174
175
176
class Review(models.Model):
    username = models.CharField(max_length=100)
    profile = models.CharField(max_length=100, default=getRandomColor)
    review = models.TextField(default="review")
    materi = models.ForeignKey(Materi, models.SET_NULL, null=True)
    user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
    timestamp = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.username

177
178
179
180
181
182
183
184
185
186
187
188

class LikeComment(models.Model):
    comment = models.ForeignKey(Comment, models.SET_NULL, null=True)
    timestamp = models.DateTimeField(default=timezone.now)
    session_id = models.CharField(max_length=32, blank=False)


class DislikeComment(models.Model):
    comment = models.ForeignKey(Comment, models.SET_NULL, null=True)
    timestamp = models.DateTimeField(default=timezone.now)
    session_id = models.CharField(max_length=32, blank=False)

189
190
191
192
193
194

class Like(models.Model):
    materi = models.ForeignKey(Materi, models.SET_NULL, null=True)
    timestamp = models.DateTimeField(default=timezone.now)
    session_id = models.CharField(max_length=32, blank=False)

195

196
197
198
199
class ReqMaterial(models.Model):
    title = models.CharField(max_length=100)
    timestamp = models.DateTimeField(default=timezone.now)

insan ramadhan's avatar
insan ramadhan committed
200
201
202
203
204
205
class SubmitVisitor(models.Model):
    user_id = models.CharField(max_length=50)
    email = models.CharField(max_length=50)
    msg = models.CharField(max_length=100)
    timestamp = models.DateTimeField(default=timezone.now)

206
207

class ViewStatistics(models.Model):
208
    materi = models.ForeignKey(Materi, models.SET_NULL, null=True, related_name="baca")
209
210
211
212
    timestamp = models.DateTimeField(default=timezone.now)


class DownloadStatistics(models.Model):
213
214
    materi = models.ForeignKey(Materi, models.SET_NULL, null=True, related_name="unduh")
    downloader = models.ForeignKey(User, models.SET_NULL, blank=True, null=True, related_name="riwayat_unduh")
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    timestamp = models.DateTimeField(default=timezone.now)


class DummyLike(models.Model):
    item = models.ForeignKey(Like, on_delete=models.CASCADE)


class DummyViewStatistics(models.Model):
    item = models.ForeignKey(ViewStatistics, on_delete=models.CASCADE)


class DummyDownloadStatistics(models.Model):
    item = models.ForeignKey(DownloadStatistics, on_delete=models.CASCADE)


class DummyComment(models.Model):
    item = models.ForeignKey(Comment, on_delete=models.CASCADE)
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


class Rating(models.Model):
    materi = models.ForeignKey(Materi, models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
    timestamp = models.DateTimeField(default=timezone.now)
    score = models.IntegerField()

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if 1 <= self.score <= 5:
            super().save(force_insert, force_update, using, update_fields)
        else:
            raise ValidationError("Rating score must be integer between 1-5")

    def __str__(self):
        return "Material:{} | User:{} | Rating:{}".format(self.materi.title, self.user.name, self.score)

    class Meta:
        unique_together = ["materi", "user"]
251
252
253
254
255


class RatingContributor(models.Model):
    timestamp = models.DateTimeField(auto_now=True)
    score = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
256
257
    contributor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contributor')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
258
259
260
261
262

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if 1 <= self.score <= 5:
            super().save(force_insert, force_update, using, update_fields)
        else:
263
            raise ValidationError("Rating score must be integer between 1-5")
264
265
266
    
    class Meta:
        unique_together = ["contributor", "user"]
267

268
269
270
271
272
273
274
275
276
277
278
279
280
class SubscribeModel(models.Model):
    sys_id = models.AutoField(primary_key=True, null=False, blank=True)
    email = models.EmailField(null=False, blank=True, max_length=200, unique=True)
    status = models.CharField(max_length=64, null=False, blank=True)
    created_date = models.DateTimeField(null=False, blank=True)
    updated_date = models.DateTimeField(null=False, blank=True)

    class Meta:
        app_label = "app"
        db_table = "app_subscribe"

    def __str__(self):
        return self.email
281

282
283
284
285
286
class LaporanMateri(models.Model):
    materi = models.ForeignKey(Materi, on_delete=models.CASCADE, max_length=120)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    laporan = models.TextField(validators=[MinValueValidator(30), MaxValueValidator(120)], default="")
    timestamp = models.DateTimeField(default=timezone.now)
287
    is_rejected = models.BooleanField(default=False)