move css rules to css file
[qcg-portal.git] / qcg / utils.py
1 from django.core.paginator import Paginator
2 from django.db import transaction
3 from django.utils.formats import date_format
4 from django.utils.timezone import now, localtime
5 from pyqcg.service import Registry
6 from pyqcg.utils import Credential, TimePeriod
7
8 from qcg import constants
9
10
11 def get_attributes(obj, attrs):
12     return {name: getattr(obj, name) for name in attrs if getattr(obj, name) is not None}
13
14
15 def username_from_dn(dn):
16     _, username = dn.rsplit('=', 1)
17
18     return username
19
20
21 @transaction.atomic
22 def update_user_data(user, proxy):
23     from qcg.models import User, Job, Task, Allocation, NodeInfo
24
25     credential = Credential(proxy)
26     registry = Registry(credential)
27
28     # put lock on user record (hopefully..?)
29     user = User.objects.select_for_update().get(pk=user.pk)
30
31     changed_filter = {'changed': TimePeriod(after=user.last_update)}
32
33     ###################################
34     # Jobs
35     ###################################
36     for qcg_job in registry.jobs(**changed_filter):
37         params = Job.qcg_map(qcg_job, user)
38         job_id = params.pop('job_id')
39
40         Job.objects.update_or_create(job_id=job_id, defaults=params)
41
42     ###################################
43     # Tasks
44     ###################################
45     jobs_cache = {j.job_id: j for j in Job.objects.filter(owner=user)}
46     for qcg_task in registry.tasks(**changed_filter):
47         params = Task.qcg_map(qcg_task, jobs_cache)
48         task_id = params.pop('task_id')
49
50         task, created = Task.objects.update_or_create(job__job_id=qcg_task.job_id, task_id=task_id, defaults=params)
51
52         if not created:
53             task.allocations.all().delete()
54
55         for qcg_alloc in qcg_task.allocations:
56             alloc = task.allocations.create(**Allocation.qcg_map(qcg_alloc))
57
58             for qcg_node in qcg_alloc.nodes:
59                 alloc.nodes.create(**NodeInfo.qcg_map(qcg_node))
60
61     # release user lock
62     user.last_update = now()
63     user.save()
64
65
66 def try_parse_int(s, default=None, base=10):
67     try:
68         return int(s, base)
69     except (TypeError, ValueError):
70         return default
71
72
73 def paginator_context(request, objects, per_page=constants.PER_PAGE):
74     paginator = Paginator(objects, per_page)
75
76     page_num = try_parse_int(request.GET.get('page'), 1)
77     if not (1 <= page_num <= paginator.num_pages):
78         page_num = 1
79
80     pages_range = range(max(2, min(page_num - 2, paginator.num_pages - 4)),
81                         min(max(page_num + 2, 5), paginator.num_pages) + 1)
82
83     return {'page': paginator.page(page_num), 'num_pages': paginator.num_pages, 'pages_range': pages_range}
84
85
86 def localtime_str(datetime):
87     return date_format(localtime(datetime), 'DATETIME_FORMAT')