api_routes.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. from aiohttp import web
  2. from aiohttp_session import get_session
  3. from user import UserError
  4. from user import LoginError, log_in, log_out
  5. from user import SignupError, sign_up
  6. from user import find_user_by_id
  7. from user import get_user_videos, get_user_videos_count
  8. from user import is_video_liked
  9. from user import like_video, unlike_video
  10. from user import upload_avatar, upload_video
  11. from user import serialize_user
  12. from user import get_authorized_user
  13. from video import VideoError
  14. from video import serialize_video
  15. from video import get_random_video
  16. from video import get_likes, get_tags
  17. from comment import get_comments, get_comments_count, post_comment
  18. from common import search_videos, suggest_tag
  19. from tools import verify_captcha
  20. from config import config
  21. routes = web.RouteTableDef()
  22. def report_error(error):
  23. return web.json_response({
  24. 'error': str(error)
  25. })
  26. @routes.post('/api/random')
  27. async def api_random(request):
  28. video = await get_random_video()
  29. return web.json_response({
  30. 'video_id': video.id
  31. })
  32. @routes.post('/api/login')
  33. async def api_login(request):
  34. session = await get_session(request)
  35. data = await request.post()
  36. username = data.get('username')
  37. password = data.get('password')
  38. hcaptcha_token = data.get('h-captcha-response')
  39. if not await verify_captcha(hcaptcha_token):
  40. return report_error('captcha check failed')
  41. try:
  42. user = await log_in(session, username, password)
  43. except (UserError, LoginError) as error:
  44. return report_error(error)
  45. return web.json_response({
  46. 'user_id': user.id
  47. })
  48. @routes.post('/api/signup')
  49. async def api_signup(request):
  50. session = await get_session(request)
  51. data = await request.post()
  52. username = data.get('username')
  53. password = data.get('password')
  54. hcaptcha_token = data.get('h-captcha-response')
  55. if not await verify_captcha(hcaptcha_token):
  56. return report_error('captcha check failed')
  57. try:
  58. user = await sign_up(session, username, password, ip_address=request.remote)
  59. except (UserError, SignupError) as error:
  60. return report_error(error)
  61. return web.json_response({
  62. 'user_id': user.id
  63. })
  64. @routes.post('/api/logout')
  65. async def api_logout(request):
  66. session = await get_session(request)
  67. try:
  68. await log_out(session)
  69. except UserError as error:
  70. return report_error(error)
  71. return web.json_response({
  72. 'status': 'success'
  73. })
  74. @routes.post('/api/user')
  75. async def api_user(request):
  76. data = await request.post()
  77. user_id = data.get('user_id')
  78. try:
  79. user = await find_user_by_id(user_id)
  80. except UserError as error:
  81. return report_error(error)
  82. return web.json_response(await serialize_user(user))
  83. @routes.post('/api/videos')
  84. async def api_videos(request):
  85. data = await request.post()
  86. user_id = data.get('user_id')
  87. offset = data.get('offset')
  88. try:
  89. videos = await get_user_videos(user_id, offset=offset)
  90. videos_count = await get_user_videos_count(user_id)
  91. except (UserError, VideoError) as error:
  92. return report_error(error)
  93. return web.json_response({
  94. 'videos': videos,
  95. 'videos_count': videos_count
  96. })
  97. @routes.post('/api/comments')
  98. async def api_comments(request):
  99. data = await request.post()
  100. video_id = data.get('video_id')
  101. offset = data.get('offset')
  102. try:
  103. comments = await get_comments(video_id, offset=offset)
  104. comments_count = await get_comments_count(video_id)
  105. except VideoError as error:
  106. return report_error(error)
  107. return web.json_response({
  108. 'comments': comments,
  109. 'comments_count': comments_count
  110. })
  111. @routes.post('/api/search')
  112. async def api_search(request):
  113. data = await request.post()
  114. tags = data.get('tags')
  115. offset = data.get('offset')
  116. try:
  117. videos = await search_videos(tags, offset=offset)
  118. except SyntaxError as error: # SyntaxError is thrown by parse_tags.
  119. return report_error(error)
  120. return web.json_response({
  121. 'videos': videos
  122. })
  123. @routes.post('/api/suggest')
  124. async def api_tags(request):
  125. data = await request.post()
  126. tag = data.get('tag')
  127. try:
  128. tags_list = await suggest_tag(tag)
  129. except SyntaxError as error:
  130. return report_error(error)
  131. return web.json_response({
  132. 'tags_list': tags_list
  133. })
  134. @routes.post('/api/tags')
  135. async def api_tags(request):
  136. data = await request.post()
  137. video_id = data.get('video_id')
  138. try:
  139. tags_list = await get_tags(video_id)
  140. except VideoError as error:
  141. return report_error(error)
  142. return web.json_response({
  143. 'tags_list': tags_list
  144. })
  145. @routes.post('/api/liked')
  146. async def api_liked(request):
  147. session = await get_session(request)
  148. data = await request.post()
  149. video_id = data.get('video_id')
  150. try:
  151. is_liked = await is_video_liked(session, video_id)
  152. except (UserError, VideoError) as error:
  153. return report_error(error)
  154. return web.json_response({
  155. 'is_liked': is_liked
  156. })
  157. @routes.post('/api/likes')
  158. async def api_likes(request):
  159. data = await request.post()
  160. video_id = data.get('video_id')
  161. try:
  162. likes_count = await get_likes(video_id)
  163. except VideoError as error:
  164. return report_error(error)
  165. return web.json_response({
  166. 'likes_count': likes_count
  167. })
  168. @routes.post('/api/like')
  169. async def api_like(request):
  170. session = await get_session(request)
  171. data = await request.post()
  172. video_id = data.get('video_id')
  173. try:
  174. await like_video(session, video_id)
  175. likes_count = await get_likes(video_id)
  176. except (UserError, VideoError) as error:
  177. return report_error(error)
  178. return web.json_response({
  179. 'likes_count': likes_count
  180. })
  181. @routes.post('/api/unlike')
  182. async def api_unlike(request):
  183. session = await get_session(request)
  184. data = await request.post()
  185. video_id = data.get('video_id')
  186. try:
  187. await unlike_video(session, video_id)
  188. likes_count = await get_likes(video_id)
  189. except (UserError, VideoError) as error:
  190. return report_error(error)
  191. return web.json_response({
  192. 'likes_count': likes_count
  193. })
  194. @routes.post('/api/comment')
  195. async def api_comment(request):
  196. session = await get_session(request)
  197. data = await request.post()
  198. video_id = data.get('video_id')
  199. text = data.get('text')
  200. try:
  201. comment = await post_comment(session, video_id, text)
  202. except (UserError, VideoError, ValueError) as error:
  203. return report_error(error)
  204. return web.json_response({
  205. 'comment_id': comment.id
  206. })
  207. @routes.post('/api/upload/avatar')
  208. async def api_upload_avatar(request):
  209. session = await get_session(request)
  210. reader = await request.multipart()
  211. image = await reader.next()
  212. try:
  213. await upload_avatar(session, image)
  214. user = await get_authorized_user(session)
  215. except UserError as error:
  216. return report_error(error)
  217. return web.json_response(await serialize_user(user))
  218. @routes.post('/api/upload/video')
  219. async def api_upload_video(request):
  220. session = await get_session(request)
  221. if 'authorized' not in session:
  222. return web.json_response({
  223. 'error': 'not authorized.'
  224. })
  225. video = None
  226. tags = None
  227. hcaptcha_token = None
  228. reader = await request.multipart()
  229. while True:
  230. part = await reader.next()
  231. if not part:
  232. break
  233. if part.name == 'video':
  234. video = bytearray()
  235. size = 0
  236. while True:
  237. chunk = await part.read_chunk()
  238. if not chunk:
  239. break
  240. size += len(chunk)
  241. if size >= config.MAX_VIDEO_SIZE * 1024 * 1024:
  242. return report_error('illegal video')
  243. video += chunk
  244. elif part.name == 'tags':
  245. tags = await part.read_chunk()
  246. tags = tags.decode('ASCII')
  247. elif part.name == 'h-captcha-response':
  248. hcaptcha_token = await part.read_chunk()
  249. hcaptcha_token = hcaptcha_token.decode('ASCII')
  250. if not hcaptcha_token:
  251. return report_error('captcha check failed')
  252. if not await verify_captcha(hcaptcha_token):
  253. return report_error('captcha check failed')
  254. if not video:
  255. return report_error('illegal video')
  256. if not tags:
  257. return report_error('illegal tags')
  258. try:
  259. video = await upload_video(session, video, tags)
  260. except (UserError, VideoError, SyntaxError) as error:
  261. return report_error(error)
  262. return web.json_response({
  263. 'video_id': video.id
  264. })