def test_get_my_messages(self): test_device = 'dev_id' ch1 = Channel.objects.create(name="SubCha1", description="", kind=PUBLIC) ch2 = Channel.objects.create(name="SubCha2", description="", kind=PUBLIC) SubscriberManager().subscribe("SubCha1", 'ios', test_device, 'token') SubscriberManager().subscribe("SubCha2", 'ios', test_device, 'token') msg1 = ChannelMsg(channel=ch1) msg1.body = "aaa" msg1.message_type = "text/plain" msg1.expire = datetime.utcnow() + timedelta(days=5) msg1.save() msg2 = ChannelMsg(channel=ch2) msg2.body = "bbbb" msg2.message_type = "text/plain" msg2.expire = datetime.utcnow() + timedelta(days=3) msg2.save() msg_expired = ChannelMsg(channel=ch2) msg_expired.body = "cccc" msg_expired.message_type = "text/plain" msg_expired.expire = datetime.utcnow() + timedelta(days=-3) msg_expired.save() url = reverse('messages-api:messages-by-owner', args=[test_device]) response = self.client.get(url) print response.data self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 2)
def delete(self, request, name=None, sub_type=None, device_id=None): """ Unsubscribe from a channel """ channels = Channel.objects.filter(name=name) if not channels: return Response(status=status.HTTP_404_NOT_FOUND) if not name is None and not device_id is None: result = status.HTTP_200_OK channel = channels[0] subManager = SubscriberManager() sub_token = subManager.get_subscription(channel.name, sub_type, device_id) if not sub_token is None: subManager.unsubscribe(channel.name, device_id, sub_type) # Dec num subscriptions channel.subscriptions = channel.subscriptions - 1 channel.save() else: # Verifica che non si tratti di una subscription reqs = ChannelSubscribeRequest.objects.filter(device_id=device_id).filter(channel=channel) if reqs.count() > 0: reqs[0].delete() else: result = status.HTTP_404_NOT_FOUND return Response(status=result) else: return Response(status=status.HTTP_400_BAD_REQUEST)
def test_subscrive_already_exist_device(self): url = reverse('subscribers-api:subscribers-list') data = { u'token': u'APA91bGTpK3rxSwkXaH1negC7F4FWeNTRb-mBX9i6F8cPXq65NWaVfAdrrI4mtY8MLE7wUuyWnfGebgJeQ6U8zZGFjVy7FT5cfyPCg6L6mYoDGwmwC5-A5tnbCzitip78iMTjsQrQjjsZ3SmgeTrDuZloxXGwCpgiw', u'sub_type': u'android', u'name': u'UnitTest', u'device_id': u'ffffffff-c97a-15d1-ffff-ffffef05ac4a'} response = self.client.post(url, data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) print "First device subscribe" ch1 = Channel.objects.create(name='SubCh1', description="", kind=PUBLIC) ch2 = Channel.objects.create(name='SubCh2', description="", kind=PUBLIC) SubscriberManager().subscribe('SubCh1', 'android', 'ffffffff-c97a-15d1-ffff-ffffef05ac4a', 'APA91bGTpK3rxSwkXaH1negC7F4FWeNTRb-mBX9i6F8cPXq65NWaVfAdrrI4mtY8MLE7wUuyWnfGebgJeQ6U8zZGFjVy7FT5cfyPCg6L6mYoDGwmwC5-A5tnbCzitip78iMTjsQrQjjsZ3SmgeTrDuZloxXGwCpgiw') SubscriberManager().subscribe('SubCh2', 'android', 'ffffffff-c97a-15d1-ffff-ffffef05ac4a', 'APA91bGTpK3rxSwkXaH1negC7F4FWeNTRb-mBX9i6F8cPXq65NWaVfAdrrI4mtY8MLE7wUuyWnfGebgJeQ6U8zZGFjVy7FT5cfyPCg6L6mYoDGwmwC5-A5tnbCzitip78iMTjsQrQjjsZ3SmgeTrDuZloxXGwCpgiw') data = {u'token': u'newtok', u'sub_type': u'android', u'name': u'UnitTest', u'device_id': u'ffffffff-c97a-15d1-ffff-ffffef05ac4a'} # Nuova registrazione del device post subscription di un paio di canali response = self.client.post(url, data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) newtok = SubscriberManager().get_subscription('SubCh1', 'android', 'ffffffff-c97a-15d1-ffff-ffffef05ac4a') self.assertEqual(newtok, 'newtok') newtok = SubscriberManager().get_subscription('SubCh2', 'android', 'ffffffff-c97a-15d1-ffff-ffffef05ac4a') self.assertEqual(newtok, 'newtok')
def delete(self, request, name=None, sub_type=None, device_id=None): """ Unsubscribe from a channel """ channels = Channel.objects.filter(name=name) if not channels: return Response(status=status.HTTP_404_NOT_FOUND) if not name is None and not device_id is None: result = status.HTTP_200_OK channel = channels[0] subManager = SubscriberManager() sub_token = subManager.get_subscription(channel.name, sub_type, device_id) if not sub_token is None: subManager.unsubscribe(channel.name, device_id, sub_type) # Dec num subscriptions channel.subscriptions = channel.subscriptions - 1 channel.save() else: # Verifica che non si tratti di una subscription reqs = ChannelSubscribeRequest.objects.filter( device_id=device_id).filter(channel=channel) if reqs.count() > 0: reqs[0].delete() else: result = status.HTTP_404_NOT_FOUND return Response(status=result) else: return Response(status=status.HTTP_400_BAD_REQUEST)
def unsubscribe_channel(channel, device_id): """ Unsubscribe a device from a channel :param channel: :param device_id: """ subscriber = Subscriber.objects.get(device_id=device_id) result = False if not channel is None and not device_id is None: result = True subManager = SubscriberManager() sub_token = subManager.get_subscription(channel.name, subscriber.sub_type, subscriber.device_id) if not sub_token is None: subManager.unsubscribe(channel.name, subscriber.device_id, subscriber.sub_type) # Dec num subscriptions channel.subscriptions = channel.subscriptions - 1 channel.save() else: # Verifica che non si tratti di una subscription nel caso la cancella reqs = ChannelSubscribeRequest.objects.filter(device_id=subscriber.device_id).filter(channel=channel) if reqs.count() > 0: reqs[0].delete() else: result = False return result
def unsubscribe_channel(channel, device_id): """ Unsubscribe a device from a channel :param channel: :param device_id: """ subscriber = Subscriber.objects.get(device_id=device_id) result = False if not channel is None and not device_id is None: result = True subManager = SubscriberManager() sub_token = subManager.get_subscription(channel.name, subscriber.sub_type, subscriber.device_id) if not sub_token is None: subManager.unsubscribe(channel.name, subscriber.device_id, subscriber.sub_type) # Dec num subscriptions channel.subscriptions = channel.subscriptions - 1 channel.save() else: # Verifica che non si tratti di una subscription nel caso la cancella reqs = ChannelSubscribeRequest.objects.filter( device_id=subscriber.device_id).filter(channel=channel) if reqs.count() > 0: reqs[0].delete() else: result = False return result
def post(self, request, format=None): serializer = SubscriberSerializer(data=request.DATA) if serializer.is_valid(): is_sandbox = (True if settings.ENVIRONMENT == "dev" else False) subscriber_data = serializer.object subscriber, created = Subscriber.objects.get_or_create(device_id=subscriber_data["device_id"], defaults={'sub_type': subscriber_data["sub_type"], 'sandbox': is_sandbox, 'enabled': True, 'name': subscriber_data["name"], 'token': subscriber_data["token"]}) if not created: subscriber.token = subscriber_data["token"] subscriber.name = subscriber_data["name"] subscriber.save() # Update del token nelle subscription del device subMamager = SubscriberManager() channel_subscriptions = subMamager.get_device_subscriptions(subscriber_data["device_id"]) for channel_sub in channel_subscriptions: subMamager.subscribe(channel_sub, subscriber_data["sub_type"], subscriber_data["device_id"], subscriber_data["token"]) return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def subscribe_to_channel(subscriber, channel): subscription = SubscriberManager().get_subscription( channel.name, subscriber.sub_type, subscriber.device_id) if subscription is None: SubscriberManager().subscribe(channel.name, subscriber.sub_type, subscriber.device_id, subscriber.token) # Inc num subscriptions channel.subscriptions = channel.subscriptions + 1 channel.save()
def pre_remove_subscription(sender, **kwargs): subscriber = kwargs.get('instance') sub_manager = SubscriberManager() subscriptions = sub_manager.get_device_subscriptions(subscriber.device_id) logger.info("Delete subscriber ({0} - {1}) signal ".format(subscriber.name, subscriber.sub_type)) for channel_name in subscriptions: unsubscribe_channel(channel, subscriber.device_id)
def pre_remove_subscription(sender, **kwargs): subscriber = kwargs.get('instance') sub_manager = SubscriberManager() subscriptions = sub_manager.get_device_subscriptions(subscriber.device_id) logger.info("Delete subscriber ({0} - {1}) signal ".format( subscriber.name, subscriber.sub_type)) for channel_name in subscriptions: unsubscribe_channel(channel, subscriber.device_id)
def test_subscribe_not_logged_device(self): ch1 = Channel.objects.create(name='TestSubscriptions1', description="test for subscriptions 1", kind=PUBLIC) ch2 = Channel.objects.create(name='TestSubscriptions2', description="test for subscriptions 2", kind=PUBLIC) SubscriberManager().subscribe('TestSubscriptions1', 'ios', 'device1', 'token') SubscriberManager().subscribe('TestSubscriptions2', 'ios', 'device1', 'token') url = reverse('subscriptions-api:subsctiptions-list', args=['device1']) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK)
def pre_remove_channel(sender, **kwargs): channel = kwargs.get('instance') sub_manager = SubscriberManager() sub_tokens = sub_manager.get_all_subscribers(channel.name) devices = Subscriber.objects.filter(token__in=sub_tokens) logger.info("Delete channel ({0}) signal ".format(channel.name)) for dev in devices.all(): logger.info("\t removing subscriber {0}".format(dev.device_id)) unsubscribe_channel(channel, dev.device_id)
def delete(self, request, device_id=None, channel_name=None): channel = get_object_or_404(Channel, name=channel_name) channels = SubscriberManager().get_device_subscriptions(device_id) resp = 404 if next( (x for x in channels if x == channel.name.lower()), None) != None: current_dev = Subscriber.objects.get(device_id=device_id) SubscriberManager().unsubscribe(channel_name, device_id, current_dev.sub_type) resp = 200 return HttpResponse(status=resp)
def get(self, request, format=None, deviceId=None): channel_names = SubscriberManager().get_device_subscriptions(deviceId) channels = Channel.objects.filter(name__in=channel_names) serializer = ChannelSerializer(channels, many=True) return Response(serializer.data)
def get(self, request): owner_channels = Channel.objects.filter(owner=request.user) auth_token = None try: auth_token = Token.objects.get(user=request.user) except Token.DoesNotExist: auth_token = Token.objects.create(user=request.user) subscribers_tokens = [] subscribers = [] chan_subscribers = [] for channel in owner_channels: chan_subscribers = SubscriberManager().get_all_subscribers(channel.name) subscribers_tokens.append(chan_subscribers) subscribers.append(Subscriber.objects.filter(token__in=chan_subscribers)) messages_count = ChannelMsg.objects.filter(channel__in=owner_channels).count() return render_to_response('dashboard.html', dict( apikey=auth_token.key if auth_token else "No token", owner_channels_count=len(owner_channels), latest_channels=owner_channels[:5], subscribers_count=len(chan_subscribers), messages_count=messages_count, subscribers=subscribers[:5] ), context_instance=RequestContext(request) )
def setUp(self): settings.REDIS_DB = 15 # Db usato per i test SubscriberManager().flushdb() sub1 = Subscriber() sub1.sub_type = 'type2' sub1.token = 'token2' sub1.device_id = 'devid_subs' sub1.save()
def get(self, request, device_id=None, channel_name=None): channel = get_object_or_404(Channel, name=channel_name) channels = SubscriberManager().get_device_subscriptions(device_id) resp = 200 if next((x for x in channels if x == channel.name.lower()), None) == None: resp = 404 return HttpResponse(status=resp)
def ask_subscribe_channel(channel, device_id): """ Ask for subscribe to a channel. If public subscription is immediate else a request to channel owner is generated :param channel: :param device_id: """ try: asking_subscriber = Subscriber.objects.get(device_id=device_id) # Verifico che non sia già sottoscritto il canale (nel caso rispondo semplicemente con 200 OK) subscription = SubscriberManager().get_subscription( channel.name, asking_subscriber.sub_type, device_id) if subscription is None: if channel.kind == PUBLIC: SubscriberManager().subscribe(channel.name, asking_subscriber.sub_type, device_id, asking_subscriber.token) # Inc num subscriptions channel.subscriptions = channel.subscriptions + 1 channel.save() return SubscribeResponse.SUBSCRIBED elif channel.kind == PRIVATE: # Viene creata la richiesta di subscription # e al cliamante la risposta sarà NOT_AUTHORIZED if not ChannelSubscribeRequest.objects.filter( device_id=device_id).filter(channel=channel).exists(): subscribe_request = ChannelSubscribeRequest( device_id=device_id, channel=channel, status=PENDING) subscribe_request.save() # Segnalazione via mail all'owner del canale send_authrequest_email(channel, asking_subscriber) return SubscribeResponse.REQUEST_SEND except Subscriber.DoesNotExist: return SubscribeResponse.ERROR
def get(self, request, device_id=None): suggestion = get_suggested_channels() if device_id is not None: # Vengono rimossi dai suggeriti quelli già sottoscritti channel_names = SubscriberManager().get_device_subscriptions( device_id) suggestion = [ sugg for sugg in suggestion if not sugg.name.lower() in channel_names ] serializer = ChannelSerializer(suggestion, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request, format=None): serializer = SubscriberSerializer(data=request.DATA) if serializer.is_valid(): is_sandbox = (True if settings.ENVIRONMENT == "dev" else False) subscriber_data = serializer.object subscriber, created = Subscriber.objects.get_or_create( device_id=subscriber_data["device_id"], defaults={ 'sub_type': subscriber_data["sub_type"], 'sandbox': is_sandbox, 'enabled': True, 'name': subscriber_data["name"], 'token': subscriber_data["token"] }) if not created: subscriber.token = subscriber_data["token"] subscriber.name = subscriber_data["name"] subscriber.save() # Update del token nelle subscription del device subMamager = SubscriberManager() channel_subscriptions = subMamager.get_device_subscriptions( subscriber_data["device_id"]) for channel_sub in channel_subscriptions: subMamager.subscribe(channel_sub, subscriber_data["sub_type"], subscriber_data["device_id"], subscriber_data["token"]) return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def push_messages(pmsg, channel_name, platform): """ :param pmsg: Message to push :param channel_name: Channel to push :param platform: Target platform """ sub_tokens = SubscriberManager().get_subscribers(channel_name, platform) logger.info("Pushing {0} tokens to channel {1} for platform {2}".format( len(sub_tokens), channel_name, platform)) # PUSH EFFETTIVO pusher = PushProviderFactory.create(platform, logger) pusher.pushMessage(pmsg, sub_tokens, channel_name)
def get_device_subscriptions(device_id): """ get all channel subscribed by a device :param device_id: """ channel_names = SubscriberManager().get_device_subscriptions(device_id) # Uso ChannelSubscribeRequestSerializer e quelli già sottoscritti li aggiungo fake come ACCEPTED channels = Channel.objects.filter(name__in=channel_names) subscribed = [ ChannelSubscribeRequest(channel=ch, device_id=device_id, status=ACCEPTED) for ch in channels ] # Le richieste visualizzate client side sono solo quelle requests = ChannelSubscribeRequest.objects.filter( device_id=device_id).filter(status=PENDING) return subscribed + list(requests)
def get(self, request, format=None, message_id=None, device_id=None): if message_id != None: obj = get_object_or_404(ChannelMsg, pk=message_id) serializer = ChannelMsgSerializer(obj) return Response(serializer.data, status=status.HTTP_200_OK) if device_id != None: channel_names = SubscriberManager().get_device_subscriptions(device_id) # Nota: verificare come gestire la casistica di risultati molto ampi, introdotto inanto il throttling per limitare messages = ChannelMsg.objects.filter(Q(expire__isnull=True) | Q(expire__gte=datetime.utcnow())).filter( channel__name__in=channel_names) serializer = ChannelMsgSerializer(messages, many=True) return Response(serializer.data, status=status.HTTP_200_OK) return Response(status=status.HTTP_404_NOT_FOUND)
def get(self, request, format=None, deviceId=None): channel_names = SubscriberManager().get_device_subscriptions(deviceId) # Uso ChannelSubscribeRequestSerializer e quelli già sottoscritti li aggiungo fake come ACCEPTED channels = Channel.objects.filter(name__in=channel_names) subscribed = [ ChannelSubscribeRequest(channel=ch, device_id=deviceId, status=ACCEPTED) for ch in channels ] # Le richieste visualizzate client side sono solo quelle requests = ChannelSubscribeRequest.objects.filter( device_id=deviceId).filter(status=PENDING) serializer = ChannelSubscribeRequestSerializer(subscribed + list(requests), many=True) return Response(serializer.data)
def get(self, request, channel_name=None): if channel_name is None: user_channels = request.user.channels return render_to_response('my_channels.html', dict(user_channels=user_channels.all()), context_instance=RequestContext(request) ) else: channels = Channel.objects.filter(owner=request.user).filter(name=channel_name) tokens = SubscriberManager().get_all_subscribers(channel_name)[:10] subscribers = Subscriber.objects.filter(token__in=tokens) requests = ChannelSubscribeRequest.objects.filter(channel=channels[0]) return render_to_response('my_channel-view.html', { 'channel': channels[0], 'subscribers': subscribers, 'requests': requests, }, context_instance=RequestContext(request) )
def setUp(self): settings.REDIS_DB = 15 # Db usato per i test SubscriberManager().flushdb()
def setUp(self): settings.REDIS_DB = 15 # Db usato per i test settings.ENVIRONMENT = "dev" SubscriberManager().flushdb()