def execute_scheduled_actions_task(debug: bool): """Execute the entries in the DB that are due. :return: Nothing. """ # Get the current date/time s_items = _get_pending_items() # If the number of tasks to execute is zero, we are done. if s_items.count() == 0: return for s_item in s_items: if debug: logger.info('Starting execution of task %s', str(s_item.id)) with cache.lock(cache_lock_format.format(s_item.id)): # Item is now locked by the cache mechanism s_item.refresh_from_db() if s_item.status != ScheduledOperation.STATUS_PENDING: continue try: # Set item to running s_item.status = ScheduledOperation.STATUS_EXECUTING s_item.save() run_result = None log_item = None action_info = None # Get action info and log item if s_item.action.action_type in _function_distributor: action_info, log_item = _function_distributor[ s_item.action.action_type](s_item) if log_item: run_result = run_task( s_item.user.id, log_item.id, action_info.get_store()) s_item.last_executed_log = log_item else: logger.error( 'Execution of action type "%s" not implemented', s_item.action.action_type) _update_item_status(s_item, run_result, debug) except Exception as exc: logger.error( 'Error while processing scheduled action: {0}'.format( str(exc)))
def execute_scheduled_actions_task(debug: bool): """Execute the entries in the DB that are due. :return: Nothing. """ # Get the current date/time now = datetime.now(pytz.timezone(settings.TIME_ZONE)) # Get all the actions that are pending s_items = ScheduledAction.objects.filter( status=ScheduledAction.STATUS_PENDING, execute__lt=now + timedelta(minutes=1)) logger.info('%s actions pending execution', s_items.count()) # If the number of tasks to execute is zero, we are done. if s_items.count() == 0: return for s_item in s_items: if debug: logger.info('Starting execution of task %s', str(s_item.id)) # Set item to running s_item.status = ScheduledAction.STATUS_EXECUTING s_item.save() run_result = None log_item = None # # EMAIL ACTION # if s_item.action.action_type == Action.personalized_text: action_info = EmailPayload(s_item.payload) action_info['action_id'] = s_item.action_id action_info['item_column'] = s_item.item_column.name action_info['exclude_values'] = s_item.exclude_values # Log the event log_item = Log.objects.register( s_item.user, Log.SCHEDULE_EMAIL_EXECUTE, s_item.action.workflow, { 'action': s_item.action.name, 'action_id': s_item.action.id, 'bcc_email': s_item.payload.get('bcc_email'), 'cc_email': s_item.payload.get('cc_email'), 'item_column': s_item.item_column.name, 'execute': s_item.execute.isoformat(), 'exclude_values': s_item.exclude_values, 'from_email': s_item.user.email, 'send_confirmation': s_item.payload.get('send_confirmation'), 'status': 'Preparing to execute', 'subject': s_item.payload.get('subject'), 'track_read': s_item.payload.get('track_read') }) run_result = run_task(s_item.user.id, log_item.id, action_info.get_store()) # # SEND LIST ACTION # elif s_item.action.action_type == Action.send_list: action_info = SendListPayload(s_item.payload) action_info['action_id'] = s_item.action_id # Log the event log_item = Log.objects.register( s_item.user, Log.SCHEDULE_SEND_LIST_EXECUTE, s_item.action.workflow, { 'action': s_item.action.name, 'action_id': s_item.action.id, 'from_email': s_item.user.email, 'email_to': s_item.payload.get('email_to'), 'subject': s_item.payload.get('subject'), 'bcc_email': s_item.payload.get('bcc_email'), 'cc_email': s_item.payload.get('cc_email'), 'execute': s_item.execute.isoformat(), 'status': 'Preparing to execute' }) run_result = run_task(s_item.user.id, log_item.id, action_info.get_store()) # # JSON action # elif s_item.action.action_type == Action.personalized_json: # Get the information about the keycolum item_column = None if s_item.item_column: item_column = s_item.item_column.name action_info = JSONPayload(s_item.payload) action_info['action_id'] = s_item.action_id action_info['item_column'] = item_column action_info['exclude_values'] = s_item.exclude_values # Log the event log_item = Log.objects.register( s_item.user, Log.SCHEDULE_JSON_EXECUTE, s_item.action.workflow, { 'action': s_item.action.name, 'action_id': s_item.action.id, 'exclude_values': s_item.exclude_values, 'item_column': item_column, 'status': 'Preparing to execute', 'target_url': s_item.action.target_url }) # Send the objects run_result = run_task(s_item.user.id, log_item.id, action_info.get_store()) # # JSON LIST action # elif s_item.action.action_type == Action.send_list_json: # Get the information about the keycolum item_column = None if s_item.item_column: item_column = s_item.item_column.name action_info = JSONPayload(s_item.payload) action_info['action_id'] = s_item.action_id # Log the event log_item = Log.objects.register( s_item.user, Log.SCHEDULE_JSON_EXECUTE, s_item.action.workflow, { 'action': s_item.action.name, 'action_id': s_item.action.id, 'status': 'Preparing to execute', 'target_url': s_item.action.target_url }) # Send the objects run_result = run_task(s_item.user.id, log_item.id, action_info.get_store()) # # Canvas Email Action # elif s_item.action.action_type == Action.personalized_canvas_email: # Get the information from the payload action_info = CanvasEmailPayload(s_item.payload) action_info['action_id'] = s_item.action_id action_info['item_column'] = s_item.item_column.name action_info['exclude_values'] = s_item.exclude_values # Log the event log_item = Log.objects.register( s_item.user, Log.SCHEDULE_EMAIL_EXECUTE, s_item.action.workflow, { 'action': s_item.action.name, 'action_id': s_item.action.id, 'item_column': s_item.item_column.name, 'execute': s_item.execute.isoformat(), 'exclude_values': s_item.exclude_values, 'from_email': s_item.user.email, 'status': 'Preparing to execute', 'subject': s_item.payload.get('subject', '') }) run_result = run_task(s_item.user.id, log_item.id, action_info.get_store()) else: logger.error('Execution of action type "%s" not implemented', s_item.action.action_type) if run_result: s_item.status = ScheduledAction.STATUS_DONE else: s_item.status = ScheduledAction.STATUS_DONE_ERROR if debug: logger.info('Status set to %s', s_item.status) if log_item: # Store the log event in the scheduling item s_item.last_executed_log = log_item # Save the new status in the DB s_item.save()
def increase_track_count(method, get_dict): """ Function to process track requests asynchronously. :param method: GET or POST received in the request :param get_dict: GET dictionary received in the request :return: If correct, increases one row of the DB by one """ if method != 'GET': # Only GET requests are accepted logger.error(ugettext('Non-GET request received in Track URL')) return False # Obtain the track_id from the request track_id = get_dict.get('v') if not track_id: logger.error(ugettext('No track_id found in request')) # No track id, nothing to do return False # If the track_id is not correctly signed, finish. try: track_id = signing.loads(track_id) except signing.BadSignature: logger.error(ugettext('Bad signature in track_id')) return False # The request is legit and the value has been verified. Track_id has now # the dictionary with the tracking information # Get the objects related to the ping user = get_user_model().objects.filter(email=track_id['sender']).first() if not user: logger.error( ugettext('Incorrect user email {0}').format(track_id['sender']) ) return False action = Action.objects.filter(pk=track_id['action']).first() if not action: logger.error( ugettext('Incorrect action id {0}').format(track_id['action']) ) return False # Extract the relevant fields from the track_id column_dst = track_id.get('column_dst', '') column_to = track_id.get('column_to', '') msg_to = track_id.get('to', '') column = action.workflow.columns.filter(name=column_dst).first() if not column: # If the column does not exist, we are done logger.error( ugettext('Column {0} does not exist').format(column_dst) ) return False log_payload = {'to': msg_to, 'email_column': column_to, 'column_dst': column_dst } # If the track comes with column_dst, the event needs to be reflected # back in the data frame if column_dst: try: # Increase the relevant cell by one dataops.sql.row_queries.increase_row_integer( action.workflow.get_data_frame_table_name(), column_dst, column_to, msg_to ) except Exception as e: log_payload['EXCEPTION_MSG'] = str(e) else: # Get the tracking column and update all the conditions in the # actions that have this column as part of their formulas # FIX: Too aggressive? track_col = action.workflow.columns.get(name=column_dst) for action in action.workflow.actions.all(): action.update_n_rows_selected(track_col) # Record the event Log.objects.register(user, Log.ACTION_EMAIL_READ, action.workflow, log_payload) return True