directory_image.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import pathlib
  2. from .image import image
  3. from .product import product
  4. from .exception import directory_image_exception
  5. class directory_image:
  6. """
  7. This is image directory manager. It could store new images for product,
  8. move it, when product name had been changed, and also remove images.
  9. """
  10. def __init__(self, target: pathlib.Path, thumbnail: int = 400) -> None:
  11. """
  12. This initialize new manager.
  13. Parameters;
  14. target (pathlib.Path): Directory to store images in
  15. thumbnail (int): Dimension of the thumbnails
  16. """
  17. self.__target = target
  18. self.__thumbnail_size = thumbnail
  19. if not self.__target.is_dir():
  20. self.__target.mkdir()
  21. @property
  22. def thumbnail_size(self) -> int:
  23. """ Diameter of the thumbnails. """
  24. return self.__thumbnail_size
  25. def server_path() -> str:
  26. """ This return where bind covers on server. """
  27. return "/covers"
  28. @property
  29. def target(self) -> pathlib.Path:
  30. """ Target directory of the manager. """
  31. return self.__target
  32. def __name(self, target: product) -> str:
  33. """
  34. Base name of the image.
  35. Parameters:
  36. target (product): Target product to generate name of
  37. Returns:
  38. (str): Base part of the name
  39. """
  40. return target.name.encode("UTF-8").hex()
  41. def get_full_name(self, target: product) -> str:
  42. """
  43. Name of the full size image.
  44. Parameters:
  45. target (product): Target product to generate name of
  46. Returns:
  47. (str): Name of the full size file
  48. """
  49. return self.__name(target) + ".full.png"
  50. def get_thumbnail_name(self, target: product) -> str:
  51. """
  52. Name of the thumbnail.
  53. Parameters:
  54. target (product): Target product to generate name of
  55. Returns:
  56. (str): Name of the thumnail file
  57. """
  58. return self.__name(target) + ".thumbnail.webp"
  59. def __full_path(self, target: product) -> pathlib.Path:
  60. """
  61. Path of the full size image.
  62. Parameters:
  63. target (product): Target product to generate path from
  64. Returns:
  65. (pathlib.Parh): Path of the image
  66. """
  67. return self.target / pathlib.Path(self.get_full_name(target))
  68. def __thumbnail_path(self, target: product) -> pathlib.Path:
  69. """
  70. Path of the thumbnail image.
  71. Parameters:
  72. target (product): Target product to generate path from
  73. Returns:
  74. (pathlib.Parh): Path of the thumbnail
  75. """
  76. return self.target / pathlib.Path(self.get_thumbnail_name(target))
  77. def save(self, content: image, target: product) -> None:
  78. """
  79. This save new image for new product.
  80. Parameters:
  81. coded (str): Base64 coded received image
  82. target (product): Target product to save image for
  83. """
  84. full = self.__full_path(target)
  85. thumbnail = self.__thumbnail_path(target)
  86. if full.is_file() or thumbnail.is_file():
  87. content = "Images for product \"" + target.name + "\" "
  88. content = content + "already exists."
  89. raise directory_image_exception(content)
  90. content \
  91. .save_full(full) \
  92. .save_thumbnail(thumbnail, self.thumbnail_size)
  93. def drop(self, target: product) -> None:
  94. """
  95. This drop images for given product.
  96. Parameters:
  97. target (product): Target product to remove images for
  98. """
  99. full = self.__full_path(target)
  100. thumbnail = self.__thumbnail_path(target)
  101. if not full.is_file() or not thumbnail.is_file():
  102. content = "Can not remove images for \"" + target.name + "\" "
  103. content = content + "it not exiets."
  104. raise directory_image_exception(content)
  105. full.unlink()
  106. thumbnail.unlink()
  107. def update(self, old: product, new: product) -> None:
  108. """
  109. This update names of the images for product. Name of the images is
  110. connected with name of the product, and when name of the product
  111. had been changed, also images must be updated.
  112. Parameters:
  113. old (product): Product before update
  114. new (product): Product after update
  115. """
  116. same_name = (
  117. self.get_thumbnail_name(old) == self.get_thumbnail_name(new) and \
  118. self.get_full_name(old) == self.get_full_name(new)
  119. )
  120. if same_name:
  121. return
  122. old_full = self.__full_path(old)
  123. old_thumbnail = self.__thumbnail_path(old)
  124. if not old_full.is_file() or not old_thumbnail.is_file():
  125. content = "Can not move file for \"" + old.name + "\" "
  126. content = content + "because not exists."
  127. raise directory_image_exception(content)
  128. new_full = self.__full_path(new)
  129. new_thumbnail = self.__thumbnail_path(new)
  130. if new_full.is_file() or new_thumbnail.is_file():
  131. content = "Can not move, because images for \"" + new.name + "\" "
  132. content = content + "already exists."
  133. raise directory_image_exception(content)
  134. old_full.rename(new_full)
  135. old_thumbnail.rename(new_thumbnail)