def process(self, data): """ denied by last_action_user_id send mail to user """ req = Request.by_id(self.session, data['req_id']) # retrieve user who performed last action action_user = User.by_id(self.session, req.last_action_user_id) # send mail to user src = action_user.email dst = req.user.email content = """You request has been refused for the following reason: %s Request details: %s""" % (req.reason, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err)) self.session.flush() transaction.commit()
def process(self, data): """send a trial reminder mail for a user to his admin""" user = User.by_id(self.session, data['user_id']) duration = data['duration'] conf = ConfCache() sender = conf.get('reminder', {}).get('sender', 'pyvac') # send mail to user country admin (HR) subject = 'Trial period reminder: %s' % user.name admin = user.get_admin(self.session) target = self.get_admin_mail(admin) content = """Hello, This is a reminder that %s trial period has been running for %d months. Arrival date: %s """ % (user.name, duration, user.arrival_date.strftime('%d/%m/%Y')) try: self.smtp.send_mail(sender, target, subject, content) data = {'user_id': user.id} parameters = json.dumps(OrderedDict(data)) rem = Reminder(type='trial_threshold', parameters=parameters) self.session.add(rem) self.session.flush() transaction.commit() except Exception: self.log.exception('Error while sending mail')
def render(self): user = User.by_id(self.session, int(self.request.matchdict['user_id'])) if self.user.has_no_role: # can only see own requests if user.id != self.user.id: return HTTPFound(location=route_url('list_request', self.request)) if self.user.is_manager: # can only see own requests and managed user requests if ((user.id != self.user.id) and (user.manager_id != self.user.id)): return HTTPFound(location=route_url('list_request', self.request)) today = datetime.now() year = int(self.request.params.get('year', today.year)) start = datetime(2014, 5, 1) years = [item for item in reversed(range(start.year, today.year + 1))] pool_history = User.get_rtt_history(self.session, user, year) return {'user': user, 'year': year, 'years': years, 'pool_history': pool_history}
def process(self, data): """ denied by last_action_user_id send mail to user """ req = Request.by_id(self.session, data['req_id']) # retrieve user who performed last action action_user = User.by_id(self.session, req.last_action_user_id) # send mail to user src = action_user.email dst = req.user.email content = """Your request has been refused for the following reason: %s Request details: %s""" % (req.reason, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err), self.session) self.session.flush() transaction.commit()
def get_target_user(self, logged_user): if self.user.is_admin: sudo_user_id = int(self.request.params.get('sudo_user')) if sudo_user_id != -1: user = User.by_id(self.session, sudo_user_id) if user: return user return logged_user
def test_post_delete_ok(self): from pyvac.views.account import Delete from pyvac.models import User view = Delete(self.create_request({'form.submitted': '1', }, matchdict={'user_id': self.account_id },))() self.assertIsRedirect(view) account = User.by_id(self.session, self.account_id) self.assertIsNone(account) self.account_todelete = []
def test_post_delete_ok(self): from pyvac.views.account import Delete from pyvac.models import User view = Delete( self.create_request( { 'form.submitted': '1', }, matchdict={'user_id': self.account_id}, ))() self.assertIsRedirect(view) account = User.by_id(self.session, self.account_id) self.assertIsNone(account) self.account_todelete = []
def test_post_edit_ok(self): from pyvac.views.account import Edit from pyvac.models import User view = Edit(self.create_request({'form.submitted': '1', 'user.login': u'dummy_edited', 'user.firstname': u'', 'user.lastname': u'', 'user.email': u'*****@*****.**', 'groups': [u'1'] }, matchdict={'user_id': self.account_id }))() self.assertIsRedirect(view) self.session.flush() user = User.by_id(self.session, self.account_id) self.assertEqual(user.login, u'dummy_edited') self.assertEqual([g.id for g in user.groups], [1])
def test_post_edit_ok(self): from pyvac.views.account import Edit from pyvac.models import User view = Edit( self.create_request( { 'form.submitted': '1', 'user.login': u'dummy_edited', 'user.firstname': u'', 'user.lastname': u'', 'user.email': u'*****@*****.**', 'groups': [u'1'] }, matchdict={'user_id': self.account_id}))() self.assertIsRedirect(view) self.session.flush() user = User.by_id(self.session, self.account_id) self.assertEqual(user.login, u'dummy_edited') self.assertEqual([g.id for g in user.groups], [1])
def render(self): if not self.user.is_sudoer(self.session): log.info("user '%s' tried to access sudo but is not authorized" % self.user.login) return HTTPFound(location=route_url("home", self.request)) req = self.request if req.method == "POST" and "continue" in req.params: headers = None target_id = int(req.params.get("sudo", self.user.id)) if target_id != self.user.id: target = User.by_id(self.session, target_id) if not target: errors = ["Cannot find user with id %d" % target_id] self.request.session.flash("error;%s" % ",".join(errors)) log.info("user '%s' will sudo to user '%s'" % (self.user.login, target.login)) headers = remember(self.request, target.login) return HTTPFound(location=route_url("home", self.request), headers=headers) return {"user": self.user}
def render(self): user = User.by_id(self.session, int(self.request.matchdict['user_id'])) if self.user.has_no_role: # can only see own requests if user.id != self.user.id: return HTTPFound( location=route_url('list_request', self.request)) if self.user.is_manager: # can only see own requests and managed user requests if ((user.id != self.user.id) and (user.manager_id != self.user.id)): return HTTPFound( location=route_url('list_request', self.request)) today = datetime.now() year = int(self.request.params.get('year', today.year)) start = datetime(2014, 5, 1) years = [item for item in reversed(range(start.year, today.year + 1))] if today.year > year: if user.country == 'lu': today = datetime(year, 12, 31) else: today = datetime(year, 5, 31) if year >= 2018: pool_history = self.get_new_history(user, today, year) else: pool_history = self.get_old_history(user, today, year) ret = { 'user': user, 'year': year, 'years': years, 'pool_history': pool_history } return ret
def render(self): if not self.user.is_sudoer(self.session): log.info("user '%s' tried to access sudo but is not authorized" % self.user.login) return HTTPFound(location=route_url('home', self.request)) req = self.request if req.method == 'POST' and 'continue' in req.params: headers = None target_id = int(req.params.get('sudo', self.user.id)) if target_id != self.user.id: target = User.by_id(self.session, target_id) if not target: errors = ['Cannot find user with id %d' % target_id] self.request.session.flash('error;%s' % ','.join(errors)) log.info("user '%s' will sudo to user '%s'" % (self.user.login, target.login)) headers = remember(self.request, target.login) return HTTPFound(location=route_url('home', self.request), headers=headers) return {'user': self.user}
def render(self): try: form_date_from = self.request.params.get('date_from') if ' - ' not in form_date_from: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) dates = self.request.params.get('date_from').split(' - ') date_from = datetime.strptime(dates[0], '%d/%m/%Y') date_to = datetime.strptime(dates[1], '%d/%m/%Y') # retrieve holidays for user so we can remove them from selection holidays = get_holiday(self.user, year=date_from.year, use_datetime=True) submitted = [d for d in daterange(date_from, date_to) if d.isoweekday() not in [6, 7] and d not in holidays] days = float(len(submitted)) pool = None days_diff = (date_to - date_from).days if days_diff < 0: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if (date_to == date_from) and days > 1: # same day, asking only for one or less day duration msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if days <= 0: msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # retrieve future requests for user so we can check overlap futures = [d for req in Request.by_user_future(self.session, self.user) for d in daterange(req.date_from, req.date_to)] intersect = set(futures) & set(submitted) if intersect: msg = 'Invalid period: days already requested.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) vac_type = VacationType.by_id(self.session, int(self.request.params.get('type'))) # check if vacation requires user role if (vac_type.visibility and self.user.role not in vac_type.visibility): msg = 'You are not allowed to use type: %s' % vac_type.name self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # label field is used when requesting half day label = u'' breakdown = self.request.params.get('breakdown') if breakdown != 'FULL': # handle half day if (days > 1): msg = ('AM/PM option must be used only when requesting a ' 'single day.') self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) else: days = 0.5 label = unicode(breakdown) # check RTT usage if vac_type.name == u'RTT': pool = rtt_data = self.user.get_rtt_usage(self.session) if rtt_data is not None and rtt_data['left'] <= 0: msg = 'No RTT left to take.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check that we have enough RTT to take if rtt_data is not None and days > rtt_data['left']: msg = 'You only have %s RTT to use.' % rtt_data['left'] self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check that we request vacations in the allowed year if rtt_data is not None and ( date_from.year != rtt_data['year'] or date_to.year != rtt_data['year']): msg = ('RTT can only be used for year %d.' % rtt_data['year']) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) message = None # check Exceptionnel mandatory field if vac_type.name == u'Exceptionnel': message = self.request.params.get('exception_text') message = message.strip() if message else message if not message: msg = ('You must provide a reason for %s requests' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check size if len(message) > 140: msg = ('%s reason must not exceed 140 characters' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check Récupération reason field if vac_type.name == u'Récupération': message = self.request.params.get('exception_text') message = message.strip() if message else message # check size if message and len(message) > 140: msg = ('%s reason must not exceed 140 characters' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # create the request # default values target_status = u'PENDING' target_user = self.user target_notified = False sudo_use = False if self.user.is_admin: sudo_user_id = int(self.request.params.get('sudo_user')) if sudo_user_id != -1: user = User.by_id(self.session, sudo_user_id) if user: sudo_use = True target_user = user target_status = u'APPROVED_ADMIN' target_notified = True # save pool status when making the request if pool: pool_status = json.dumps(pool) else: pool_status = json.dumps({}) request = Request(date_from=date_from, date_to=date_to, days=days, vacation_type=vac_type, status=target_status, user=target_user, notified=target_notified, label=label, message=message, pool_status=pool_status, ) self.session.add(request) self.session.flush() if request and not sudo_use: msg = 'Request sent to your manager.' self.request.session.flash('info;%s' % msg) # call celery task directly, do not wait for polling from celery.registry import tasks from celery.task import subtask req_task = tasks['worker_pending'] data = {'req_id': request.id} subtask(req_task).apply_async(kwargs={'data': data}, countdown=5) log.info('scheduling task worker_pending for %s' % data) if request and sudo_use: settings = self.request.registry.settings if 'pyvac.celery.yaml' in settings: with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') request.add_to_cal(caldav_url) msg = 'Request added to calendar and DB.' self.request.session.flash('info;%s' % msg) except Exception as exc: log.error(exc) msg = ('An error has occured while processing this request: %r' % exc) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request))
def tearDown(self): from pyvac.models import User for id in self.account_todelete: u = User.by_id(self.session, id) self.session.delete(u) super(AccountTestCase, self).tearDown()
def render(self): try: form_date_from = self.request.params.get('date_from') if ' - ' not in form_date_from: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) dates = self.request.params.get('date_from').split(' - ') date_from = datetime.strptime(dates[0], '%d/%m/%Y') date_to = datetime.strptime(dates[1], '%d/%m/%Y') breakdown = self.request.params.get('breakdown') # retrieve holidays for user so we can remove them from selection holidays = get_holiday(self.user, year=date_from.year, use_datetime=True) submitted = [ d for d in daterange(date_from, date_to) if d.isoweekday() not in [6, 7] and d not in holidays ] days = float(len(submitted)) pool = None days_diff = (date_to - date_from).days if days_diff < 0: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if (date_to == date_from) and days > 1: # same day, asking only for one or less day duration msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if days <= 0: msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check if user is sudoed check_user = self.get_target_user(self.user) # retrieve future requests for user so we can check overlap futures = [ d for req in Request.by_user_future(self.session, check_user) for d in daterange(req.date_from, req.date_to) ] intersect = set(futures) & set(submitted) if intersect: err_intersect = True # must check for false warning in case of half day requests if len(intersect) == 1: # only one date in conflict, check if it's for an half-day dt = intersect.pop() # retrieve the request for this date req = [ req for req in Request.by_user_future( self.session, check_user) for d in daterange(req.date_from, req.date_to) if d == dt ] if len(req) < 2: req = req.pop() if req.label != breakdown: # intersect is false, it's not the same halfday err_intersect = False log.debug( 'False positive on intersect ' 'for %s (%s): request: %d (%s)' % (date_from, breakdown, req.id, req.label)) if err_intersect: msg = 'Invalid period: days already requested.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) vac_type = VacationType.by_id(self.session, int(self.request.params.get('type'))) if not self.user.is_admin: # check if vacation requires user role if (vac_type.visibility and self.user.role not in vac_type.visibility): msg = 'You are not allowed to use type: %s' % vac_type.name self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check RTT usage access if vac_type.name == u'RTT': if self.user.has_feature('disable_rtt'): msg = 'You are not allowed to use type: %s' % vac_type.name self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # label field is used when requesting half day label = u'' if breakdown != 'FULL': # handle half day if (days > 1): msg = ('AM/PM option must be used only when requesting a ' 'single day.') self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) else: days = 0.5 label = unicode(breakdown) # check RTT usage if vac_type.name == u'RTT': pool = rtt_data = check_user.get_rtt_usage(self.session) if rtt_data is not None and rtt_data['left'] <= 0: msg = 'No RTT left to take.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check that we have enough RTT to take if rtt_data is not None and days > rtt_data['left']: msg = 'You only have %s RTT to use.' % rtt_data['left'] self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check that we request vacations in the allowed year if rtt_data is not None and (date_from.year != rtt_data['year'] or date_to.year != rtt_data['year']): msg = ('RTT can only be used for year %d.' % rtt_data['year']) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) message = None # check Exceptionnel mandatory field if vac_type.name == u'Exceptionnel': message = self.request.params.get('exception_text') message = message.strip() if message else message if not message: msg = ('You must provide a reason for %s requests' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check size if len(message) > 140: msg = ('%s reason must not exceed 140 characters' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check for Compensatoire type (LU holiday recovery) if vac_type.name == u'Compensatoire': to_recover = self.request.params.get('recovered_holiday') if to_recover == '-1': msg = 'You must select a date for %s' % vac_type.name self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) recover_date = datetime.strptime(to_recover, '%d/%m/%Y') vac_class = vac_type.get_class(check_user.country) if vac_class: error = vac_class.validate_request(check_user, None, days, recover_date, date_to) if error is not None: self.request.session.flash('error;%s' % error) return HTTPFound( location=route_url('home', self.request)) message = to_recover # check Récupération reason field if vac_type.name == u'Récupération': message = self.request.params.get('exception_text') message = message.strip() if message else message # check size if message and len(message) > 140: msg = ('%s reason must not exceed 140 characters' % vac_type.name) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check CP usage if vac_type.name == u'CP': cp_class = check_user.get_cp_class(self.session) pool = check_user.get_cp_usage(self.session) if cp_class: # only FR and LU have a dedicated CP class to use # convert days to hours for LU if needed days = cp_class.convert_days(days) error = cp_class.validate_request(check_user, pool, days, date_from, date_to) if error is not None: self.request.session.flash('error;%s' % error) return HTTPFound( location=route_url('home', self.request)) if pool: # remove expire datetimes as it's not json serializable if 'n_1' in pool: pool['n_1'].pop('expire', None) if 'extra' in pool: pool['extra'].pop('expire', None) pool['acquis'].pop('expire', None) pool['restant'].pop('expire', None) # create the request # default values target_status = u'PENDING' target_user = self.user target_notified = False sudo_use = False if self.user.is_admin: sudo_user_id = int(self.request.params.get('sudo_user')) if sudo_user_id != -1: user = User.by_id(self.session, sudo_user_id) if user: sudo_use = True target_user = user target_status = u'APPROVED_ADMIN' target_notified = True # save pool status when making the request if pool: pool_status = json.dumps(pool) else: pool_status = json.dumps({}) request = Request( date_from=date_from, date_to=date_to, days=days, vacation_type=vac_type, status=target_status, user=target_user, notified=target_notified, label=label, message=message, pool_status=pool_status, ) self.session.add(request) self.session.flush() # create history entry sudo_user = None if sudo_use: sudo_user = self.user RequestHistory.new(self.session, request, '', target_status, target_user, pool_status, message=message, sudo_user=sudo_user) if request and not sudo_use: msg = 'Request sent to your manager.' self.request.session.flash('info;%s' % msg) # call celery task directly, do not wait for polling from celery.registry import tasks from celery.task import subtask req_task = tasks['worker_pending'] data = {'req_id': request.id} subtask(req_task).apply_async(kwargs={'data': data}, countdown=5) log.info('scheduling task worker_pending for %s' % data) if request and sudo_use: settings = self.request.registry.settings if 'pyvac.celery.yaml' in settings: with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') request.add_to_cal(caldav_url, self.session) msg = 'Request added to calendar and DB.' self.request.session.flash('info;%s' % msg) except Exception as exc: log.error(exc) msg = ('An error has occured while processing this request: %r' % exc) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request))
def render(self): user = User.by_id(self.session, int(self.request.matchdict['user_id'])) if self.user.has_no_role: # can only see own requests if user.id != self.user.id: return HTTPFound( location=route_url('list_request', self.request)) if self.user.is_manager: # can only see own requests and managed user requests if ((user.id != self.user.id) and (user.manager_id != self.user.id)): return HTTPFound( location=route_url('list_request', self.request)) today = datetime.now() year = int(self.request.params.get('year', today.year)) start = datetime(2014, 5, 1) years = [item for item in reversed(range(start.year, today.year + 1))] pool_history = {} pool_history['RTT'] = User.get_rtt_history(self.session, user, year) if today.year > year: if user.country == 'lu': today = datetime(year, 12, 31) else: today = datetime(year, 5, 31) history, restant = User.get_cp_history(self.session, user, year, today) vac_class = user.get_cp_class(self.session) cp_history = [] pool_acquis = 0 pool_restant = 0 for idx, entry in enumerate(history): if idx == 0: pool_restant = restant[entry['date']] if entry['value'] < 0: if user.country == 'lu': pool_restant, pool_acquis = vac_class.consume( taken=entry['value'], restant=pool_restant, acquis=pool_acquis) else: _, pool_restant, pool_acquis, _ = vac_class.consume( taken=entry['value'], restant=pool_restant, acquis=pool_acquis, n_1=0, extra=0) else: pool_acquis = pool_acquis + entry['value'] item = { 'date': entry['date'].strftime('%Y-%m-%d'), 'value': entry['value'], 'restant': pool_restant, 'acquis': pool_acquis, 'flavor': entry.get('flavor', ''), } cp_history.append(item) pool_history['CP'] = cp_history ret = { 'user': user, 'year': year, 'years': years, 'pool_history': pool_history } return ret
def render(self): try: form_date_from = self.request.params.get('date_from') if ' - ' not in form_date_from: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) dates = self.request.params.get('date_from').split(' - ') date_from = datetime.strptime(dates[0], '%d/%m/%Y') date_to = datetime.strptime(dates[1], '%d/%m/%Y') days = float(len([d for d in daterange(date_from, date_to) if d.isoweekday() not in [6, 7]])) days_diff = (date_to - date_from).days if days_diff < 0: msg = 'Invalid format for period.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if (date_to == date_from) and days > 1: # same day, asking only for one or less day duration msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) if days <= 0: msg = 'Invalid value for days.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) vac_type = VacationType.by_id(self.session, int(self.request.params.get('type'))) # label field is used when requesting half day label = u'' breakdown = self.request.params.get('breakdown') if breakdown != 'FULL': # handle half day if (days > 1): msg = ('AM/PM option must be used only when requesting a ' 'single day.') self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) else: days = 0.5 label = unicode(breakdown) # check RTT usage if vac_type.name == u'RTT': rtt_data = self.user.get_rtt_usage(self.session) if rtt_data is not None and rtt_data['left'] <= 0: msg = 'No RTT left to take.' self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # check that we have enough RTT to take if rtt_data is not None and days > rtt_data['left']: msg = 'You only have %s RTT to use.' % rtt_data['left'] self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request)) # create the request # default values target_status = u'PENDING' target_user = self.user target_notified = False sudo_use = False if self.user.is_admin: sudo_user_id = int(self.request.params.get('sudo_user')) if sudo_user_id != -1: user = User.by_id(self.session, sudo_user_id) if user: sudo_use = True target_user = user target_status = u'APPROVED_ADMIN' target_notified = True request = Request(date_from=date_from, date_to=date_to, days=days, vacation_type=vac_type, status=target_status, user=target_user, notified=target_notified, label=label, ) self.session.add(request) self.session.flush() if request and not sudo_use: msg = 'Request sent to your manager.' self.request.session.flash('info;%s' % msg) # call celery task directly, do not wait for polling from celery.registry import tasks from celery.task import subtask req_task = tasks['worker_pending'] data = {'req_id': request.id} subtask(req_task).apply_async(kwargs={'data': data}, countdown=5) log.info('scheduling task worker_pending for %s' % data) if request and sudo_use: settings = self.request.registry.settings if 'pyvac.celery.yaml' in settings: with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') request.add_to_cal(caldav_url) msg = 'Request added to calendar and DB.' self.request.session.flash('info;%s' % msg) except Exception as exc: log.error(exc) msg = ('An error has occured while processing this request: %r' % exc) self.request.session.flash('error;%s' % msg) return HTTPFound(location=route_url('home', self.request))