Completed
Push — master ( 856bc1...ee6984 )
by Fox
40s
created

Digest   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 24
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
rs 10
wmc 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A show() 0 8 1
A __str__() 0 4 1
1
# coding: utf-8
2
import arrow
3
4
from django.conf import settings
5
from django.contrib.auth.models import User
6
from django.core.exceptions import ObjectDoesNotExist
7
from django.db import models
8
from django.db.models.signals import post_save
9
from django.dispatch import receiver
10
from django.utils.timezone import now
11
from django.utils.translation import ugettext_lazy as _
12
13
from logging import getLogger
14
15
from django_th.signals import digest_event
16
from django_th.tools import warn_user_and_admin
17
18
logger = getLogger('django_th.trigger_happy')
19
20
21
class ServicesActivated(models.Model):
22
23
    """
24
        Services Activated from the admin
25
    """
26
    name = models.CharField(max_length=200, unique=True)
27
    status = models.BooleanField(default=False)
28
    auth_required = models.BooleanField(default=True)
29
    self_hosted = models.BooleanField(default=False)
30
    description = models.CharField(max_length=200)
31
32
    class Meta:
33
        verbose_name = 'Services'
34
        verbose_name_plural = 'Services'
35
36
    def show(self):
37
        """
38
39
        :return: string representing object
40
        """
41
        return "Service Activated %s %s %s %s" % (self.name, self.status,
42
                                                  self.auth_required,
43
                                                  self.description)
44
45
    def __str__(self):
46
        return self.name
47
48
49
class UserService(models.Model):
50
51
    """
52
        UserService a model to link service and user
53
    """
54
    DAY = 'd'
55
    WEEK = 'w'
56
    MONTH = 'm'
57
    NONE = 'n'
58
    DURATION = (
59
        (DAY, _('Day')),
60
        (WEEK, _('Week')),
61
        (MONTH, _('Month')),
62
        (NONE, _('None'))
63
    )
64
65
    user = models.ForeignKey(User)
66
    token = models.CharField(max_length=255, blank=True)
67
    name = models.ForeignKey(
68
        ServicesActivated, to_field='name', related_name='+')
69
    username = models.CharField(
70
        _('username'), max_length=255, default='', blank=True)
71
    password = models.CharField(
72
        _('password'), max_length=128, default='', blank=True)
73
    host = models.CharField(_('host'), max_length=255, default='', blank=True)
74
    client_id = models.CharField(
75
        _('client id'), max_length=255, default='', blank=True)
76
    client_secret = models.CharField(
77
        _('client secret'), max_length=255, default='', blank=True)
78
    duration = models.CharField(max_length=1, choices=DURATION, default=NONE)
79
80
    def show(self):
81
        """
82
83
        :return: string representing object
84
        """
85
        return "User Service %s %s %s" % (self.user, self.token, self.name)
86
87
    def __str__(self):
88
        return self.name.name
89
90
91
class TriggerService(models.Model):
92
93
    """
94
        TriggerService
95
    """
96
    provider = models.ForeignKey(UserService, related_name='+', blank=True)
97
    consumer = models.ForeignKey(UserService, related_name='+', blank=True)
98
    description = models.CharField(max_length=200)
99
    user = models.ForeignKey(User)
100
    date_created = models.DateField(auto_now_add=True)
101
    date_triggered = models.DateTimeField(null=True)
102
    status = models.BooleanField(default=False)
103
    result = models.CharField(max_length=255, default='')
104
    date_result = models.DateTimeField(auto_now=True, null=True)
105
    provider_failed = models.IntegerField(db_index=True, default=0)
106
    consumer_failed = models.IntegerField(db_index=True, default=0)
107
108
    def show(self):
109
        """
110
111
        :return: string representing object
112
        """
113
        return "My Service %s - %s - %s - %s" % (self.user,
114
                                                 self.provider.name,
115
                                                 self.consumer.name,
116
                                                 self.description)
117
118
    def __str__(self):
119
        return "%s - %s - %s - %s" % (self.user,
120
                                      self.provider.name,
121
                                      self.consumer.name,
122
                                      self.description)
123
124
125
class Digest(models.Model):
126
    """
127
    Digest service to store the data from other service
128
    """
129
    user = models.ForeignKey(User)
130
    title = models.CharField(max_length=600)
131
    link = models.URLField()
132
    duration = models.CharField(max_length=1)
133
    date_end = models.DateField()
134
    provider = models.CharField(max_length=40)
135
136
    def show(self):
137
        """
138
139
        :return: string representing object
140
        """
141
        return "Digest %s - %s - %s - %s - %s - %s" % (
142
            self.user, self.provider, self.title, self.link, self.duration,
143
            self.date_end)
144
145
    def __str__(self):
146
        return "%s - %s - %s - %s - %s - %s" % (
147
            self.user, self.provider, self.title, self.link, self.duration,
148
            self.date_end)
149
150
151
def update_result(trigger_id, msg, status):
152
    """
153
    :param trigger_id: trigger id
154
    :param msg: result msg
155
    :param status: status of the handling of the current trigger
156
    :return:
157
    """
158
    # if status is True, reset *_failed counter
159
    if status:
160
        TriggerService.objects.filter(id=trigger_id).update(result=msg,
161
                                                            date_result=now(),
162
                                                            provider_failed=0,
163
                                                            consumer_failed=0)
164
    # otherwise, add 1 to the consumer_failed
165
    else:
166
        service = TriggerService.objects.get(id=trigger_id)
167
        failed = service.consumer_failed + 1
168
        if failed > settings.DJANGO_TH.get('failed_tries', 5):
169
            TriggerService.objects.filter(id=trigger_id).\
170
                update(result=msg, date_result=now(), status=False)
171
        else:
172
            TriggerService.objects.filter(id=trigger_id).\
173
                update(result=msg, date_result=now(), consumer_failed=failed)
174
175
        warn_user_and_admin('consumer', service)
176
177
178
def th_create_user_profile(sender, instance, created, **kwargs):
179
    # create the default service that does not
180
    # need any third party auth
181
    user = instance
182
    if user.last_login is None:
183
        services = ('ServiceRss', 'ServicePelican', )
184
        for service in services:
185
            if any(service in s for s in settings.TH_SERVICES):
186
                try:
187
                    sa = ServicesActivated.objects.get(name=service)
188
                    UserService.objects.get_or_create(user=user, name=sa)
189
                except ObjectDoesNotExist:
190
                    logger.debug("A new user %s has been connected but %s "
191
                                 "could not be added to his services because "
192
                                 "the service is present in TH_SERVICES but not"
193
                                 " activated from the Admin Panel" %
194
                                 (user, service))
195
196
197
post_save.connect(th_create_user_profile, sender=User,
198
                  dispatch_uid="create_user_profile")
199
200
201
@receiver(digest_event)
202
def digest_save(sender, **kwargs):
203
    """
204
205
    :param sender:
206
    :param kwargs:
207
    :return:
208
    """
209
    # set the deadline of the publication of the digest data
210
    duration = kwargs.get('duration')
211
    if duration not in ('d', 'w', 'm'):
212
        return
213
    # get the current date
214
    now = arrow.utcnow().to(settings.TIME_ZONE)
215
216
    # set the deadline
217
    if duration == 'd':
218
        # set tomorrow
219
        tomorrow = now.shift(days=+1)
220
        date_end = tomorrow.date()  # noqa extrat the date part
221
    elif duration == 'w':
222
        # set next week
223
        next_week = now.shift(weeks=+1)
224
        date_end = next_week.date()
225
    else:
226
        # set next month
227
        next_month = now.shift(months=+1)
228
        date_end = next_month.date()
229
230
    Digest.objects.create(user=kwargs.get('user'),
231
                          title=kwargs.get('title'),
232
                          link=kwargs.get('link'),
233
                          duration=duration,
234
                          date_end=str(date_end),
235
                          provider=sender)
236