publish.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. # -*- coding: utf-8 -*-
  2. # @Author: wangkun
  3. # @Time: 2022/8/1
  4. import json
  5. import os
  6. import random
  7. import time
  8. import oss2
  9. import requests
  10. import urllib3
  11. from main.common import Common
  12. proxies = {"http": None, "https": None}
  13. class Publish:
  14. @classmethod
  15. def publish_video_dev(cls, log_type, request_data):
  16. """
  17. loginUid 站内uid (随机)
  18. appType 默认:888888
  19. crawlerSrcId 站外视频ID
  20. crawlerSrcCode 渠道(自定义 KYK)
  21. crawlerSrcPublishTimestamp 视频原发布时间
  22. crawlerTaskTimestamp 爬虫创建时间(可以是当前时间)
  23. videoPath 视频oss地址
  24. coverImgPath 视频封面oss地址
  25. title 标题
  26. totalTime 视频时长
  27. viewStatus 视频的有效状态 默认1
  28. versionCode 版本 默认1
  29. :return:
  30. """
  31. # Common.logger().info('publish request data: {}'.format(request_data))
  32. result = cls.request_post('https://videotest.yishihui.com/longvideoapi/crawler/video/send', request_data)
  33. # Common.logger(log_type).info('publish result: {}'.format(result))
  34. video_id = result["data"]["id"]
  35. # Common.logger(log_type).info('video_id: {}'.format(video_id))
  36. if result['code'] != 0:
  37. Common.logger(log_type).error('pushlish failure msg = {}'.format(result['msg']))
  38. else:
  39. Common.logger(log_type).info('publish success video_id = : {}'.format(request_data['crawlerSrcId']))
  40. return video_id
  41. @classmethod
  42. def publish_video_prod(cls, log_type, request_data):
  43. """
  44. loginUid 站内uid (随机)
  45. appType 默认:888888
  46. crawlerSrcId 站外视频ID
  47. crawlerSrcCode 渠道(自定义 KYK)
  48. crawlerSrcPublishTimestamp 视频原发布时间
  49. crawlerTaskTimestamp 爬虫创建时间(可以是当前时间)
  50. videoPath 视频oss地址
  51. coverImgPath 视频封面oss地址
  52. title 标题
  53. totalTime 视频时长
  54. viewStatus 视频的有效状态 默认1
  55. versionCode 版本 默认1
  56. :return:
  57. """
  58. result = cls.request_post('https://longvideoapi.piaoquantv.com/longvideoapi/crawler/video/send', request_data)
  59. # Common.logger(log_type).info('publish result: {}'.format(result))
  60. video_id = result["data"]["id"]
  61. # Common.logger(log_type).info('video_id: {}'.format(video_id))
  62. if result['code'] != 0:
  63. Common.logger(log_type).error('pushlish failure msg = {}'.format(result['msg']))
  64. else:
  65. Common.logger(log_type).info('publish success video_id = : {}'.format(request_data['crawlerSrcId']))
  66. return video_id
  67. @classmethod
  68. def request_post(cls, request_url, request_data):
  69. """
  70. post 请求 HTTP接口
  71. :param request_url: 接口URL
  72. :param request_data: 请求参数
  73. :return: res_data json格式
  74. """
  75. urllib3.disable_warnings()
  76. response = requests.post(url=request_url, data=request_data, proxies=proxies, verify=False)
  77. if response.status_code == 200:
  78. res_data = json.loads(response.text)
  79. return res_data
  80. # 以下代码展示了基本的文件上传、下载、罗列、删除用法。
  81. # 首先初始化AccessKeyId、AccessKeySecret、Endpoint等信息。
  82. # 通过环境变量获取,或者把诸如“<你的AccessKeyId>”替换成真实的AccessKeyId等。
  83. #
  84. # 以杭州区域为例,Endpoint可以是:
  85. # http://oss-cn-hangzhou.aliyuncs.com
  86. # https://oss-cn-hangzhou.aliyuncs.com
  87. # 分别以HTTP、HTTPS协议访问。
  88. access_key_id = os.getenv('OSS_TEST_ACCESS_KEY_ID', 'LTAIP6x1l3DXfSxm')
  89. access_key_secret = os.getenv('OSS_TEST_ACCESS_KEY_SECRET', 'KbTaM9ars4OX3PMS6Xm7rtxGr1FLon')
  90. bucket_name = os.getenv('OSS_TEST_BUCKET', 'art-pubbucket')
  91. # endpoint = os.getenv('OSS_TEST_ENDPOINT', 'oss-cn-hangzhou-internal.aliyuncs.com')
  92. endpoint = os.getenv('OSS_TEST_ENDPOINT', 'oss-cn-hangzhou.aliyuncs.com')
  93. # 确认上面的参数都填写正确了
  94. for param in (access_key_id, access_key_secret, bucket_name, endpoint):
  95. assert '<' not in param, '请设置参数:' + param
  96. # 创建Bucket对象,所有Object相关的接口都可以通过Bucket对象来进行
  97. bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
  98. """
  99. 处理流程:
  100. 1. 定时(每天凌晨1点执行一次)循环files文件下的内容 结构:files -> 视频文件夹 -> 视频文件 + 封面图 + 基本信息
  101. 2. 视频文件和封面上传到oss
  102. - 视频文件oss目录 longvideo/crawler_local/video/prod/文件名
  103. - 视频封面oss目录 longvideo/crawler_local/image/prod/文件名
  104. 3. 发布视频
  105. - 读取 基本信息 调用发布接口
  106. """
  107. # env 日期20220225 文件名
  108. oss_file_path_video = 'longvideo/crawler_local/video/{}/{}/{}'
  109. oss_file_path_image = 'longvideo/crawler_local/image/{}/{}/{}'
  110. @classmethod
  111. def put_file(cls, log_type, oss_file, local_file):
  112. cls.bucket.put_object_from_file(oss_file, local_file)
  113. Common.logger(log_type).info("put oss file = {}, local file = {} success".format(oss_file, local_file))
  114. # 清除本地文件
  115. @classmethod
  116. def remove_local_file(cls, log_type, local_file):
  117. os.remove(local_file)
  118. Common.logger(log_type).info("remove local file = {} success".format(local_file))
  119. # 清除本地文件夹
  120. @classmethod
  121. def remove_local_file_dir(cls, log_type, local_file):
  122. os.rmdir(local_file)
  123. Common.logger(log_type).info("remove local file dir = {} success".format(local_file))
  124. local_file_path = './videos'
  125. video_file = 'video'
  126. image_file = 'image'
  127. info_file = 'info'
  128. uids_dev_up = [6267140]
  129. uids_dev_play = [6267141]
  130. uids_prod_up = [20631273, 20631274, 20631275, 20631276, 20631277]
  131. uids_prod_play = [20631273, 20631274, 20631275, 20631276, 20631277]
  132. @classmethod
  133. def upload_and_publish(cls, log_type, env, job):
  134. """
  135. 上传视频到 oss
  136. :param log_type: 选择的 log
  137. :param env: 测试环境:dev,正式环境:prod
  138. :param job: 上升榜:up,播放量:play
  139. """
  140. Common.logger(log_type).info("upload_and_publish starting...")
  141. today = time.strftime("%Y%m%d", time.localtime())
  142. # videos 目录下的所有视频文件夹
  143. files = os.listdir(cls.local_file_path)
  144. for f in files:
  145. try:
  146. # 单个视频文件夹
  147. fi_d = os.path.join(cls.local_file_path, f)
  148. # 确认为视频文件夹
  149. if os.path.isdir(fi_d):
  150. Common.logger(log_type).info('dir = {}'.format(fi_d))
  151. # 列出所有视频文件夹
  152. dir_files = os.listdir(fi_d)
  153. data = {'appType': '888888',
  154. 'crawlerSrcCode': 'GONGZHONGHAO',
  155. 'viewStatus': '1',
  156. 'versionCode': '1'}
  157. now_timestamp = int(round(time.time() * 1000))
  158. data['crawlerTaskTimestamp'] = str(now_timestamp)
  159. global uid
  160. if env == "dev" and job == "up":
  161. uid = str(random.choice(cls.uids_dev_up))
  162. elif env == "dev" and job == "play":
  163. uid = str(random.choice(cls.uids_dev_play))
  164. elif env == "prod" and job == "up":
  165. uid = str(random.choice(cls.uids_prod_up))
  166. elif env == "prod" and job == "play":
  167. uid = str(random.choice(cls.uids_prod_play))
  168. data['loginUid'] = uid
  169. # 单个视频文件夹下的所有视频文件
  170. for fi in dir_files:
  171. # 视频文件夹下的所有文件路径
  172. fi_path = fi_d + '/' + fi
  173. Common.logger(log_type).info('dir fi_path = {}'.format(fi_path))
  174. # 读取 info.txt,赋值给 data
  175. if cls.info_file in fi:
  176. f = open(fi_path, "r", encoding="UTF-8")
  177. # 读取数据 数据准确性写入的时候保证 读取暂不处理
  178. for i in range(14):
  179. line = f.readline()
  180. line = line.replace('\n', '')
  181. if line is not None and len(line) != 0 and not line.isspace():
  182. # Common.logger(log_type).info("line = {}".format(line))
  183. if i == 0:
  184. data['crawlerSrcId'] = line
  185. elif i == 1:
  186. data['title'] = line
  187. elif i == 2:
  188. data['totalTime'] = line
  189. elif i == 8:
  190. data['crawlerSrcPublishTimestamp'] = line
  191. else:
  192. Common.logger(log_type).warning("{} line is None".format(fi_path))
  193. f.close()
  194. # remove info.txt
  195. cls.remove_local_file(log_type, fi_path)
  196. # 刷新数据
  197. dir_files = os.listdir(fi_d)
  198. for fi in dir_files:
  199. fi_path = fi_d + '/' + fi
  200. # Common.logger(log_type).info('dir fi_path = {}'.format(fi_path))
  201. # 上传oss
  202. if cls.video_file in fi:
  203. global oss_video_file
  204. if env == "dev":
  205. oss_video_file = cls.oss_file_path_video.format("dev", today, data['crawlerSrcId'])
  206. elif env == "prod":
  207. oss_video_file = cls.oss_file_path_video.format("prod", today, data['crawlerSrcId'])
  208. Common.logger(log_type).info("oss_video_file = {}".format(oss_video_file))
  209. cls.put_file(log_type, oss_video_file, fi_path)
  210. data['videoPath'] = oss_video_file
  211. Common.logger(log_type).info("videoPath = {}".format(oss_video_file))
  212. elif cls.image_file in fi:
  213. global oss_image_file
  214. if env == "dev":
  215. oss_image_file = cls.oss_file_path_image.format("env", today, data['crawlerSrcId'])
  216. elif env == "prod":
  217. oss_image_file = cls.oss_file_path_image.format("prod", today, data['crawlerSrcId'])
  218. Common.logger(log_type).info("oss_image_file = {}".format(oss_image_file))
  219. cls.put_file(log_type, oss_image_file, fi_path)
  220. data['coverImgPath'] = oss_image_file
  221. Common.logger(log_type).info("coverImgPath = {}".format(oss_image_file))
  222. # 全部remove
  223. cls.remove_local_file(log_type, fi_path)
  224. # 发布
  225. if env == "dev":
  226. video_id = cls.publish_video_dev(log_type, data)
  227. elif env == "prod":
  228. video_id = cls.publish_video_prod(log_type, data)
  229. else:
  230. video_id = cls.publish_video_dev(log_type, data)
  231. cls.remove_local_file_dir(log_type, fi_d)
  232. return video_id
  233. else:
  234. Common.logger(log_type).error('file not a dir = {}'.format(fi_d))
  235. except Exception as e:
  236. Common.logger(log_type).exception('upload_and_publish error', e)