add celery to push message(async)
diff --git a/book/Util/conf.py b/book/Util/conf.py
index c2a0843..59f63aa 100644
--- a/book/Util/conf.py
+++ b/book/Util/conf.py
@@ -1,5 +1,8 @@
# please put your app_key and master_secret here
#app_key = u'65ad21e7cb76e1b60bcc237f'
#master_secret = u'f9e78a98c0d996e527fea4aa'
+'''
+we get app_key and master_secret from Jpush Server
+'''
app_key = u'77f80ebef5571a87bc17f616'
master_secret = u'c2de5c19b0a146646ea42bda'
diff --git a/book/Util/tasks.py b/book/Util/tasks.py
new file mode 100644
index 0000000..56a01f2
--- /dev/null
+++ b/book/Util/tasks.py
@@ -0,0 +1,147 @@
+#coding = utf-8
+'''
+This function of this file:
+1. modify the alias or tags of device
+2. push message by registerId or alise or tags
+3. adopt celery Using an asyncchronous manner to push message by share_task
+ for the detailed info: please read the link below:
+ http://www.jianshu.com/p/1840035cb510
+ http://shangliuyan.github.io/2015/07/04/celery%E6%9C%89%E4%BB%80%E4%B9%88%E9%9A%BE%E7%90%86%E8%A7%A3%E7%9A%84/
+'''
+
+from __future__ import absolute_import
+from .conf import app_key, master_secret
+from celery import shared_task
+from jpush import common
+import jpush as jpush
+#regid = "18071adc030bb6dd31d"
+
+
+def jpushCreateDevice():
+ _jpush = jpush.JPush(app_key, master_secret)
+ device = _jpush.create_device()
+ _jpush.set_logging("DEBUG")
+
+ return device
+
+@shared_task
+def add(x, y):
+ return x+y
+
+@shared_task
+def jpushDeviceSetAlias(regid, alias):
+ device = jpushCreateDevice()
+ entity = jpush.device_alias(alias)
+ result = device.set_devicemobile(regid, entity)
+ return result.status_code
+
+@shared_task
+def jpushDeviceClearAlias(regid, alias):
+ device = jpushCreateDevice()
+ entity = jpush.device_alias("")
+ result = device.set_deviceinfo(regid, entity)
+ return result.status_code
+
+@shared_task
+def jpushDeviceSetTag(regid, tags):
+ device = jpushCreateDevice()
+ entity = jpush.device_tag(jpush.add(tags))
+ result = device.set_devicemobile(regid, entity)
+ return result.status_code
+
+@shared_task
+def jpushDeviceSetTag(regid, tags):
+ device = jpushCreateDevice()
+ entity = jpush.device_tag("")
+ result = device.set_deviceinfo(regid, entity)
+ return result.status_code
+
+@shared_task
+def jpushDeviceSetAliasAndTag(regid, tags, alias):
+ result1 = jpushDeviceSetAlias(regid, alias)
+ result2 = jpushDeviceSetTag(regid, tags)
+
+ return result1 and result2
+
+''' push operation '''
+
+@shared_task
+def jpushCreateClient():
+ _jpush = jpush.JPush(app_key, master_secret)
+ push = _jpush.create_push()
+ push.platform = jpush.all_
+
+ return push
+
+@shared_task
+def jushPushMessageToJiGuang(push):
+ try:
+ response=push.send()
+ except common.Unauthorized:
+ raise common.Unauthorized("Unauthorized")
+ except common.APIConnectionException:
+ raise common.APIConnectionException("conn")
+ except common.JPushFailure:
+ print ("JPushFailure")
+ except:
+ print ("Exception")
+
+ return response
+
+@shared_task
+def jpushMessageWithRegId(regid, msg, action):
+ push = jpushCreateClient()
+ push.audience = jpush.audience(
+ jpush.registration_id(regid)
+ )
+ push.notification = jpush.notification(android=jpush.android(alert=action, extras=msg))
+ print msg, push.notification
+ resp = jushPushMessageToJiGuang(push)
+ return resp
+
+@shared_task
+def jpushMessageWithTags(tags, msg, action):
+ push = jpushCreateClient()
+ push.audience = jpush.audience(
+ jpush.tag(tags)
+ )
+ push.notification = jpush.notification(android=jpush.android(alert=action, extras=msg))
+ resp = jushPushMessageToJiGuang(push)
+ return resp
+
+
+@shared_task
+def jpushMessageWithAlias(alias, msg, action):
+ push = jpushCreateClient()
+ push.audience = jpush.audience(
+ jpush.alias(alias)
+ )
+ push.notification = jpush.notification(android=jpush.android(alert=action, extras=msg))
+ resp = jushPushMessageToJiGuang(push)
+ return resp
+
+@shared_task
+def jpushMessageWithAliasTag(alias, tags, msg, action):
+ print "xxx"
+ push = jpushCreateClient()
+ push.audience = jpush.audience(
+ jpush.alias(alias),
+ jpush.tag(tags)
+ )
+ push.notification = jpush.notification(android=jpush.android(alert=action, extras=msg))
+ resp = jushPushMessageToJiGuang(push)
+ return resp
+
+@shared_task
+def jpushMessageAllUser(action, msg):
+ push = jpushCreateClient()
+ push.audience = jpush.all_
+ push.notification = jpush.notification(android=jpush.android(alert=action, extras=msg))
+ resp = jushPushMessageToJiGuang(push)
+ return resp
+
+
+if __name__ == '__main__':
+#jpushDeviceSetAlias(regid, "xxx")
+ print jpushMessageAllUser('hello', {"112":"www"})
+ print jpushMessageWithRegId("1507bfd3f7cf3e96363", {}, "hello")
diff --git a/book/Util/upJiGuang.py b/book/Util/upJiGuang.py
index 4bcf81e..58ed11a 100644
--- a/book/Util/upJiGuang.py
+++ b/book/Util/upJiGuang.py
@@ -1,4 +1,7 @@
#coding = utf-8
+'''
+ block to push message to Jpush server without celery
+'''
from conf import app_key, master_secret
import jpush as jpush
from jpush import common
diff --git a/book/Util/util.py b/book/Util/util.py
index ed72bce..a6354b4 100644
--- a/book/Util/util.py
+++ b/book/Util/util.py
@@ -1,5 +1,8 @@
#coding = utf-8
-
+'''
+the function of this file:
+1. accomplish the common function
+'''
def getCacheKey(cacheTag, key_prefix, version):
return "".join([key_prefix, cacheTag, str(version)])
diff --git a/book/urls.py b/book/urls.py
index 011e159..23b5c33 100755
--- a/book/urls.py
+++ b/book/urls.py
@@ -1,4 +1,4 @@
-
+'''
from django.conf.urls import patterns, url
from book import views,vbook
from django.views.decorators.cache import cache_page
@@ -32,3 +32,37 @@
url(r'^getMessage/$',views.getEventComment, name = 'getEventComment'),
)
+'''
+
+from django.conf.urls import url
+from book import views,vbook
+from django.views.decorators.cache import cache_page
+from django.contrib import admin
+
+urlpatterns = [
+# user and shop
+ url(r'^regist/$',views.regist,name = 'regist'),
+ url(r'^login/$',views.login,name = 'login'),
+ url(r'^postRegisterID/$',views.postRegisterID,name = 'postRegisterID'),
+ url(r'^createShop/$',views.createShop, name = 'createShop'),
+ url(r'^modifyShop/$',views.modifyShop, name = 'modifyShop'),
+ url(r'^manageShop/$',views.manageShop, name = 'manageShop'),
+ url(r'^browseShop/$',views.browseShop, name = 'browseShop'),
+# book
+ url(r'^addBook/$',vbook.addBook, name = 'addBook'),
+ url(r'^getBook/$',vbook.getBook, name = 'getBook'),
+ url(r'^removeBook/$',vbook.removeBook, name = 'removeBook'),
+ url(r'^getBorrowBook/$',vbook.reqBorrowBook, name = 'borrowBook'),
+ url(r'^postBorrowAction/$',vbook.respBorrowAction, name = 'respBorrowBook'),
+ url(r'^returnBook/$',vbook.returnBook, name = 'returnBook'),
+ url(r'^getCurrentBorrowBook/$',vbook.getCurrentBorrowBook, name = 'currentBorrowBook'),
+ url(r'^getHistoryBorrowBook/$',vbook.getHistoryBorrowBook, name = 'HistoryBorrowBook'),
+# url(r'^modifyBook/$',views.modifyBook, name = 'modifyBook'),
+# url(r'^delBook/$',views.delBook, name = 'delBook'),
+# search
+ url(r'^searchBook/$',vbook.searchBook, name = 'searchBook'),
+ url(r'^searchArea/$',views.searchArea, name = 'searchArea'),
+# event
+ url(r'^checkMessage/$',views.checkEventCnt, name = 'checkEventCnt'),
+ url(r'^getMessage/$',views.getEventComment, name = 'getEventComment'),
+]
diff --git a/book/vbook.py b/book/vbook.py
index aca6a7d..08d1ce3 100644
--- a/book/vbook.py
+++ b/book/vbook.py
@@ -4,20 +4,30 @@
from django.forms.models import model_to_dict
from book.models import *
-from book.Util.upJiGuang import *
+#from book.Util.upJiGuang import *
+from book.Util.tasks import *
from book.Util.util import *
import simplejson
import random
import datetime
import logging
import sys
-#logger = logging.getLogger(__name__)
-logger = logging.getLogger("mysite")
+logger = logging.getLogger(__name__)
+#logger = logging.getLogger("mysite")
-
+'''
+function: get current time
+return: Time
+Notice: none
+'''
def getCurrentTime():
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+'''
+function: record footprint of borrowing book
+return: none
+Notice: please sync the status of APP
+'''
def recordToHistory(user, book_dict):
if book_dict['action'] == 'borrow':
if UserCurrentBorrow.checkIsExistThisBook(user.id, book_dict['owner'], book_dict['shop'], book_dict['book'], "borrowing"):
@@ -55,7 +65,11 @@
logger.info("no this action")
######################## B O O K #############################
-
+'''
+function: add book to database
+return: states
+Notice:invalid cache of shop
+'''
def addBook(request):
state = "fail"
dict = {}
@@ -84,8 +98,8 @@
imageurl = request.POST.get('imageurl', '')
extlink = request.POST.get('extlink', '')
book = Book.createBookRow(bookname, author, publisher, detail, shop.id, 1, isbn, "", imageurl, extlink)
- shop.Belong_Shop.add(book)
- shop.changeTag += 1
+# shop.Belong_Shop.add(book)
+ shop.changeTag += 1 # to invalid cache
shop.save()
state = 'success'
@@ -94,7 +108,11 @@
logger.info(dict)
return HttpResponse(json)
-
+'''
+function: get book
+return: state and the detailed info about book
+notice: none
+'''
def getBook(request):
state = "fail"
dict = {}
@@ -122,6 +140,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: delete book from database
+return: state
+notice: invalid cache
+'''
def removeBook(request):
state = "fail"
dict = {}
@@ -150,7 +173,11 @@
logger.info(dict)
return HttpResponse(json)
-
+'''
+function: request to borrow book
+return: state
+Notice: jpush
+'''
def reqBorrowBook(request):
state = "fail"
dict = {}
@@ -189,11 +216,11 @@
alert = borrower.name + u' 向你借书: <<'.encode('utf-8').decode('utf-8') + bookname + ">>"
logger.info(bookname)
logger.info(alert)
- jpushMessageWithRegId(owner.regid, msg, alert);
+ jpushMessageWithRegId.delay(owner.regid, msg, alert); # push message
#userEvent = UserEvent.objects.create(user_id=owner.id, owner=owner.name, borrower=borrower.name, \
# book=bookname, time=curtime, shop=shopname, action="borrow")
#recordToHistory(borrower, model_to_dict(userEvent))
-
+
recordToHistory(borrower, {'owner':owner.name,'shop':shopname, 'book':bookname, 'action':action, 'time':curtime})
state = 'success'
@@ -202,6 +229,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: response about borrowing request -- accept or refuse
+return: state
+notice: jpush
+'''
def respBorrowAction(request):
state = "fail"
dict = {}
@@ -239,7 +271,7 @@
msg['count'] = 1
#alert = owner.name + u' 同意借书请求'.encode('utf-8').decode('utf-8')
alert = owner.name + u' 同意借书: <<'.encode('utf-8').decode('utf-8') + bookname + ">>"
- jpushMessageWithRegId(borrower.regid, msg, alert);
+ jpushMessageWithRegId.delay(borrower.regid, msg, alert);
#userEvent = UserEvent.objects.create(user_id=borrower.id, owner=owner.name, borrower=fromname, book=bookname, time=curtime, shop=shopname, action=action)
#recordToHistory(borrower, model_to_dict(userEvent))
recordToHistory(borrower, {'owner':owner.name,'shop':shopname, 'book':bookname, 'action':action, 'time':curtime})
@@ -257,6 +289,12 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: return book by owner
+return: status
+notice: not communicate with borrower
+ invalid cache
+'''
def returnBook(request):
state = "fail"
dict = {}
@@ -299,6 +337,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: search book by name
+return:booklist
+notice: none
+'''
def searchBook(request):
state = None
dict = {}
@@ -328,6 +371,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: get history of borrowing book
+return: booklist that were borrowing
+Notice: none
+'''
def getCurrentBorrowBook(request):
state = "fail"
dict = {}
@@ -353,6 +401,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: get history of borrowed book
+return: booklist that were borrowed
+Notice: none
+'''
def getHistoryBorrowBook(request):
state = "fail"
dict = {}
diff --git a/book/views.py b/book/views.py
index d02baf4..6051826 100755
--- a/book/views.py
+++ b/book/views.py
@@ -4,8 +4,11 @@
from django.forms.models import model_to_dict
from django.core.cache import cache
from book.models import *
-from book.Util.upJiGuang import *
+#from book.Util.upJiGuang import *
+from book.Util.tasks import *
+#from book.Util.pushTask import *
from book.Util.util import *
+from bookStore import celery_app
import simplejson
import random
import datetime
@@ -14,29 +17,36 @@
# Get an instance of a logger
#logger = logging.getLogger(__name__)
+'''
+set log output to console or file
+modify the bookStore/setting.py
+'''
logger = logging.getLogger("mysite")
# Create your views here.
+'''
+function: regist new User with username and password
+return: state
+Notice: not support have the same username in the database"
+'''
def regist(request):
state = "fail"
dict = {}
+ add.delay(4,4)
logger.info(request.POST)
logger.info(os.getpid())
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
- #regid = request.POST.get('regid', '')
- #regid = "18071adc030bb6dd31d"
if User.checkIsExistWithName(username):
state = 'user_exist'
else:
User.createUserRow(username, password, username, "", "", username)
-# jpushResult = jpushDeviceSetAlias(regid, username)
+# jpushResult = jpushDeviceSetAlias(regid, username)
dict['token'] = username
-# print "==========? " + str(jpushResult)
-# dict['jpushResult'] = jpushResult
+# dict['jpushResult'] = jpushResult
state = 'success'
dict['result'] = state
@@ -44,6 +54,12 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: get regid from APP when user connect APP server
+ regid - APP can get it from Jpush server
+return: state
+Notice: none
+'''
def postRegisterID(request):
state = "fail"
dict = {}
@@ -67,7 +83,11 @@
logger.info(dict)
return HttpResponse(json)
-
+'''
+function: establish the connection between APP and Server throught Token
+return: token and state
+Notice: Token will randomly generate when user log in server
+'''
def login(request):
state = "fail"
dict = {}
@@ -82,12 +102,16 @@
if user is None:
state = 'not_exist_or_password_error'
else:
+ '''
+ Get shoplist when user log in server
+ Now only support one shop, so return the first shop of shoplist
+ '''
shops = User.getUserShops(user)
if shops is not None and len(shops):
fstShop = shops[0]
dict['shopname'] = fstShop.name
- token = User.setUserToken(user)
+ token = User.setUserToken(user) # regenerate the new token
dict['token'] = token
state = 'success'
@@ -98,7 +122,11 @@
######################## S H O P #############################
-
+'''
+function: create a new shop, and shop can't belong the shoplist of user
+return: state
+Notice: the shoplist can't have the same shop name
+'''
def createShop(request):
state = "fail"
dict = {}
@@ -127,7 +155,7 @@
addr = request.POST.get('shopaddr', '')
comment = request.POST.get('shopcomment', '')
shop = Shop.createShopRow(shopname, addr, comment, user.id, user.name, changeTag=0)
- user.Belong_user.add(shop)
+#user.Belong_user.add(shop)
state = 'success'
dict['result'] = state
@@ -135,6 +163,13 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: get the detailed information about shop
+return: state and booklist
+Notice: when cache valid, we will get result from cache, or we will read database and recache shop
+ when the status of book changes or add book or remove, we need invalid cache.
+'''
+
def manageShop(request):
state = "fail"
dict = {}
@@ -152,10 +187,17 @@
if shop is None:
state = 'this shop not in '+user.name
else:
+ '''
+ when between cache and database have difference, we should change changeTag to invalid cache - key
+ It's not good solution.
+ Because the value of originl cache have existed.
+ '''
shopVersion = shop.changeTag
cacheTag = request.get_full_path()
cacheKey = getCacheKey(cacheTag, key_prefix='shop', version=shopVersion)
cacheValue = cache.get(cacheKey, version=shopVersion)
+#cacheValue.state = 'xxxxxxxxxxxxxxx'
+# print cacheValue
#cacheValue = 0
if cacheValue:
json=simplejson.dumps(cacheValue)
@@ -180,6 +222,11 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: browse shop by username
+return: the booklist of this shop
+Notice: none
+'''
def browseShop(request):
state = "fail"
dict = {}
@@ -211,7 +258,11 @@
logger.info(dict)
return HttpResponse(json)
-
+'''
+function: modify shopname by old shopname
+return: state and new shopname
+Notice: none
+'''
def modifyShop(request):
state = "fail"
dict = {}
@@ -240,7 +291,11 @@
logger.info(dict)
return HttpResponse(json)
-
+'''
+function: get all area from contains the key string
+return: all area matched
+Notice: none
+'''
def searchArea(request):
state = "fail"
dict = {}
@@ -264,6 +319,9 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: deleted
+'''
def checkEventCnt(request):
state = None
dict = {}
@@ -285,6 +343,9 @@
logger.info(dict)
return HttpResponse(json)
+'''
+function: deleted
+'''
def getEventComment(request):
state = None
dict = {}
diff --git a/bookStore/__init__.py b/bookStore/__init__.py
index e69de29..b21edbb 100755
--- a/bookStore/__init__.py
+++ b/bookStore/__init__.py
@@ -0,0 +1,6 @@
+from __future__ import absolute_import
+
+# This will make sure the app is always imported when
+# Django starts so that shared_task will use this app.
+from .celery import app as celery_app # noqa
+__all__ = ['celery_app']
diff --git a/bookStore/celery.py b/bookStore/celery.py
new file mode 100644
index 0000000..bc32cb0
--- /dev/null
+++ b/bookStore/celery.py
@@ -0,0 +1,45 @@
+from __future__ import absolute_import
+
+import os
+
+from celery import Celery
+
+# set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookStore.settings')
+
+from django.conf import settings # noqa
+
+app = Celery('bookStore',
+ broker = 'redis://localhost',
+ backend = 'redis://localhost',
+ )
+
+
+# Using a string here means the worker will not have to
+# pickle the object when using Windows.
+app.config_from_object('django.conf:settings')
+app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print('Request: {0!r}'.format(self.request))
+
+'''
+from __future__ import absolute_import
+
+from celery import Celery
+
+app = Celery('proj',
+ broker = 'redis://localhost',
+ backend = 'redis://localhost',
+ include=['proj.tasks'])
+
+# Optional configuration, see the application user guide.
+app.conf.update(
+ CELERY_TASK_RESULT_EXPIRES=3600,
+ )
+
+if __name__ == '__main__':
+ app.start()
+'''
diff --git a/bookStore/settings.py b/bookStore/settings.py
index ae1f92e..c998558 100755
--- a/bookStore/settings.py
+++ b/bookStore/settings.py
@@ -39,6 +39,7 @@
#'online',
# 'management',
'book',
+ 'book.Util',
)
MIDDLEWARE_CLASSES = (
@@ -195,7 +196,7 @@
'disable_existing_loggers': False,
'formatters': {
'verbose': {
- 'format' : "[%(asctime)s] [%(name)s:%(funcName)s:%(lineno)s] [%(levelname)s]: %(message)s",
+ 'format' : "[%(asctime)s.%(msecs)03d] [%(name)s:%(funcName)s:%(lineno)s] [%(levelname)s]: %(message)s",
'datefmt' : "%d/%b/%Y %H:%M:%S"
},
'simple': {
@@ -216,9 +217,9 @@
},
'console': {
'level': 'INFO',
- 'filters': ['require_debug_false'],
+# 'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
- 'formatter': 'simple'
+ 'formatter': 'verbose'
},
'mail_admins': {
'level': 'ERROR',
@@ -238,7 +239,7 @@
'propagate': False,
},
'mysite': {
- 'handlers': ['file'],
+ 'handlers': ['console'],
'level': 'INFO',
},
}
diff --git a/bookStore/urls.py b/bookStore/urls.py
index 1bebfcd..0efb97c 100755
--- a/bookStore/urls.py
+++ b/bookStore/urls.py
@@ -1,3 +1,4 @@
+'''
from django.conf.urls import patterns, include, url
from django.contrib import admin
@@ -11,3 +12,13 @@
url(r'^book/', include('book.urls')),
url(r'^admin/', include(admin.site.urls)),
)
+'''
+
+
+from django.conf.urls import url,include
+from django.contrib import admin
+
+urlpatterns = [
+ url(r'^book/', include('book.urls')),
+ url(r'^admin/', include(admin.site.urls)),
+]