· 6 years ago · Dec 04, 2019, 05:00 PM
1import lime_webserver.webserver as webserver
2import logging
3import pytz
4import pendulum
5from ..endpoints import api
6from datetime import datetime, timedelta
7from lime_query import execute_query
8from lime_type.limetypes import FileProperty
9
10logger = logging.getLogger(__name__)
11
12
13class Error(Exception):
14 """Base class for other exceptions"""
15 pass
16
17
18class IntervalError(Error):
19 """Raised when invalid intervall"""
20 pass
21
22
23class Scheduling(webserver.LimeResource):
24 """ Endpoint responsible for creating scheduled helpdesks
25 """
26
27 def get(self):
28 app = self.application
29
30 # schedule runs only monday to friday
31 today = datetime.today()
32 # today = datetime(2019, 12, 26, 17, 51)
33 weekdays = range(0, 5)
34 helpdesks = []
35
36 if today.weekday() in weekdays:
37 # create unit of work
38 uow = app.unit_of_work()
39
40 # get available scheduling intervals
41 intervals = app.limetypes.scheduling.get_property('interval')
42
43 # run scheduling for all available intervals
44 for option in intervals.options:
45 if option.text != '':
46 new_helpdesks = self._run(app=app,
47 uow=uow,
48 interval=option.key,
49 date=today)
50 helpdesks.append(new_helpdesks)
51 uow.commit()
52
53 return str(helpdesks)
54
55 def _run(self, app, uow, interval, date):
56 schedules = self._get_schedules(app=app, interval=interval, date=date)
57 schedule_objects = schedules['objects']
58
59 # import pdb; pdb.set_trace()
60 helpdesks = []
61 for o in schedule_objects:
62 # get original deal to copy from
63 original_helpdesk = self._get_helpdesk(app=app,
64 helpdeskno=o['scheduleid'])
65
66 if original_helpdesk:
67 # check if copy exists
68 exists = self._copy_exists(app=app,
69 scheduleid=o['scheduleid'],
70 interval=interval,
71 repeat=o['repeat'],
72 today=date)
73
74 if not exists:
75 # copy original deal
76 new_helpdesk = self._copy(app=app,
77 uow=uow,
78 limeobject=original_helpdesk)
79 # give copy scheduleid
80 new_helpdesk.properties.scheduleid.value = o['scheduleid']
81 # append and add
82 helpdesks.append(new_helpdesk)
83 uow.add(new_helpdesk)
84 # create history and attach to scheduling
85 self._create_history(app=app,
86 uow=uow,
87 o=o,
88 helpdesk=new_helpdesk)
89
90 return helpdesks
91
92 def _create_history(self, app, uow, o, helpdesk):
93 cmnt = app.limetypes.history.get_property('type').get_by_key('comment')
94 history = app.limetypes.history(
95 type=cmnt,
96 note='Ärende skapat via schemaläggning'
97 )
98 scheduling = app.limetypes.scheduling.get(o['_id'])
99 if scheduling:
100 history.properties.scheduling.attach(scheduling)
101 uow.add(scheduling)
102 if helpdesk:
103 history.properties.helpdesk.attach(helpdesk)
104 uow.add(helpdesk)
105 uow.add(history)
106
107 def _copy(self, app, uow, limeobject):
108 limetype = app.limetypes.get_limetype(limeobject.limetype.name)
109 new_object = limetype()
110
111 # copy properties
112 properties = limeobject.get_non_relational_properties()
113 for p in properties:
114 if not isinstance(p.lime_property, FileProperty) and \
115 not p.name == 'helpdeskno':
116 new_object.get_property(p.name).value = \
117 limeobject.get_property(p.name).value
118
119 # copy file properties
120 file_properties = limeobject.get_file_properties()
121 for f in file_properties:
122 related_file = limeobject.get_property(f.name).fetch()
123 if related_file:
124 new_object.get_property(f.name).attach(related_file)
125 uow.add(related_file)
126
127 # copy relations
128 relations = limeobject.get_relations()
129 existing_relations = [x for x in relations if x.value is not None]
130 for r in existing_relations:
131 related_object = limeobject.get_property(r.name).fetch()
132 if related_object:
133 new_object.get_property(r.name).attach(related_object)
134 uow.add(related_object)
135
136 return new_object
137
138 def _get_intervaldates(self, interval, repeat, today):
139 if interval == 'day':
140 end = today
141 begin = end - timedelta(days=repeat)
142 elif interval == 'week':
143 end = pendulum.naive(today.year,
144 today.month,
145 today.day,
146 today.hour,
147 today.minute,
148 today.second)
149 begin = end.subtract(weeks=repeat)
150 elif interval == 'month':
151 end = pendulum.naive(today.year,
152 today.month,
153 today.day,
154 today.hour,
155 today.minute,
156 today.second)
157 begin = end.subtract(months=repeat)
158 elif interval == 'year':
159 subtract_year = today.year - repeat
160 end = today
161 begin = datetime(subtract_year,
162 today.month,
163 today.day,
164 today.hour,
165 today.minute,
166 today.second)
167 else:
168 raise IntervalError('Invalid interval.')
169
170 # give dates timezone
171 utc = pytz.utc
172 begin = utc.localize(begin)
173 end = utc.localize(end)
174
175 return begin, end
176
177 def _copy_exists(self, app, interval, repeat, scheduleid, today):
178 # get interval dates first
179 try:
180 begin, end = self._get_intervaldates(interval=interval,
181 repeat=repeat,
182 today=today)
183 except IntervalError:
184 pass
185
186 query = {
187 'limetype': 'helpdesk',
188 'limit': 200,
189 'responseFormat': {
190 'object': {
191 '_id': None,
192 '_createdtime': None,
193 'title': None,
194 'helpdeskno': None,
195 'scheduleid': None
196 }
197 },
198 'filter': {
199 'op': 'AND',
200 'exp': [
201 {'op': '=', 'key': 'scheduleid', 'exp': scheduleid},
202 {'op': '<', 'key': '_createdtime', 'exp': end},
203 {'op': '>=', 'key': '_createdtime', 'exp': begin}
204 ]
205 }
206 }
207 response = execute_query(
208 query=query,
209 conn=app.database.connection,
210 limetypes=app.limetypes,
211 acl=app.acl,
212 user=app.user
213 )
214
215 exists = True
216 if len(response['objects']) == 0:
217 exists = False
218 else:
219 exists = True
220
221 return exists
222
223 def _get_helpdesk(self, app, helpdeskno):
224 query = {
225 'limetype': 'helpdesk',
226 'limit': 1,
227 'responseFormat': {
228 'object': {
229 '_id': None,
230 'title': None,
231 'helpdeskno': None
232 }
233 },
234 'filter': {
235 'op': 'AND',
236 'exp': [
237 {'op': '=', 'key': 'helpdeskno', 'exp': helpdeskno}
238 ]
239 }
240 }
241 response = execute_query(
242 query=query,
243 conn=app.database.connection,
244 limetypes=app.limetypes,
245 acl=app.acl,
246 user=app.user
247 )
248
249 try:
250 helpdesk = app.limetypes.helpdesk.get(response['objects'][0]['_id'])
251 return helpdesk
252
253 except IndexError:
254 print('There is no helpdesk with helpdesknumber ' + str(helpdeskno))
255
256 def _get_schedules(self, app, interval, date):
257 query = {
258 'limetype': 'scheduling',
259 'responseFormat': {
260 'object': {
261 '_id': None,
262 'scheduleid': None,
263 'repeat': None,
264 'start': None,
265 'end': None
266 }
267 },
268 'filter': {
269 'op': 'AND',
270 'exp': [
271 {'op': '=', 'key': 'interval', 'exp': interval},
272 {'op': '<', 'key': 'start', 'exp': date},
273 {'op': '>=', 'key': 'end', 'exp': date + timedelta(days=-1)}
274 ]
275 }
276 }
277 response = execute_query(
278 query=query,
279 conn=app.database.connection,
280 limetypes=app.limetypes,
281 acl=app.acl,
282 user=app.user
283 )
284
285 return response
286
287
288api.add_resource(Scheduling, '/scheduling/')