201 lines
7.1 KiB
Python
201 lines
7.1 KiB
Python
#coding: utf-8
|
|
# +-------------------------------------------------------------------
|
|
# | YakPanel
|
|
# +-------------------------------------------------------------------
|
|
# | Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
|
# +-------------------------------------------------------------------
|
|
# | Author: lotk
|
|
# | 邮局调用退订接口(免登录)
|
|
# +-------------------------------------------------------------------
|
|
|
|
import public,os,sys,db,time,json,re
|
|
|
|
|
|
try:
|
|
import jwt
|
|
except:
|
|
public.ExecShell('btpip install pyjwt')
|
|
import jwt
|
|
|
|
|
|
class mailUnsubscribe:
|
|
|
|
# 获取 SECRET_KEY
|
|
def get_SECRET_KEY(self):
|
|
path = '/www/server/panel/data/mail/jwt-secret.txt'
|
|
if not os.path.exists(path):
|
|
secretKey = public.GetRandomString(64)
|
|
public.writeFile(path, secretKey)
|
|
secretKey = public.readFile(path)
|
|
return secretKey
|
|
def M(self, table_name):
|
|
import db
|
|
sql = db.Sql()
|
|
sql._Sql__DB_FILE = '/www/vmail/postfixadmin.db'
|
|
sql._Sql__encrypt_keys = []
|
|
return sql.table(table_name)
|
|
def M3(self, table_name):
|
|
import db
|
|
sql = db.Sql()
|
|
sql._Sql__DB_FILE = '/www/vmail/mail_unsubscribe.db'
|
|
sql._Sql__encrypt_keys = []
|
|
return sql.table(table_name)
|
|
|
|
def Unsubscribe(self, get):
|
|
token = get.get('jwt', '')
|
|
if not token:
|
|
# return 'There is no token'
|
|
return public.returnJson(False, public.lang("There is no token"))
|
|
SECRET_KEY = self.get_SECRET_KEY()
|
|
try:
|
|
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
|
|
|
|
email = payload['email']
|
|
# etypename = payload['etypename'] # 邮件类型名
|
|
|
|
# 优先取用户设置的退订
|
|
untype = get.get('id', '')
|
|
if not untype:
|
|
# 兼容旧退订 邮件类型id
|
|
etypes = payload.get('etypes', '')
|
|
if not etypes:
|
|
etypes = payload.get('etype', '')
|
|
else:
|
|
etypes = untype
|
|
|
|
|
|
# 任务主题 发件时间 todo
|
|
subject = payload.get('subject', '')
|
|
send_time = payload.get('send_time', 0)
|
|
|
|
task_id = payload.get('task_id', 0) # 群发任务
|
|
|
|
args = public.dict_obj()
|
|
args.email = email
|
|
args.etypes = etypes
|
|
args.task_id = task_id
|
|
args.subject = subject
|
|
args.send_time = send_time
|
|
|
|
|
|
self.submit_recipient_blacklist(args)
|
|
|
|
# return public.lang("The unsubscribe of email {} is successful", email)
|
|
return {"status": True, "msg": public.lang("The unsubscribe of email {} is successful", email)}
|
|
except jwt.ExpiredSignatureError:
|
|
# return public.lang('Operation failed,The token expires')
|
|
return {"status": False, "msg": public.lang('Operation failed,The token expires')}
|
|
except jwt.InvalidTokenError:
|
|
# return public.lang('Operation failed,Invalid tokens')
|
|
# return abort(404)
|
|
|
|
return {"status": False, "msg": public.lang('Operation failed,Invalid tokens')}
|
|
except Exception as e:
|
|
return {"status": False, "msg": f"error: {e}"}
|
|
|
|
# 订阅调用 获取类型和邮箱 判断邮箱可用?(邮箱校验 校验后插入) 可用插入数据库 (邮箱校验和邮箱发送营销邮件)
|
|
def Subscribe(self, get):
|
|
etype = get.get('etype', '')
|
|
public.print_log('etype {}'.format(etype))
|
|
|
|
email = get.get('email', '')
|
|
public.print_log('email {}'.format(email))
|
|
|
|
# todo 验证邮箱 生成验证链接
|
|
|
|
|
|
# 查询类型存在
|
|
etype = int(etype)
|
|
with self.M('mail_type') as obj:
|
|
etype_exit = obj.where('id =?', etype).count()
|
|
if not etype_exit:
|
|
# 无对应类型跳过
|
|
return
|
|
|
|
# 插入邮箱
|
|
with public.S("mail_unsubscribe", '/www/vmail/mail_unsubscribe.db') as obj:
|
|
# 有退订 改为订阅
|
|
exit_un = obj.where('recipient', email).where('etype', etype).where('active', 0).count()
|
|
if exit_un:
|
|
obj.where('recipient', email).where('etype', etype).update({'active': 1})
|
|
return
|
|
|
|
# 不存在 新增
|
|
exit = obj.where('recipient', email).where('etype', etype).where('active', 1).count()
|
|
if not exit:
|
|
created = int(time.time())
|
|
insert = {
|
|
'created': created,
|
|
'recipient': email,
|
|
'etype': etype,
|
|
'active': 1,
|
|
}
|
|
obj.insert(insert)
|
|
return
|
|
|
|
|
|
# 退订接口调用的提交黑名单
|
|
def submit_recipient_blacklist(self, args):
|
|
|
|
email = args.email
|
|
etypes = args.etypes
|
|
task_id = args.task_id
|
|
subject = args.subject
|
|
send_time = args.send_time
|
|
|
|
created = int(time.time())
|
|
etype_list = etypes.split(",")
|
|
|
|
with self.M('mail_type') as obj:
|
|
data_list = obj.select()
|
|
types = {str(item["id"]): item["mail_type"] for item in data_list}
|
|
try:
|
|
with public.S("mail_unsubscribe", '/www/vmail/mail_unsubscribe.db') as obj:
|
|
for etype in etype_list:
|
|
etype = int(etype)
|
|
|
|
if not types.get(str(etype), None):
|
|
continue
|
|
|
|
# 有退订 跳过
|
|
exit_un = obj.where('recipient', email).where('etype', etype).where('active', 0).count()
|
|
if exit_un:
|
|
continue
|
|
|
|
# 有订阅 改为退订记录任务
|
|
exit = obj.where('recipient', email).where('etype', etype).where('active', 1).count()
|
|
if exit:
|
|
# 更新退订时间
|
|
bb = obj.where('recipient', email).where('etype', etype).update({'active': 0, 'task_id': task_id, 'created':created})
|
|
|
|
continue
|
|
return True
|
|
except Exception as e:
|
|
# public.print_log(public.get_error_info())
|
|
return False
|
|
|
|
|
|
# 获取退订类型
|
|
def get_mail_type_list(self, get):
|
|
email = get.get('email', '')
|
|
if not email:
|
|
# return 'There is no email'
|
|
return {"status": False, "msg": public.lang("There is no email")}
|
|
|
|
with self.M('mail_type') as obj:
|
|
typelist = obj.order('created desc').select()
|
|
typelist = {str(item["id"]): item["mail_type"] for item in typelist}
|
|
|
|
with public.S("mail_unsubscribe", '/www/vmail/mail_unsubscribe.db') as obj:
|
|
mail_type = []
|
|
etypes = obj.where('active', 1).where('recipient like ?', '{}%'.format(email)).field('etype').select()
|
|
|
|
|
|
for j in etypes:
|
|
if typelist.get(str(j['etype']), None):
|
|
mail_type.append({'id': j['etype'], 'mail_type':typelist[str(str(j['etype']))]})
|
|
|
|
|
|
# return mail_type
|
|
return {"status":True, "msg": mail_type}
|