utils.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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.http import FileResponse
  5. import stat
  6. import time
  7. KB = 1024
  8. MB = 1024 * 1024
  9. GB = 1024 * 1024 * 1024
  10. TB = 1024 * 1024 * 1024 * 1024
  11. class FileResponseAfter(FileResponse):
  12. def __init__(self, callback, *args, **kwargs):
  13. super().__init__(*args, **kwargs)
  14. self.callback = callback
  15. def close(self):
  16. super().close()
  17. self.callback()
  18. def parse_mode(obj):
  19. if obj.st_mode:
  20. mt = stat.S_IFMT(obj.st_mode)
  21. if mt == stat.S_IFIFO:
  22. kind = "p"
  23. elif mt == stat.S_IFCHR:
  24. kind = "c"
  25. elif mt == stat.S_IFDIR:
  26. kind = "d"
  27. elif mt == stat.S_IFBLK:
  28. kind = "b"
  29. elif mt == stat.S_IFREG:
  30. kind = "-"
  31. elif mt == stat.S_IFLNK:
  32. kind = "l"
  33. elif mt == stat.S_IFSOCK:
  34. kind = "s"
  35. else:
  36. kind = "?"
  37. code = obj._rwx(
  38. (obj.st_mode & 448) >> 6, obj.st_mode & stat.S_ISUID
  39. )
  40. code += obj._rwx(
  41. (obj.st_mode & 56) >> 3, obj.st_mode & stat.S_ISGID
  42. )
  43. code += obj._rwx(
  44. obj.st_mode & 7, obj.st_mode & stat.S_ISVTX, True
  45. )
  46. else:
  47. kind = "?"
  48. code = '---------'
  49. return kind, code
  50. def format_size(size):
  51. if size:
  52. if size < KB:
  53. return f'{size}B'
  54. if size < MB:
  55. return f'{size / KB:.1f}K'
  56. if size < GB:
  57. return f'{size / MB:.1f}M'
  58. if size < TB:
  59. return f'{size / GB:.1f}G'
  60. return f'{size / TB:.1f}T'
  61. else:
  62. return ''
  63. def parse_sftp_attr(obj):
  64. if (obj.st_mtime is None) or (obj.st_mtime == int(0xffffffff)):
  65. date = "(unknown date)"
  66. else:
  67. date = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(obj.st_mtime))
  68. kind, code = parse_mode(obj)
  69. is_dir = stat.S_ISDIR(obj.st_mode) if obj.st_mode else False
  70. size = obj.st_size or ''
  71. return {
  72. 'name': getattr(obj, 'filename', '?'),
  73. 'size': '' if is_dir else format_size(size),
  74. 'date': date,
  75. 'kind': kind,
  76. 'code': code
  77. }