add push
This commit is contained in:
parent
fa875390dc
commit
50e613b123
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
from polls.models import Notice
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
@ -1716,6 +1717,12 @@ def news_management_create(request):
|
|||
|
||||
news = News(type=t, title=title, author=author, date=date, content=content, source=source, image=image)
|
||||
news.save()
|
||||
if t== 5:
|
||||
profiles = Userprofile.objects.filter(status=1)
|
||||
for p in profiles:
|
||||
content = '%s发布了通知,请查收消息' % (p, )
|
||||
Notice.create_news_notice(p.user_id, content, news.id)
|
||||
|
||||
messages.success(request, '添加成功!!!')
|
||||
return HttpResponseRedirect('/management/news/management/create/')
|
||||
type = News.NEWMEDIA_NEWS_CHOICES
|
||||
|
|
|
@ -36,6 +36,7 @@ class VerifyCode(models.Model):
|
|||
NOTICE_TYPE_CHOICES = (
|
||||
(0, 'normal'),
|
||||
(1, 'reply'),
|
||||
(2, 'news')
|
||||
)
|
||||
|
||||
|
||||
|
@ -47,6 +48,8 @@ class Notice(models.Model):
|
|||
content = models.CharField('内容', max_length=256, null=False)
|
||||
group_id = models.CharField(
|
||||
'group_id', max_length=256, null=True, blank=True)
|
||||
news_id = models.CharField(
|
||||
'news_id', max_length=256, null=True, blank=True)
|
||||
app = models.CharField('app', max_length=256, null=True, blank=True)
|
||||
model = models.CharField('model', max_length=256, null=True, blank=True)
|
||||
field = models.CharField('field', max_length=256, null=True, blank=True)
|
||||
|
@ -72,6 +75,10 @@ class Notice(models.Model):
|
|||
def create_normal_notice(cls, user_id, content, group_id):
|
||||
return Notice.objects.create(user_id=user_id, content=content, group_id=group_id)
|
||||
|
||||
@classmethod
|
||||
def create_news_notice(cls, user_id, content, news_id):
|
||||
return Notice.objects.create(user_id=user_id, content=content, news_id=news_id)
|
||||
|
||||
@classmethod
|
||||
def create_reply_notice(cls, user_id, content, app, model, field, record_id, record_pass_value, record_reject_value):
|
||||
return Notice.objects.create(type=1, user_id=user_id, content=content, app=app, model=model, field=field, record_id=record_id, record_pass_value=record_pass_value, record_reject_value=record_reject_value)
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
ERR_OK = 0
|
||||
ERR_PARAM = -1
|
||||
ERR_TIMESTAMP = -2
|
||||
ERR_SIGN = -3
|
||||
ERR_INTERNAL = -4
|
||||
ERR_HTTP = -100
|
||||
ERR_RETURN_DATA = -101
|
||||
|
||||
ENV_PROD = 1
|
||||
ENV_DEV = 2
|
||||
|
||||
MESSAGE_TYPE_ANDROID_NOTIFICATION = 1
|
||||
MESSAGE_TYPE_ANDROID_MESSAGE = 2
|
||||
MESSAGE_TYPE_IOS_APNS_NOTIFICATION = 11
|
||||
MESSAGE_TYPE_IOS_REMOTE_NOTIFICATION = 12
|
||||
|
||||
|
||||
#tnps
|
||||
class ClickAction(object):
|
||||
TYPE_ACTIVITY = 1
|
||||
TYPE_URL = 2
|
||||
TYPE_INTENT = 3
|
||||
|
||||
def __init__(self, actionType=1, url='', confirmOnUrl=0, activity='', intent=''):
|
||||
self.actionType = actionType
|
||||
self.url = url
|
||||
self.confirmOnUrl = confirmOnUrl
|
||||
self.activity = activity
|
||||
self.intent = intent
|
||||
self.intentFlag = 0
|
||||
self.pendingFlag = 0
|
||||
self.packageName = ""
|
||||
self.packageDownloadUrl = ""
|
||||
self.confirmOnPackage = 1
|
||||
|
||||
def GetObject(self):
|
||||
ret = {}
|
||||
ret['action_type'] = self.actionType
|
||||
if self.TYPE_ACTIVITY == self.actionType:
|
||||
ret['activity'] = self.activity
|
||||
ret['aty_attr'] = {'if' :self.intentFlag, 'pf' :self.pendingFlag}
|
||||
elif self.TYPE_URL == self.actionType:
|
||||
ret['browser'] = {'url' :self.url, 'confirm' :self.confirmOnUrl}
|
||||
elif self.TYPE_INTENT == self.actionType:
|
||||
ret['intent'] = self.intent
|
||||
|
||||
return ret
|
||||
|
||||
class Style(object):
|
||||
N_INDEPENDENT = 0
|
||||
N_THIS_ONLY = -1
|
||||
|
||||
def __init__(self, builderId=0, ring=0, vibrate=0, clearable=1, nId=N_INDEPENDENT):
|
||||
self.builderId = builderId
|
||||
self.ring = ring
|
||||
self.vibrate = vibrate
|
||||
self.clearable = clearable
|
||||
self.nId = nId
|
||||
self.ringRaw = ""
|
||||
self.lights = 1
|
||||
self.iconType = 0
|
||||
self.iconRes = ""
|
||||
self.styleId = 1
|
||||
self.smallIcon = ""
|
||||
|
||||
class TimeInterval(object):
|
||||
STR_START = 'start'
|
||||
STR_END = 'end'
|
||||
STR_HOUR = 'hour'
|
||||
STR_MIN = 'min'
|
||||
|
||||
def __init__(self, startHour=0, startMin=0, endHour=0, endMin=0):
|
||||
self.startHour = startHour
|
||||
self.startMin = startMin
|
||||
self.endHour = endHour
|
||||
self.endMin = endMin
|
||||
|
||||
def _isValidTime(self, hour, minute):
|
||||
return isinstance(hour, int) and isinstance(minute, int) and hour >= 0 and hour <=23 and minute >=0 and minute <= 59
|
||||
|
||||
def _isValidInterval(self):
|
||||
return self.endHour * 60 + self.endMin >= self.startHour * 60 + self.startMin
|
||||
|
||||
def GetObject(self):
|
||||
if not (self._isValidTime(self.startHour, self.startMin) and self._isValidTime(self.endHour, self.endMin)):
|
||||
return None
|
||||
if not self._isValidInterval():
|
||||
return None
|
||||
return {
|
||||
self.STR_START:{self.STR_HOUR:str(self.startHour), self.STR_MIN:str(self.startMin)},
|
||||
self.STR_END:{self.STR_HOUR:str(self.endHour), self.STR_MIN:str(self.endMin)}
|
||||
}
|
||||
|
||||
class Message(object):
|
||||
"""
|
||||
待推送的消息, Android系统专用
|
||||
"""
|
||||
PUSH_SINGLE_PKG = 0
|
||||
PUSH_ACCESS_ID = 1
|
||||
|
||||
def __init__(self):
|
||||
self.title = ""
|
||||
self.content = ""
|
||||
self.expireTime = 0
|
||||
self.sendTime = ""
|
||||
self.acceptTime = ()
|
||||
self.type = 0
|
||||
self.style = None
|
||||
self.action = None
|
||||
self.custom = {}
|
||||
self.multiPkg = self.PUSH_SINGLE_PKG
|
||||
self.raw = None
|
||||
self.loopTimes = 0
|
||||
self.loopInterval = 0
|
||||
|
||||
def GetMessageObject(self):
|
||||
if self.raw is not None:
|
||||
if isinstance(self.raw, basestring):
|
||||
return json.loads(self.raw)
|
||||
else:
|
||||
return self.raw
|
||||
|
||||
message = {}
|
||||
message['title'] = self.title
|
||||
message['content'] = self.content
|
||||
|
||||
# TODO: check custom
|
||||
message['custom_content'] = self.custom
|
||||
|
||||
acceptTimeObj = self.GetAcceptTimeObject()
|
||||
if None == acceptTimeObj:
|
||||
return None
|
||||
elif acceptTimeObj != []:
|
||||
message['accept_time'] = acceptTimeObj
|
||||
|
||||
if self.type == MESSAGE_TYPE_ANDROID_NOTIFICATION:
|
||||
if None == self.style:
|
||||
style = Style()
|
||||
else:
|
||||
style = self.style
|
||||
|
||||
if isinstance(style, Style):
|
||||
message['builder_id'] = style.builderId
|
||||
message['ring'] = style.ring
|
||||
message['vibrate'] = style.vibrate
|
||||
message['clearable'] = style.clearable
|
||||
message['n_id'] = style.nId
|
||||
message['ring_raw'] = style.ringRaw
|
||||
message['lights'] = style.lights
|
||||
message['icon_type'] = style.iconType
|
||||
message['icon_res'] = style.iconRes
|
||||
message['style_id'] = style.styleId
|
||||
message['small_icon'] = style.smallIcon
|
||||
else:
|
||||
# style error
|
||||
return None
|
||||
|
||||
if None == self.action:
|
||||
action = ClickAction()
|
||||
else:
|
||||
action = self.action
|
||||
|
||||
if isinstance(action, ClickAction):
|
||||
message['action'] = action.GetObject()
|
||||
else:
|
||||
# action error
|
||||
return None
|
||||
elif self.type == MESSAGE_TYPE_ANDROID_MESSAGE:
|
||||
pass
|
||||
else:
|
||||
return None
|
||||
|
||||
return message
|
||||
|
||||
def GetAcceptTimeObject(self):
|
||||
ret = []
|
||||
for ti in self.acceptTime:
|
||||
if isinstance(ti, TimeInterval):
|
||||
o = ti.GetObject()
|
||||
if o is None:
|
||||
return None
|
||||
else:
|
||||
ret.append(ti.GetObject())
|
||||
else:
|
||||
return None
|
||||
return ret
|
||||
|
||||
class MessageIOS(Message):
|
||||
"""
|
||||
待推送的消息, iOS系统专用
|
||||
"""
|
||||
def __init__(self):
|
||||
Message.__init__(self)
|
||||
self.alert = None
|
||||
self.badge = None
|
||||
self.sound = None
|
||||
self.category = None
|
||||
self.raw = None
|
||||
self.type = MESSAGE_TYPE_IOS_APNS_NOTIFICATION
|
||||
|
||||
def GetMessageObject(self):
|
||||
if self.raw is not None:
|
||||
if isinstance(self.raw, basestring):
|
||||
try:
|
||||
return json.loads(self.raw)
|
||||
except Exception:
|
||||
return None
|
||||
elif isinstance(self.raw, dict):
|
||||
return self.raw
|
||||
else:
|
||||
return None
|
||||
|
||||
message = self.custom
|
||||
|
||||
acceptTimeObj = self.GetAcceptTimeObject()
|
||||
if None == acceptTimeObj:
|
||||
return None
|
||||
elif acceptTimeObj != []:
|
||||
message['accept_time'] = acceptTimeObj
|
||||
|
||||
aps = {}
|
||||
if self.type == MESSAGE_TYPE_IOS_APNS_NOTIFICATION:
|
||||
if isinstance(self.alert, basestring) or isinstance(self.alert, dict):
|
||||
aps['alert'] = self.alert
|
||||
else:
|
||||
# alert type error
|
||||
return None
|
||||
if self.badge is not None:
|
||||
aps['badge'] = self.badge
|
||||
if self.sound is not None:
|
||||
aps['sound'] = self.sound
|
||||
if self.category is not None:
|
||||
aps['category'] = self.category
|
||||
elif self.type == MESSAGE_TYPE_IOS_REMOTE_NOTIFICATION:
|
||||
aps['content-available'] = 1
|
||||
else: # type error
|
||||
return None
|
||||
message['aps'] = aps
|
||||
return message
|
||||
|
||||
|
||||
class MessageStatus(object):
|
||||
"""
|
||||
推送任务的状态
|
||||
"""
|
||||
def __init__(self, status, startTime):
|
||||
self.status = status
|
||||
self.startTime = startTime
|
||||
|
||||
def __str__(self):
|
||||
return str(vars(self))
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
|
@ -11,8 +11,8 @@ def process_notify_task():
|
|||
start = time.process_time()
|
||||
notices = Notice.objects.filter(is_read=False)
|
||||
for n in notices:
|
||||
two_hours_later = n.added + timedelta(minutes=2)
|
||||
four_hours_later = n.added + timedelta(minutes=4)
|
||||
two_hours_later = n.added + timedelta(minutes=120)
|
||||
four_hours_later = n.added + timedelta(minutes=240)
|
||||
now = datetime.now()
|
||||
phone = n.user.username
|
||||
today = now.date()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
import random
|
||||
from parsel import Selector
|
||||
from channels.db import database_sync_to_async
|
||||
|
@ -11,6 +12,24 @@ from aliyunsdkcore.client import AcsClient
|
|||
import uuid
|
||||
from aliyunsdkcore.profile import region_provider
|
||||
|
||||
|
||||
def send_tnps(phones, content):
|
||||
|
||||
url = 'https://api.tpns.tencent.com//v3/push/app'
|
||||
r = requests.post(url,
|
||||
auth=HTTPBasicAuth(
|
||||
'1500015491', 'd5c793535529b6dc55d00b22302bad64'),
|
||||
json={
|
||||
"audience_type": "account_list",
|
||||
"account_list": phones,
|
||||
"message": {
|
||||
"title": "【新媒体管理】有新消息",
|
||||
"content": content
|
||||
},
|
||||
"message_type": "notify"
|
||||
})
|
||||
|
||||
|
||||
def sent_sms_code(phone, code):
|
||||
clnt = YunpianClient('304eb08353f7ebf00596737acfc31f53')
|
||||
param = {YC.MOBILE: phone,
|
||||
|
@ -35,6 +54,7 @@ acs_client = AcsClient("LTAI4GDaSp41vp1X4mCb7uCa",
|
|||
region_provider.add_endpoint(
|
||||
"Dyvmsapi", "cn-hangzhou", "dyvmsapi.aliyuncs.com")
|
||||
|
||||
|
||||
def send_voice_notify(phone, type):
|
||||
business_id = uuid.uuid4()
|
||||
ttsRequest = SingleCallByTtsRequest.SingleCallByTtsRequest()
|
||||
|
@ -52,6 +72,7 @@ def send_voice_notify(phone, type):
|
|||
ttsResponse = acs_client.do_action_with_exception(ttsRequest)
|
||||
return ttsResponse
|
||||
|
||||
|
||||
def generate_code():
|
||||
return random.randint(1000, 9999)
|
||||
|
||||
|
@ -131,6 +152,7 @@ def queryset_to_list(q, fields):
|
|||
l.append(r)
|
||||
return l
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# r = sent_sms_code('13993199566', 4321)
|
||||
# print(r.code(), type(r.code()))
|
||||
|
|
Loading…
Reference in New Issue