123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 |
- # -*- coding: utf-8 -*-
- #!/usr/bin/env python
- """
- web.ad.views
- ~~~~~~~~~
- """
- import datetime
- import itertools
- import logging
- import random
- import traceback
- import simplejson as json
- import xmltodict
- from bson.objectid import ObjectId
- from django.core.handlers.wsgi import WSGIRequest
- from django.views.decorators.http import require_POST, require_GET
- from mongoengine.errors import NotUniqueError
- from typing import List, Union, Optional, Iterable, cast, TYPE_CHECKING, Dict
- from apilib import utils_datetime
- from apilib.utils import flatten
- from apilib.utils_datetime import dt_to_timestamp, date_to_datetime_floor, date_to_datetime_ceiling
- from apilib.utils_json import JsonResponse
- from apps import serviceCache
- from apps.web.ad import OfflineTaskType, MyJsonOkResponse
- from apps.web.ad.models import Advertisement, AdRecord, Advertiser, AdWord, AliAdLog
- from apps.web.ad.utils import (get_available_ads_by_user)
- from apps.web.agent.models import Agent
- from apps.web.common.validation import PASSWORD_RE
- from apps.web.core import ROLE
- from apps.web.core.db import prepare_conditions, prepare_query
- from apps.web.core.exceptions import InvalidPermission
- from apps.web.core.models import OfflineTask
- from apps.web.core.utils import DefaultJsonErrorResponse, parse_json_payload
- from apps.web.core.utils import JsonErrorResponse, JsonOkResponse
- from apps.web.dealer.models import Dealer
- from apps.web.device.models import Device
- from apps.web.device.models import Group
- from apps.web.management.models import Manager
- from apps.web.user.models import MyUser, Redpack
- from apps.web.user.utils import RedpackBuilder
- from apps.web.utils import advertiser_login, \
- is_advertiser, is_manager, is_advertisement
- from apps.web.utils import error_tolerate, permission_required
- from taskmanager.mediator import task_caller
- if TYPE_CHECKING:
- from apps.web.common.models import UserSearchable
- logger = logging.getLogger(__name__)
- @error_tolerate(nil = DefaultJsonErrorResponse)
- @require_POST
- @permission_required(ROLE.manager, ROLE.advertiser)
- def getAdPreAllocatedDevice(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 根据多种多样的查询条件获取供分配设备列表List[Dict]
- {"devCondition":[{"agentIdList":[],"dealerIdList":[],"groupIdList":[]}],"addressTypeList":[],"devTypeList":[]}
- get_devices query =
- dealerIdList => Device.objects(ownerId__in=dealerIdList)
- | agentIdList => Device.objects(Dealer.objects(agentId__=agentIdList)
- | groupIdList => Device.objects(groupId__in=groupIdList)
- devices.filter( _ => _.devType in devTypeList & _ => _.group.addressType in addressTypeList)
- return [ { 'logicalCode': x, 'devType': 'y' } ]
- TODO:
- 优化方向,
- 0. 优化解析过程
- 1. 建立query解析缓存
- 2. 运用mongodb pipeline
- 3. 本地化部分数据(将厂商ID绑定到设备端,解绑记得清除,将地址类型也绑定到设备,解绑记得清除)
- :param request:
- :return:
- :rtype: JsonResponse
- """
- query = json.loads(request.body)
- currentUser = request.user #type: cast(Union[Manager, Advertiser])
- if is_manager(currentUser):
- devCondition, addressTypeList, devTypeList = query['devCondition'], query['addressTypeList'], query['devTypeList']
- elif is_advertiser(currentUser):
- devCondition, addressTypeList, devTypeList = currentUser.preAllocatedDeviceConditions, query['addressTypeList'], query['devTypeList']
- else:
- raise InvalidPermission(u'只有广告主或厂商才能查询广告投放设备')
- hasDevCondition = bool(len(list(itertools.ifilter(lambda _ : _ != [], flatten(_.values() for _ in devCondition)))))
- hasAddressTypeList = bool(len(addressTypeList))
- hasDevTypeList = bool(len(devTypeList))
- def imerge_dicts(iterable):
- """
- Given any number of dicts, shallow copy and merge into a new dict,
- precedence goes to key value pairs in latter dicts.
- """
- result = {}
- for dictionary in iterable:
- result.update(dictionary)
- return result
- to_query = lambda _ : imerge_dicts( x.to_query(None) for x in prepare_conditions(_) )
- def acc_or_append(q, data):
- """
- :param q: [{}]
- :param data:
- :return:
- """
- if not len(q):
- q.append(data)
- else:
- for item in q:
- if data == item: break
- elif item['field'] == data['field'] and item['operator'] == data['operator']:
- item['value'] = list(set(item['value'] + data['value']))
- break
- else:
- q.append(data)
- break
- def parse_devCondition(conditions):
- """
- :param conditions: [{..conditions}]
- :return:
- """
- queries = {
- 'device': [],
- 'dealer': [],
- 'group': []
- }
- for cond in conditions:
- # 优先级 groupIdList > dealerIdList > agentIdList
- if cond['groupIdList']:
- acc_or_append(queries['group'], {"field": "_id", "operator": "in", "value": [ ObjectId(_) for _ in cond['groupIdList']] })
- continue
- elif cond['dealerIdList']:
- acc_or_append(queries['group'], {"field": "ownerId", "operator": "in", "value": map(str, cond['dealerIdList']) })
- continue
- elif cond['agentIdList']:
- acc_or_append(queries['dealer'], {"field": "agentId", "operator": "in", "value": cond['agentIdList']})
- continue
- return queries
- #: 生成,拼装请求,延迟请求Device到最后, 减少IO
- queries = parse_devCondition(devCondition)
- #: 默认只能选择某厂商下的所有设备
- #acc_or_append(queries['device'],{"field": "managerId", "operator": "", "value": managerId})
- #: 不选择的时候,选择所有组的设备
- if not hasDevCondition:
- if is_manager(currentUser):
- agentIds = [ str(_['_id']) for _ in Agent.get_collection().find({'managerId': str(currentUser.id)})]
- acc_or_append(queries['dealer'], {"field": "agentId", "operator": "in", "value": agentIds})
- elif is_advertiser(currentUser):
- agentIds = [ str(_.id) for _ in Agent.objects(managerId=currentUser.managerId) ]
- acc_or_append(queries['dealer'], {"field": "agentId", "operator": "in", "value": agentIds})
- if hasDevTypeList:
- acc_or_append(queries['device'], {"field": "devType.id", "operator": "in", "value": devTypeList})
- if hasAddressTypeList:
- acc_or_append(queries['group'], {"field": "addressType", "operator": "in", "value": addressTypeList})
- if queries['dealer']:
- dealers = [ str(_['_id']) for _ in Dealer.get_collection().find(to_query(queries['dealer']), {'_id': 1}) ]
- acc_or_append(queries['group'], {"field": "ownerId", "operator": "in", "value": dealers})
- if queries['group']:
- groups = [ str(_['_id']) for _ in Group.get_collection().find(to_query(queries['group']), {'_id': 1}) ]
- acc_or_append(queries['device'], {"field": "groupId", "operator": "in", "value": groups})
- if queries['device']:
- dataList = [ {'logicalCode': _['logicalCode'], 'devTypeName' : _['devType'].get('name')} for _ in
- Device.get_collection()
- .find(to_query(queries['device']), {'logicalCode': 1, 'devType.name': 1})]
- return JsonResponse({'result': 1, 'payload': {'dataList': dataList}})
- return JsonResponse({'result': 1, 'payload': {'dataList': []}})
- ###: 广告增删查改
- @require_GET
- @error_tolerate(nil = DefaultJsonErrorResponse)
- @permission_required(ROLE.manager, ROLE.advertisement, ROLE.advertiser)
- def getAdList(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取广告列表
- :param request:
- :return:
- """
- return JsonResponse({'result': 1, 'description': '', 'payload': {'total': 0, 'dataList': []}})
- @require_GET
- @error_tolerate(nil=JsonErrorResponse(u'获取广告分配设备列表失败'))
- @permission_required(ROLE.manager, ROLE.advertiser)
- def getDevListByAd(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 为了加快广告加载速度,不默认返回设备列表,只有在用户点击广告的时候才会请求设备列表
- :param request:
- :return:
- """
- adId = request.GET.get('adId')
- devList = Advertisement.get_by_adId(adId=adId).devList
- return JsonResponse({'result': 1, 'description': '', 'payload': {'total': len(devList), 'dataList': devList }})
- @require_POST
- @error_tolerate(nil = JsonErrorResponse(u'添加广告失败'))
- @permission_required(ROLE.manager, ROLE.advertiser)
- def addAd(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 添加广告
- 广告主和厂商都可以添加广告
- 广告主只可配置 publicAdAvailable的广告主
- :param request:
- :return:
- """
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- @require_POST
- @error_tolerate(nil = JsonErrorResponse(u'编辑广告失败'))
- @permission_required(ROLE.manager, ROLE.advertiser)
- def editAd(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 编辑广告
- :param request:
- :return:
- """
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- @require_POST
- @error_tolerate(nil = JsonErrorResponse(u'删除广告失败'))
- @permission_required(ROLE.manager, ROLE.advertiser)
- def deleteAd(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 删除广告
- :param request:
- :return:
- """
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- ###: 各种过滤器
- @error_tolerate(nil = JsonErrorResponse(u'获取经销商列表失败'))
- @permission_required(ROLE.manager)
- def getDealerList(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取经销商列表
- :param request:
- :return:
- """
- agentId = request.GET.get('agentId', None)
- if agentId is None:
- return JsonResponse({'result': 0, 'description': u'请传入正确的参数', 'payload': {}})
- dealers = [{'value': str(dealer.id), 'label': dealer.nickname} for dealer in Dealer.objects(agentId = str(agentId))]
- return JsonResponse({'result': 1, 'description': '', 'payload': dealers})
- @error_tolerate(nil = JsonErrorResponse(u'获取地址列表失败'))
- @permission_required(ROLE.manager)
- def getAddressList(request):
- # type:(WSGIRequest)->JsonResponse
- """
- dealer->group.address
- :param request:
- :return:
- """
- dealerId = request.GET.get('id')
- groupIds = Group.get_group_ids_of_dealer(dealerId)
- groups = Group.get_groups_by_group_ids(groupIds)
- if groups is None:
- return JsonResponse({'result': 1, 'description': '', 'payload': []})
- else:
- groupIdAddressPair = [{'value': k, 'label': v['address']} for k, v in groups.iteritems()]
- return JsonResponse({'result': 1, 'description': '', 'payload': groupIdAddressPair})
- @error_tolerate(nil = JsonErrorResponse(u'获取设备列表失败'))
- @permission_required(ROLE.manager)
- def getDevList(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 广告系统获取设备列表
- :param request:
- :return:
- """
- groupId = request.GET.get('id')
- deviceNos = Device.get_devNos_by_group([groupId])
- devs = Device.get_dev_by_nos(deviceNos)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload':
- [
- {'value': deviceNo, 'label': dev['logicalCode']}
- for deviceNo, dev in devs.items()
- ] if deviceNos else []
- }
- )
- ### 查看设备被分配的广告列表
- @error_tolerate(nil = JsonErrorResponse(u'查看设备广告列表失败'))
- @permission_required(ROLE.manager)
- def getDeviceAllocatedAds(request):
- # type:(WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- logicalCode = request.GET.get('logicalCode')
- return JsonResponse({'result': 1, 'description': '', 'payload': {'total': 0, 'dataList': []}})
- ### 广告数据报表
- @error_tolerate(nil = JsonErrorResponse(u'获取趋势列表失败'))
- @permission_required(ROLE.manager, ROLE.advertisement, ROLE.advertiser)
- def getAdFansTrend(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取广告效果趋势
- :param request:
- :return:
- """
- currentUser = request.user # type: cast(Union[Advertisement, Advertiser, Manager])
- query = prepare_query(request.GET)
- queryDict = query.raw
- delta = query.attrs['dateTimeAdded__lte'] - query.attrs['dateTimeAdded__gte'] # type: datetime.timedelta
- if delta.days > 90:
- return JsonErrorResponse(u'只支持查询最远至90天前的数据')
- #: TODO to refactor 引入校验schema
- if 'adId' in queryDict:
- queryDict['adId'] = int(queryDict['adId'])
- if is_manager(currentUser):
- queryDict['managerId'] = str(currentUser.id)
- elif is_advertiser(currentUser):
- queryDict['advertiserId'] = str(currentUser.id)
- elif is_advertisement(currentUser):
- queryDict['adId'] = int(currentUser.adId)
- matchStage = {
- 'createdDate':
- {
- '$gte': queryDict.pop('startTime'),
- '$lte': queryDict.pop('endTime')
- },
- }
- matchStage.update(queryDict)
- projectStage = {
- '_id': 0,
- 'clicks': 1,
- 'createdDate': 1,
- 'fans': {'$cond': ['$converted', 1, 0]},
- 'maleFans': '$features.sex.is_male',
- 'femaleFans': '$features.sex.is_female'
- }
- projectStage.update(dict.fromkeys(AdRecord.filter_fields(), 1))
- groupStage = {
- '_id': '$createdDate',
- 'clicks': {'$sum': '$clicks'},
- 'fans': {'$sum': '$fans'},
- 'show': {'$sum': '$clicks'},
- 'maleFans': {'$sum': '$maleFans'},
- 'femaleFans': {'$sum': '$femaleFans'}
- }
- aggregates = AdRecord.get_collection().aggregate(
- [
- {'$project': projectStage},
- {'$match': matchStage},
- {'$group': groupStage},
- {'$addFields': {'time': '$_id'}},
- {'$sort': {'time': 1}},
- ]
- )
- return JsonResponse({'result': 1, 'description': '', 'payload': list(aggregates)})
- @permission_required(ROLE.manager)
- def getAdMoneyTrend(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 收益趋势
- :param request:
- :return:
- """
- # TODO 待讨论
- return JsonResponse({'result': 1, 'description': '', 'payload': []})
- @error_tolerate(nil = DefaultJsonErrorResponse)
- @permission_required(ROLE.manager, ROLE.advertisement, ROLE.advertiser)
- def getAdFansDetail(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取广告效果详情列表
- :param request:
- :return:
- """
- query = prepare_query(request.GET)
- currentUser = request.user # type: cast(Union[Advertisement, Advertiser, Manager])
- if is_manager(currentUser):
- query.attrs['managerId'] = str(currentUser.id)
- elif is_advertiser(currentUser):
- query.attrs['advertiserId'] = str(currentUser.id)
- elif is_advertisement(currentUser):
- query.attrs['adId'] = int(currentUser.adId)
- cursor = AdRecord.objects(converted=True, **query.attrs)
- total = cursor.count()
- pagedRecords = cursor.order_by('-dateTimeAdded').paginate(pageIndex=query.pageIndex, pageSize=query.pageSize) # type: List[AdRecord]
- records = [ r.to_dict() for r in pagedRecords ]
- return JsonResponse({'result': 1, 'description': None, 'data': {'total': total, 'dataList': records}})
- @error_tolerate(nil=DefaultJsonErrorResponse)
- def getPayAfterAd(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取支付后广告链接(蓝牙payAfter页面)
- :param request:
- :return:
- """
- logicalCode = request.GET.get('logicalCode', None)
- if not logicalCode:
- logger.debug('no logical code.')
- return JsonOkResponse(description='no ads available')
- device = Device.get_dev_by_logicalCode(logicalCode)
- if not device:
- logger.debug('no device find.')
- return JsonOkResponse(description='no ads available')
- ua = request.META.get('HTTP_USER_AGENT', '')
- user = request.user # type: MyUser
- ad_dict = Advertisement.fetch_payafter_ad(ua, user, device.owner, device)
- logger.debug('ad dict is {}'.format(ad_dict))
- if not ad_dict:
- return JsonOkResponse(description='no ads available')
- else:
- return JsonResponse({'result': 1, 'description': u'', 'payload': ad_dict})
- def taskList(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 广告适配系统
- :param request:
- :return:
- """
- try:
- user = request.user # type: cast(MyUser)
- devNo = request.GET.get('devNo')
- if not devNo:
- return JsonResponse({'result': 0, 'description': u'请首先扫码', 'payload': {}})
- device = Device.get_dev(devNo)
- if not device:
- return JsonResponse({'result': 0, 'description': u'设备不存在', 'payload': {}})
- ads = get_available_ads_by_user(device, user)
- logger.debug('%s got ads(%s) on device(logicalCode=%s)' % (repr(user), ads, device['logicalCode']))
- allocated_ads = [{'id': ad.adId, 'name': ad.name, 'word': ad.word, 'qrcode': ad.img} for ad in ads]
- random.shuffle(allocated_ads)
- return JsonResponse({'result': 1, 'description': None, 'payload': {'taskList': allocated_ads}})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 1, 'description': None, 'payload': {'taskList': []}})
- ### 广告主
- @error_tolerate(nil = JsonErrorResponse(u'注册失败'))
- def registerAdvertiser(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 注册成为广告主
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- try:
- Advertiser.create_user(**payload)
- except NotUniqueError:
- return JsonErrorResponse(description = u'该手机号已注册')
- return JsonResponse({'result': 1, 'description': None, 'payload': {}})
- @error_tolerate(nil = JsonErrorResponse(u'登录失败'))
- def advertiserLogin(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 广告主登录
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- username, password = payload['username'], payload['password']
- return advertiser_login(request, logger, username, password)
- @error_tolerate(nil = JsonErrorResponse(u'修改密码失败'))
- @permission_required(ROLE.advertiser)
- def changeAdvertiserPassword(request):
- # type: (WSGIRequest)->JsonResponse
- currentAdvertiser = request.user # type: cast(Advertiser)
- payload = json.loads(request.body)
- password = payload['password']
- if PASSWORD_RE.match(password) is None:
- return JsonErrorResponse(description=u'密码必须大于8位,只能是数字或字母或常见特殊符号')
- currentAdvertiser.set_password(payload['password'])
- return JsonResponse({'result': 1})
- @error_tolerate(nil = JsonErrorResponse(u'获取广告主信息失败'))
- @permission_required(ROLE.advertiser)
- def getAdvertiserInfo(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 获取广告主信息
- :param request:
- :return:
- """
- user = request.user # type: cast(Advertiser)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {'nickname': user.nickname, 'brandName': '', 'quota': user.quota, 'role': ROLE.advertiser }
- }
- )
- ### others
- @error_tolerate(nil = JsonErrorResponse(u'生成报表失败'))
- @permission_required(ROLE.manager)
- def exportExcel(request):
- # type:(WSGIRequest)->JsonResponse
- """
- 广告效果报表生成excel
- :param request:
- :return:
- """
- manager = request.user # type: cast(Manager)
- def get_offline_task_name(task_type, user, **kwargs):
- # type: (basestring, UserSearchable, Dict)->basestring
- tmp_list = [task_type, user.username]
- if 'adId' in kwargs and kwargs['adId']:
- tmp_list.append(u'广告_%s' % (kwargs['adId'],))
- elif 'devNo' in kwargs:
- logicalCode = Device.get_logicalCode_by_devNo(kwargs['devNo'])
- tmp_list.append(u'设备号_%s' % (logicalCode,))
- elif 'groupId' in kwargs:
- address = Group.get_group(kwargs['groupId']).get('address', '')
- tmp_list.append(u'地址_%s' % (address,))
- elif 'dealerId' in kwargs:
- dealerName = Dealer.objects(id = str(kwargs['dealerId'])).get().nickname
- tmp_list.append(u'经销商_%s' % (dealerName,))
- elif 'agentId' in kwargs:
- agentName = Agent.objects(id = str(kwargs['agentId'])).get().nickname
- tmp_list.append(u'代理商_%s' % (agentName,))
- tmp_list.append(u'%s至%s' % (kwargs['startTime'], kwargs['endTime']))
- tmp_list.append(str(utils_datetime.generate_timestamp_ex()))
- return '-'.join(tmp_list).replace("/", "_")
- query = prepare_query(request.GET)
- offline_task_name = get_offline_task_name(task_type = OfflineTaskType.AD_REPORT,
- user = manager,
- **(query.raw))
- #: make queryAttrs serializable
- queryAttrs = query.attrs
- queryAttrs['dateTimeAdded__lte'] = dt_to_timestamp(queryAttrs['dateTimeAdded__lte'])
- queryAttrs['dateTimeAdded__gte'] = dt_to_timestamp(queryAttrs['dateTimeAdded__gte'])
- file_path, offline_task = OfflineTask.issue_export_report(offline_task_name = offline_task_name,
- process_func_name = 'generate_ad_excel_report',
- task_type = OfflineTaskType.AD_REPORT,
- userid = str(manager.id),
- role = ROLE.manager,
- paras = queryAttrs)
- task_caller(func_name = offline_task.process_func_name,
- offline_task_id = str(offline_task.id),
- filepath = file_path,
- queryAttrs = queryAttrs)
- return JsonResponse({
- 'result': 1,
- 'description': u"请前往离线任务查看任务处理情况",
- 'payload': str(offline_task.id)})
- def getDialogAd(request):
- # type:(WSGIRequest)->JsonResponse
- # TODO 支付前广告,待补充
- return JsonResponse({
- 'result': 1,
- 'description': '',
- 'payload': {'dataList': []}})
- def getBannerAd(request):
- # type:(WSGIRequest)->JsonResponse
- logicalCode = request.GET.get('logicalCode')
- dev = Device.get_dev_by_logicalCode(logicalCode)
- dealer = Dealer.objects(id=str(dev['ownerId'])).only('agentId').get() # type: Dealer
- agent = Agent.objects(id=str(dealer.agentId)).only('managerId').get() # type: Agent
- ad = Advertisement.filter_by_top_show(managerId=agent.managerId).first() # type: Optional[Advertisement]
- if not ad:
- return JsonOkResponse(payload={})
- else:
- return JsonOkResponse(payload={'link': ad.link, 'img': ad.img})
- @permission_required(ROLE.supermanager)
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def getAdWords(request):
- # type:(WSGIRequest)->JsonResponse
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- searchKey = request.GET.get('searchKey')
- startTime = request.GET.get('startTime')
- endTime = request.GET.get('endTime')
- query = {}
- if startTime is not None and endTime is not None:
- query['dateTimeAdded__lte'] = date_to_datetime_ceiling(endTime)
- query['dateTimeAdded__gte'] = date_to_datetime_floor(startTime)
- total = AdWord.objects(**query).search(searchKey).count()
- qs = AdWord.objects(**query).search(searchKey).paginate(pageIndex=pageIndex, pageSize=pageSize) # type: Iterable[AdWord]
- return JsonOkResponse(payload={'dataList': [ _.to_dict() for _ in qs ], 'total': total})
- @permission_required(ROLE.supermanager)
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def addAdWord(request):
- # type:(WSGIRequest)->JsonResponse
- payload = parse_json_payload(request.body)
- AdWord(**payload).save()
- return JsonOkResponse()
- @permission_required(ROLE.supermanager)
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def editAdword(request):
- # type:(WSGIRequest)->JsonResponse
- payload = parse_json_payload(request.body)
- ad_word = AdWord.objects(id=payload['id']).get()
- updated = ad_word.update(**payload)
- if updated:
- return JsonOkResponse(payload={'description': u'更新成功'})
- else:
- return JsonErrorResponse(payload={'description': u'更新失败'})
- @permission_required(ROLE.supermanager)
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def deleteAdword(request):
- # type:(WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- ids = payload.get('ids')
- if not ids:
- return JsonErrorResponse(description=u'')
- AdWord.objects(id__in=ids).delete() # type: AdWord
- return JsonOkResponse()
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def userGetAdword(request):
- # type:(WSGIRequest)->JsonResponse
- try:
- user = request.user # type: cast(MyUser)
- ad_word = AdWord.get_random_one() # type: AdWord
- if ad_word is not None:
- ad_word.incr_count(1)
- title = ad_word.title
- if not ad_word.autoPass:
- return MyJsonOkResponse({'result': 1, 'description': '', 'payload': {'content': ad_word.promotionUrl}})
- tbkCode = serviceCache.get('tbk_{}'.format(str(ad_word.id)))
- if not tbkCode:
- from library.aliopen.tbkapi import CreatTaokoulingReq
- request = CreatTaokoulingReq(appKey = '33175347', appSecret = 'c4e2d8426d1d08ec49ef00bc40ac94d5')
- request.setParams(url = ad_word.promotionUrl)
- rv = xmltodict.parse(request.getResponse().content)
- logger.debug('tbk code rv for {} is: {}'.format(str(ad_word.id), str(rv)))
- tokens = rv['tbk_tpwd_create_response']['data']['model'].split(' ')
- tbkCode = '{} {} {}'.format(tokens[0], tokens[1], title)
- logger.debug('new tbk code is: {}'.format(tbkCode))
- serviceCache.set('tbk_{}'.format(str(ad_word.id)), tbkCode, 60 * 60 * 2)
- return MyJsonOkResponse({'result': 1, 'description': '', 'payload': {'content': tbkCode}})
- else:
- logger.debug('cache tbk code is: {}'.format(tbkCode))
- return MyJsonOkResponse({'result': 1, 'description': '', 'payload': {'content': tbkCode}})
- except Exception as e:
- logger.error('exception = {}; id = {}'.format(traceback.format_exc(), str(ad_word.id)))
- return MyJsonOkResponse({'result': 1, 'description': '', 'payload': {'content': ''}})
- @error_tolerate(nil = DefaultJsonErrorResponse)
- def alipayCallback(request, uidType):
- # type:(WSGIRequest, str)->JsonResponse
- try:
- uidType = uidType.upper()
- payload = json.loads(request.body)
- if uidType == 'CPM':
- # uid = payload.get('uid')
- # bid = payload.get('bid')
- # try:
- # AdLog.objects.get(openId=uid, bidid=bid, status__ne='finished').update(status='finished', finishedData=request.body, finishedTime=datetime.datetime.now())
- # except:
- # logger.info(traceback.format_exc())
- pass
- elif uidType == 'RH':
- uid = payload.get('uid')
- urlId = payload.get('ext', {}).get('id')
- redpack = Redpack.take_effect(openId = uid, urlId = urlId, **{'RHCallback': request.body})
- if redpack:
- RedpackBuilder._set_alipay_key(uid, redpack.factoryCode, urlId, redpack.money.mongo_amount,
- showType = redpack.showType)
- return JsonResponse({"status": 1, "alipayOrderId": urlId})
- elif uidType == 'LX':
- pass
- try:
- AliAdLog.objects(campaignId = payload.get('campaignId'), bid = payload.get('bid')).upsert_one(
- uid = payload.get('uid'), uidType = payload.get('uidtype'), campaignId = payload.get('campaignId'),
- bid = payload.get('bid'), tradeTS = payload.get('tradetimestamp'), commission = payload.get('commission'))
- except Exception as e:
- logger.error(e)
- finally:
- return JsonResponse({'success': True, 'errorMsg': '', 'result': True})
|