Added twitter auto notifications
This commit is contained in:
parent
4901468275
commit
c26448a1e9
|
@ -9,7 +9,7 @@ from django.db.models.signals import pre_save, post_save
|
||||||
|
|
||||||
# amiibo
|
# amiibo
|
||||||
from .handlers import (
|
from .handlers import (
|
||||||
pre_check_price_change, post_check_price_change,
|
post_check_price_change,
|
||||||
save_historical_price
|
save_historical_price
|
||||||
)
|
)
|
||||||
from .signals import amiibo_price_changed
|
from .signals import amiibo_price_changed
|
||||||
|
@ -21,9 +21,6 @@ class AmiiboAppConfig(AppConfig):
|
||||||
def ready(self):
|
def ready(self):
|
||||||
AmiiboPrice = self.get_model('AmiiboPrice')
|
AmiiboPrice = self.get_model('AmiiboPrice')
|
||||||
|
|
||||||
# pre_save.connect(pre_check_price_change,
|
|
||||||
# sender=AmiiboPrice)
|
|
||||||
|
|
||||||
post_save.connect(post_check_price_change,
|
post_save.connect(post_check_price_change,
|
||||||
sender=AmiiboPrice)
|
sender=AmiiboPrice)
|
||||||
|
|
||||||
|
|
|
@ -21,16 +21,16 @@ def save_historical_price(sender, instance, **kwargs):
|
||||||
instance.save_history(old_price, new_price)
|
instance.save_history(old_price, new_price)
|
||||||
|
|
||||||
|
|
||||||
def pre_check_price_change(sender, instance, **kwargs):
|
|
||||||
instance.old_price = copy.deepcopy(instance.price)
|
|
||||||
|
|
||||||
|
|
||||||
def post_check_price_change(sender, instance, created, **kwargs):
|
def post_check_price_change(sender, instance, created, **kwargs):
|
||||||
if instance.price != instance.old_price:
|
if (
|
||||||
|
instance.price != instance.old_price
|
||||||
|
or instance.stock != instance.old_stock
|
||||||
|
):
|
||||||
amiibo_price_changed.send(
|
amiibo_price_changed.send(
|
||||||
sender=instance.__class__,
|
sender=instance.__class__,
|
||||||
instance=instance,
|
instance=instance,
|
||||||
amiibo=instance.amiibo_shop.amiibo,
|
amiibo=instance.amiibo_shop.amiibo,
|
||||||
|
old_stock=instance.old_stock,
|
||||||
old_price=instance.old_price,
|
old_price=instance.old_price,
|
||||||
new_price=instance.price
|
new_price=instance.price
|
||||||
)
|
)
|
||||||
|
|
|
@ -141,12 +141,14 @@ class AmiiboPrice(models.Model):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(AmiiboPrice, self).__init__(*args, **kwargs)
|
super(AmiiboPrice, self).__init__(*args, **kwargs)
|
||||||
self.old_price = self.price
|
self.old_price = self.price
|
||||||
|
self.old_stock = self.stock
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'{} price for {}: {}{}'.format(
|
return u'{} price for {}: {}{}'.format(
|
||||||
self.amiibo.name,
|
self.amiibo_shop.amiibo.name,
|
||||||
self.shop.name,
|
self.amiibo_shop.shop.name,
|
||||||
self.price, self.currency
|
self.price,
|
||||||
|
self.currency
|
||||||
)
|
)
|
||||||
|
|
||||||
def fetch(self):
|
def fetch(self):
|
||||||
|
|
|
@ -8,5 +8,10 @@ from django import dispatch
|
||||||
|
|
||||||
|
|
||||||
amiibo_price_changed = dispatch.Signal(
|
amiibo_price_changed = dispatch.Signal(
|
||||||
providing_args=["instance", "amiibo", "old_price", "new_price"]
|
providing_args=[
|
||||||
|
"instance",
|
||||||
|
"amiibo",
|
||||||
|
"old_stock",
|
||||||
|
"old_price", "new_price"
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
||||||
|
default_app_config = 'amiibofindr.apps.notifications.apps.NotificationsAppConfig'
|
|
@ -0,0 +1,16 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# django
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# 3rd party
|
||||||
|
import reversion
|
||||||
|
|
||||||
|
# notifications
|
||||||
|
from .models import AmiiboNotification
|
||||||
|
|
||||||
|
|
||||||
|
class AmiiboNotificationAdmin(reversion.VersionAdmin):
|
||||||
|
filter_horizontal = ('shops', )
|
||||||
|
|
||||||
|
admin.site.register(AmiiboNotification, AmiiboNotificationAdmin)
|
|
@ -0,0 +1,25 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# django
|
||||||
|
from django.apps import AppConfig
|
||||||
|
from django.db.models.signals import pre_save, post_save
|
||||||
|
|
||||||
|
# project
|
||||||
|
from amiibofindr.apps.amiibo.signals import amiibo_price_changed
|
||||||
|
|
||||||
|
# notifications
|
||||||
|
from .handlers import launch_notifications
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationsAppConfig(AppConfig):
|
||||||
|
name = 'amiibofindr.apps.notifications'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
AmiiboNotification = self.get_model('AmiiboNotification')
|
||||||
|
|
||||||
|
amiibo_price_changed.connect(
|
||||||
|
launch_notifications
|
||||||
|
)
|
|
@ -0,0 +1,4 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
|
@ -0,0 +1,60 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
# django
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
# notifications
|
||||||
|
from .services.twitter import TwitterService
|
||||||
|
|
||||||
|
|
||||||
|
def launch_notifications(sender, instance, amiibo, old_price, new_price, **kwargs):
|
||||||
|
notifications = amiibo.notifications.all()
|
||||||
|
|
||||||
|
for notification in notifications:
|
||||||
|
shops_count = notification.shops.count()
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
shops_count > 0
|
||||||
|
and notification.shops.filter(pk__in=[instance.amiibo_shop.pk])
|
||||||
|
)
|
||||||
|
or shops_count == 0
|
||||||
|
):
|
||||||
|
notify = True
|
||||||
|
|
||||||
|
# Check if new price is lower than the notification price
|
||||||
|
if new_price > notification.max_price:
|
||||||
|
notify = False
|
||||||
|
|
||||||
|
if instance.stock is False:
|
||||||
|
notify = False
|
||||||
|
|
||||||
|
# Check if we already posted a notification in the given interval
|
||||||
|
print(notification.__dict__)
|
||||||
|
print(timezone.now()-timedelta(seconds=notification.interval))
|
||||||
|
if (
|
||||||
|
notification.last_notification
|
||||||
|
and notification.last_notification > timezone.now() - timedelta(seconds=notification.interval)
|
||||||
|
):
|
||||||
|
notify = False
|
||||||
|
|
||||||
|
print(notify)
|
||||||
|
|
||||||
|
if notify:
|
||||||
|
message = "{} {} {}{} - {}".format(
|
||||||
|
amiibo.name_eu,
|
||||||
|
instance.amiibo_shop.shop.name,
|
||||||
|
new_price,
|
||||||
|
instance.currency,
|
||||||
|
instance.amiibo_shop.get_url(),
|
||||||
|
)
|
||||||
|
|
||||||
|
if notification.notify_twitter:
|
||||||
|
twitter = TwitterService()
|
||||||
|
twitter.send(message)
|
||||||
|
|
||||||
|
notification.last_notification = timezone.now()
|
||||||
|
notification.save()
|
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('amiibo', '0017_auto_20150625_1806'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AmiiboNotification',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
|
('max_price', models.DecimalField(null=True, max_digits=6, decimal_places=2)),
|
||||||
|
('interval', models.PositiveIntegerField(default=3600)),
|
||||||
|
('notify_twitter', models.BooleanField(default=True)),
|
||||||
|
('last_notification', models.DateTimeField(null=True, blank=True)),
|
||||||
|
('amiibo', models.ForeignKey(related_name='notifications', to='amiibo.Amiibo')),
|
||||||
|
('shops', models.ManyToManyField(to='amiibo.AmiiboShop', blank=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,18 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# django
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class AmiiboNotification(models.Model):
|
||||||
|
amiibo = models.ForeignKey('amiibo.Amiibo', related_name='notifications')
|
||||||
|
max_price = models.DecimalField(max_digits=6, decimal_places=2, null=True)
|
||||||
|
interval = models.PositiveIntegerField(default=60*60)
|
||||||
|
shops = models.ManyToManyField('amiibo.AmiiboShop', blank=True)
|
||||||
|
|
||||||
|
notify_twitter = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
last_notification = models.DateTimeField(blank=True, null=True)
|
|
@ -0,0 +1,20 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# django
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
# 3rd party
|
||||||
|
import tweepy
|
||||||
|
|
||||||
|
class TwitterService(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.auth = tweepy.OAuthHandler(
|
||||||
|
settings.CONSUMER_KEY, settings.CONSUMER_SECRET)
|
||||||
|
self.auth.set_access_token(settings.ACCESS_TOKEN, settings.ACCESS_SECRET)
|
||||||
|
self.api = tweepy.API(self.auth)
|
||||||
|
|
||||||
|
def send(self, message):
|
||||||
|
self.api.update_status(status=message)
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,4 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
|
@ -0,0 +1,4 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# py3
|
||||||
|
from __future__ import unicode_literals
|
|
@ -49,6 +49,7 @@ INSTALLED_APPS = (
|
||||||
'amiibofindr.apps.amiibo',
|
'amiibofindr.apps.amiibo',
|
||||||
'amiibofindr.apps.shop',
|
'amiibofindr.apps.shop',
|
||||||
'amiibofindr.apps.home',
|
'amiibofindr.apps.home',
|
||||||
|
'amiibofindr.apps.notifications',
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
|
|
|
@ -23,5 +23,5 @@ MEDIA_ROOT = '/vagrant/media'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from local_settings import *
|
from local_settings import *
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
pass
|
print(e)
|
||||||
|
|
Loading…
Reference in New Issue