def process_fire_events(fire_ids): from temba.campaigns.models import EventFire # every event fire in the batch will be for the same flow... but if the flow has been deleted then fires won't exist single_fire = EventFire.objects.filter(id__in=fire_ids).first() if not single_fire: # pragma: no cover return flow = single_fire.event.flow # lock on the flow so we know non-one else is updating these event fires r = get_redis_connection() with r.lock('process_fire_events:%d' % flow.id, timeout=300): # only fetch fires that haven't been somehow already handled fires = list( EventFire.objects.filter(id__in=fire_ids, fired=None).prefetch_related('contact')) if fires: print("E[%s][%s] Batch firing %d events..." % (flow.org.name, flow.name, len(fires))) start = time.time() EventFire.batch_fire(fires, flow) print("E[%s][%s] Finished batch firing events in %.3f s" % (flow.org.name, flow.name, time.time() - start))
def save(self): """ Create or update our campaign event """ campaign = self.validated_data.get('campaign') offset = self.validated_data.get('offset') unit = self.validated_data.get('unit') delivery_hour = self.validated_data.get('delivery_hour') relative_to = self.validated_data.get('relative_to') message = self.validated_data.get('message') flow = self.validated_data.get('flow') if self.instance: # we are being set to a flow if flow: self.instance.flow = flow self.instance.event_type = CampaignEvent.TYPE_FLOW self.instance.message = None # we are being set to a message else: translations, base_language = message self.instance.message = translations # if we aren't currently a message event, we need to create our hidden message flow if self.instance.event_type != CampaignEvent.TYPE_MESSAGE: self.instance.flow = Flow.create_single_message(self.context['org'], self.context['user'], translations, base_language) self.instance.event_type = CampaignEvent.TYPE_MESSAGE # otherwise, we can just update that flow else: # set our single message on our flow self.instance.flow.update_single_message_flow(translations, base_language) # update our other attributes self.instance.offset = offset self.instance.unit = unit self.instance.delivery_hour = delivery_hour self.instance.relative_to = relative_to self.instance.save() self.instance.update_flow_name() else: if flow: self.instance = CampaignEvent.create_flow_event(self.context['org'], self.context['user'], campaign, relative_to, offset, unit, flow, delivery_hour) else: translations, base_language = message self.instance = CampaignEvent.create_message_event(self.context['org'], self.context['user'], campaign, relative_to, offset, unit, translations, delivery_hour, base_language) self.instance.update_flow_name() # create our event fires for this event in the background EventFire.update_eventfires_for_event(self.instance) return self.instance
def migrate_campaigns_to_production(all_notifications): for n in all_notifications: campaign = json.loads(n.history) definition = BASE_IMPORT.copy() definition["campaign"] = [campaign] n.org_dest.import_app(definition, n.created_by) n.mark_migrated() c = Campaign.objects.filter(name = n.item_name, org = n.org_dest, group__name =campaign["group"]["name"]).last() Campaign.restore_flows(c) EventFire.update_campaign_events(c)
def migrate_events_to_production(all_notifications): for n in all_notifications: #Check if campaign exist item = json.loads(n.history) c = Campaign.objects.filter(org = n.org_dest, name = item["name"], group__name = item["group"]["name"] ).last() if c : c.is_archived=False c.modified_by=n.created_by c.modified_on=timezone.now() c.save() for event_spec in item["events"]: #check if our event is in campaign e = c.events.filter(offset = event_spec ["offset"], unit = event_spec["unit"], relative_to__key =event_spec["relative_to"]["key"], flow__name = event_spec["flow"]["name"], event_type =event_spec["event_type"]) if not e: create_event(event_spec, n, c) print("Se creo el evento") else: print ("Evento ya existente") else: definition = BASE_IMPORT.copy() definition["campaign"] = item definition["flows"] =json.dumps(FlowRevision.objects.filter(flow__name=item.item_name).last().definition) n.org_dest.import_app(definition, n.created_by) c = Campaign.objects.filter(name = item["name"], org = n.org_dest, group__name =item["group"]["name"]).last() print(c) print (item) print (n.org_dest) Campaign.restore_flows(c) print("Se creo toda la campania") EventFire.update_campaign_events(c) n.mark_migrated()
def archive_changes(): admin_checked = Notification.objects.filter( reviewed = True, to_archive = True, archived = False) #campaigns campaigns = admin_checked.filter(item_type = Notification.CAMPAIGN_TYPE) for n in campaigns: c = Campaign.objects.filter(org= n.org_dest, name = n.item_name).last() if c: c.is_archived = True c.save() EventFire.update_campaign_events(c) n.mark_archived() #triggers triggers = admin_checked.filter(item_type = Notification.TRIGGER_TYPE) for n in triggers: t = Trigger.objects.filter(org= n.org_orig, name = n.item_id).last() t_prod = Trigger.objects.filter(org = n.org_dest, keyword = t.keyword, trigger_type = t.trigger_type, flow__name = t.flow.name, is_archived = False).last() if t_prod: trigger.archive(n.created_by) n.mark_archived() #flows flows = admin_checked.filter(item_type = Notification.FLOW_TYPE) for n in flows: f = Flow.objects.filter(org = n.org_dest, name = n.item_name).last() if f: print (f) f.archive() c_event = CampaignEvent.objects.filter(flow = f).last() trigger = Trigger.objects.filter(flow= f).last() if c_event: print (c_event) c_event.release() if trigger: print (trigger) trigger.archive(n.created_by) n.mark_archived()
def create_event_fires(event_id): # get a lock r = get_redis_connection() key = "event_fires_event_%d" % event_id with r.lock(key, timeout=300): try: with transaction.atomic(): event = CampaignEvent.objects.filter(pk=event_id).first() if event: EventFire.do_create_eventfires_for_event(event) except Exception as e: # pragma: no cover # requeue our task to try again in five minutes create_event_fires(event_id).delay(countdown=60 * 5) # bubble up the exception so sentry sees it raise e
def update_event_fires_for_campaign(campaign_id): # get a lock r = get_redis_connection() key = 'event_fires_campaign_%d' % campaign_id with r.lock(key, timeout=300): try: with transaction.atomic(): campaign = Campaign.objects.filter(pk=campaign_id).first() if campaign: EventFire.do_update_campaign_events(campaign) except Exception as e: # requeue our task to try again in five minutes update_event_fires_for_campaign(campaign_id).delay(countdown=60*5) # bubble up the exception so sentry sees it raise e
def process_fire_events(fire_ids): from temba.campaigns.models import EventFire # every event fire in the batch will be for the same flow... but if the flow has been deleted then fires won't exist single_fire = EventFire.objects.filter(id__in=fire_ids).first() if not single_fire: # pragma: no cover return flow = single_fire.event.flow # lock on the flow so we know non-one else is updating these event fires r = get_redis_connection() with r.lock("process_fire_events:%d" % flow.id, timeout=300): # only fetch fires that haven't been somehow already handled fires = list(EventFire.objects.filter(id__in=fire_ids, fired=None).prefetch_related("contact")) if fires: print("E[%s][%s] Batch firing %d events..." % (flow.org.name, flow.name, len(fires))) start = time.time() EventFire.batch_fire(fires, flow) print("E[%s][%s] Finished batch firing events in %.3f s" % (flow.org.name, flow.name, time.time() - start))
def recalculate_event_fires(apps, schema_editor): for event in CampaignEvent.objects.filter(is_active=True).select_related('campaign').order_by('campaign__org'): EventFire.do_update_eventfires_for_event(event)
def save(self): """ Create or update our campaign event """ campaign = self.validated_data.get("campaign") offset = self.validated_data.get("offset") unit = self.validated_data.get("unit") delivery_hour = self.validated_data.get("delivery_hour") relative_to = self.validated_data.get("relative_to") message = self.validated_data.get("message") flow = self.validated_data.get("flow") if self.instance: # we dont update, we only create self.instance = self.instance.deactivate_and_copy() # we are being set to a flow if flow: self.instance.flow = flow self.instance.event_type = CampaignEvent.TYPE_FLOW self.instance.message = None # we are being set to a message else: translations, base_language = message if not self.validated_data["new_expressions"]: translations = migrate_translations(translations) self.instance.message = translations # if we aren't currently a message event, we need to create our hidden message flow if self.instance.event_type != CampaignEvent.TYPE_MESSAGE: self.instance.flow = Flow.create_single_message( self.context["org"], self.context["user"], translations, base_language) self.instance.event_type = CampaignEvent.TYPE_MESSAGE # otherwise, we can just update that flow else: # set our single message on our flow self.instance.flow.update_single_message_flow( self.context["user"], translations, base_language) # update our other attributes self.instance.offset = offset self.instance.unit = unit self.instance.delivery_hour = delivery_hour self.instance.relative_to = relative_to self.instance.save() self.instance.update_flow_name() else: if flow: self.instance = CampaignEvent.create_flow_event( self.context["org"], self.context["user"], campaign, relative_to, offset, unit, flow, delivery_hour) else: translations, base_language = message if not self.validated_data["new_expressions"]: translations = migrate_translations(translations) self.instance = CampaignEvent.create_message_event( self.context["org"], self.context["user"], campaign, relative_to, offset, unit, translations, delivery_hour, base_language, ) self.instance.update_flow_name() # create our event fires for this event in the background EventFire.create_eventfires_for_event(self.instance) return self.instance
def recalculate_event_fires(apps, schema_editor): for event in CampaignEvent.objects.filter( is_active=True).select_related('campaign').order_by( 'campaign__org'): EventFire.do_update_eventfires_for_event(event)
def save(self): """ Create or update our campaign event """ campaign = self.validated_data.get("campaign") offset = self.validated_data.get("offset") unit = self.validated_data.get("unit") delivery_hour = self.validated_data.get("delivery_hour") relative_to = self.validated_data.get("relative_to") message = self.validated_data.get("message") flow = self.validated_data.get("flow") if self.instance: # we dont update, we only create self.instance = self.instance.deactivate_and_copy() # we are being set to a flow if flow: self.instance.flow = flow self.instance.event_type = CampaignEvent.TYPE_FLOW self.instance.message = None # we are being set to a message else: translations, base_language = message self.instance.message = translations # if we aren't currently a message event, we need to create our hidden message flow if self.instance.event_type != CampaignEvent.TYPE_MESSAGE: self.instance.flow = Flow.create_single_message( self.context["org"], self.context["user"], translations, base_language ) self.instance.event_type = CampaignEvent.TYPE_MESSAGE # otherwise, we can just update that flow else: # set our single message on our flow self.instance.flow.update_single_message_flow(translations, base_language) # update our other attributes self.instance.offset = offset self.instance.unit = unit self.instance.delivery_hour = delivery_hour self.instance.relative_to = relative_to self.instance.save() self.instance.update_flow_name() else: if flow: self.instance = CampaignEvent.create_flow_event( self.context["org"], self.context["user"], campaign, relative_to, offset, unit, flow, delivery_hour ) else: translations, base_language = message self.instance = CampaignEvent.create_message_event( self.context["org"], self.context["user"], campaign, relative_to, offset, unit, translations, delivery_hour, base_language, ) self.instance.update_flow_name() # create our event fires for this event in the background EventFire.create_eventfires_for_event(self.instance) return self.instance
def update_event_fires(event_id): event = CampaignEvent.objects.filter(pk=event_id).first() if event: EventFire.do_update_eventfires_for_event(event)