source: publico/colab/trunk/colab/super_archives/models.py @ 6126

Última Alteração nesse arquivo desde 6126 foi 6126, incluída por seocam, 8 anos atrás

Merge com a ultima versao do bitcket: https://bitbucket.org/seocam/atu-colab/src/4ee3ca57614e

File size: 8.1 KB
Linha 
1# -*- coding: utf-8 -*-
2
3import datetime
4from hashlib import md5
5
6from django.db import models
7from django.conf import settings
8from django.contrib.auth.models import User
9from django.core.urlresolvers import reverse, NoReverseMatch
10
11
12class NotSpamManager(models.Manager):
13    """Only return objects which are not marked as spam."""
14
15    def get_query_set(self):
16        return super(NotSpamManager, self).get_query_set().exclude(spam=True)
17
18
19class PageHit(models.Model):
20    url_path = models.CharField(max_length=2048, unique=True, db_index=True)
21    hit_count = models.IntegerField(default=0)
22
23
24class EmailAddress(models.Model):
25    user = models.ForeignKey(User, null=True, related_name='emails')
26    address = models.EmailField(unique=True)
27    real_name = models.CharField(max_length=64, blank=True, db_index=True)
28    md5 = models.CharField(max_length=32, null=True)
29       
30    def save(self, *args, **kwargs):
31        self.md5 = md5(self.address).hexdigest()
32        super(EmailAddress, self).save(*args, **kwargs)
33       
34    def get_full_name(self):
35        if self.user and self.user.get_full_name():
36            return self.user.get_full_name()
37        elif self.user and self.username:
38            return self.username
39        elif self.real_name:
40            return self.real_name
41           
42    def get_profile_link(self):
43        if self.user:
44            return reverse('user_profile', args=[self.user.username])
45        else:
46            return reverse('colab.views.userprofile.by_emailhash',
47                           args=[self.md5])
48
49    def __unicode__(self):
50        return '"%s" <%s>' % (self.get_full_name(), self.address)
51
52
53class UserProfile(models.Model):
54    user = models.OneToOneField(User, unique=True)
55    institution = models.CharField(max_length=128, null=True)
56    role = models.CharField(max_length=128, null=True)
57    twitter = models.CharField(max_length=128, null=True)
58    facebook = models.CharField(max_length=128, null=True)
59    google_talk = models.EmailField(null=True)
60    webpage = models.CharField(max_length=256)
61    verification_hash = models.CharField(max_length=32, null=True)
62
63    def __unicode__(self):
64        return '%s (%s)' % (self.user.get_full_name(), self.user.username)
65
66# This does the same the same than related_name argument but it also creates
67#   a profile in the case it doesn't exist yet.
68User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
69
70
71class MailingList(models.Model):
72    name = models.CharField(max_length=80)
73    email = models.EmailField()
74    description = models.TextField()
75    logo = models.FileField(upload_to='list_logo') #TODO
76    last_imported_index = models.IntegerField(default=0)
77
78    def __unicode__(self):
79        return self.name
80
81
82class MailingListMembership(models.Model):
83    user = models.ForeignKey(User)
84    mailinglist = models.ForeignKey(MailingList)
85
86    def __unicode__(self):
87        return '%s on %s' % (self.user.username, self.mailinglist.name)
88
89
90class Thread(models.Model):
91    class Meta:
92        unique_together = ('subject_token', 'mailinglist')
93   
94    subject_token = models.CharField(max_length=512)
95    mailinglist = models.ForeignKey(MailingList)
96    latest_message = models.OneToOneField('Message', null=True,
97                                                     related_name='+')
98    score = models.IntegerField(default=0)
99    spam = models.BooleanField(default=False)
100   
101    all_objects = models.Manager()
102    objects = NotSpamManager()
103
104    def __unicode__(self):
105        return '%s - %s (%s)' % (self.id,
106                                 self.subject_token,
107                                 self.message_set.count())
108
109    def update_score(self):
110        """Update the relevance score for this thread.
111       
112        The score is calculated with the following variables:
113
114        * vote_weight: 100 - (minus) 1 for each 3 days since
115          voted with minimum of 5.
116        * replies_weight: 300 - (minus) 1 for each 3 days since
117          replied with minimum of 5.
118        * page_view_weight: 10.
119
120        * vote_score: sum(vote_weight)
121        * replies_score: sum(replies_weight)
122        * page_view_score: sum(page_view_weight)
123
124        * score = (vote_score + replies_score + page_view_score) // 10
125        with minimum of 0 and maximum of 5000
126
127        """
128
129        if not self.subject_token:
130            return   
131 
132        # Save this pseudo now to avoid calling the
133        #   function N times in the loops below
134        now = datetime.datetime.now()
135        days_ago = lambda date: (now - date).days
136        get_score = lambda weight, created: \
137                                  max(weight - (days_ago(created) // 3), 5)
138
139        vote_score = 0
140        replies_score = 0
141        for msg in self.message_set.all():
142            # Calculate replies_score
143            replies_score += get_score(300, msg.received_time)
144
145            # Calculate vote_score
146            for vote in msg.vote_set.all():
147                vote_score += get_score(100, vote.created)
148
149        # Calculate page_view_score       
150        try:
151            url = reverse('thread_view', args=[self.mailinglist.name,
152                                               self.subject_token])
153            pagehit = PageHit.objects.get(url_path=url)
154            page_view_score = pagehit.hit_count * 10
155        except (NoReverseMatch, PageHit.DoesNotExist):
156            page_view_score = 0
157
158        self.score = (page_view_score + vote_score + replies_score) // 10
159        self.save()
160
161
162class Vote(models.Model):
163    user = models.ForeignKey(User)
164    message = models.ForeignKey('Message')
165    created = models.DateTimeField(auto_now_add=True)
166
167    class Meta:
168        unique_together = ('user', 'message')
169
170    def __unicode__(self):
171        return 'Vote on %s by %s' % (self.Message.id,
172                                     self.user.username)
173
174
175class Message(models.Model):
176   
177    from_address = models.ForeignKey(EmailAddress, db_index=True)
178    mailinglist = models.ForeignKey(MailingList)
179    thread = models.ForeignKey(Thread, null=True, db_index=True)
180    # RFC 2822 recommends to use 78 chars + CRLF (so 80 chars) for
181    #   the max_length of a subject but most of implementations
182    #   goes for 256. We use 512 just in case.
183    subject = models.CharField(max_length=512, db_index=True)
184    subject_clean = models.CharField(max_length=512, db_index=True)
185    body = models.TextField(default='')
186    received_time = models.DateTimeField()
187    message_id = models.CharField(max_length=512)
188    spam = models.BooleanField(default=False)
189
190    all_objects = models.Manager()
191    objects = NotSpamManager()
192   
193    def __unicode__(self):
194        return '(%s) %s: %s' % (self.id,
195                                self.from_address.get_full_name(),
196                                self.subject_clean)
197       
198    def vote_list(self):
199        """Return a list of user that voted in this message."""
200       
201        return [vote.user for vote in self.vote_set.all()]       
202 
203    def votes_count(self):
204        return len(self.vote_list())
205       
206    def vote(self, user):
207        Vote.objects.create(
208            message=self,
209            user=user
210        )
211       
212    def unvote(self, user):
213        Vote.objects.get(
214            message=self,
215            user=user
216        ).delete()
217
218    @property
219    def url(self):
220        """Shortcut to get thread url"""
221        return reverse('thread_view', args=[self.mailinglist.name,
222                                            self.thread.subject_token])
223   
224    @property
225    def Description(self):
226        """Alias to self.body"""
227        return self.body
228
229    @property
230    def Title(self):
231        """Alias to self.subject_clean"""
232        return self.subject_clean
233
234    @property
235    def modified(self):
236        """Alias to self.modified"""
237        return self.received_time
238
239
240class MessageMetadata(models.Model):
241    Message = models.ForeignKey(Message)
242    # Same problem here than on subjects. Read comment above
243    #   on Message.subject
244    name = models.CharField(max_length=512)
245    value = models.TextField()
246
247    def __unicode__(self):
248        return 'Email Message Id: %s - %s: %s' % (self.Message.id,
249                                                  self.name, self.value)
250   
Note: Veja TracBrowser para ajuda no uso do navegador do trac.
 

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.