views.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
  2. # Copyright: (c) <spug.dev@gmail.com>
  3. # Released under the AGPL-3.0 License.
  4. from django.views.generic import View
  5. from django_redis import get_redis_connection
  6. from apps.host.models import Host
  7. from apps.account.utils import has_host_perm
  8. from apps.file.utils import FileResponseAfter, FileResponse, parse_sftp_attr
  9. from libs import json_response, JsonParser, Argument
  10. from functools import partial
  11. import os
  12. class FileView(View):
  13. def get(self, request):
  14. form, error = JsonParser(
  15. Argument('id', type=int, help='参数错误'),
  16. Argument('path', help='参数错误')
  17. ).parse(request.GET)
  18. if error is None:
  19. if not has_host_perm(request.user, form.id):
  20. return json_response(error='无权访问主机,请联系管理员')
  21. host = Host.objects.get(pk=form.id)
  22. if not host:
  23. return json_response(error='未找到指定主机')
  24. with host.get_ssh() as ssh:
  25. objects = ssh.list_dir_attr(form.path)
  26. return json_response([parse_sftp_attr(x) for x in objects])
  27. return json_response(error=error)
  28. class ObjectView(View):
  29. def get(self, request):
  30. form, error = JsonParser(
  31. Argument('id', type=int, help='参数错误'),
  32. Argument('file', help='请输入文件路径')
  33. ).parse(request.GET)
  34. if error is None:
  35. if not has_host_perm(request.user, form.id):
  36. return json_response(error='无权访问主机,请联系管理员')
  37. host = Host.objects.filter(pk=form.id).first()
  38. if not host:
  39. return json_response(error='未找到指定主机')
  40. filename = os.path.basename(form.file)
  41. ssh_cli = host.get_ssh().get_client()
  42. sftp = ssh_cli.open_sftp()
  43. f = sftp.open(form.file)
  44. return FileResponseAfter(ssh_cli.close, f, as_attachment=True, filename=filename)
  45. return json_response(error=error)
  46. def post(self, request):
  47. form, error = JsonParser(
  48. Argument('id', type=int, help='参数错误'),
  49. Argument('token', help='参数错误'),
  50. Argument('path', help='参数错误'),
  51. ).parse(request.POST)
  52. if error is None:
  53. if not has_host_perm(request.user, form.id):
  54. return json_response(error='无权访问主机,请联系管理员')
  55. file = request.FILES.get('file')
  56. if not file:
  57. return json_response(error='请选择要上传的文件')
  58. host = Host.objects.get(pk=form.id)
  59. if not host:
  60. return json_response(error='未找到指定主机')
  61. rds_cli = get_redis_connection()
  62. callback = partial(self._compute_progress, rds_cli, form.token, file.size)
  63. with host.get_ssh() as ssh:
  64. ssh.put_file_by_fl(file, f'{form.path}/{file.name}', callback=callback)
  65. return json_response(error=error)
  66. def delete(self, request):
  67. form, error = JsonParser(
  68. Argument('id', type=int, help='参数错误'),
  69. Argument('file', help='请输入文件路径')
  70. ).parse(request.GET)
  71. if error is None:
  72. if not has_host_perm(request.user, form.id):
  73. return json_response(error='无权访问主机,请联系管理员')
  74. host = Host.objects.get(pk=form.id)
  75. if not host:
  76. return json_response(error='未找到指定主机')
  77. with host.get_ssh() as ssh:
  78. ssh.remove_file(form.file)
  79. return json_response(error=error)
  80. def _compute_progress(self, rds_cli, token, total, value, *args):
  81. percent = '%.1f' % (value / total * 100)
  82. rds_cli.lpush(token, percent)
  83. rds_cli.expire(token, 300)