You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
7.5 KiB

  1. # Copyright 2018 Rémy Taymans <remytaymans@gmail.com>
  2. # Copyright 2015-2016 Odoo S.A.
  3. # Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  5. import base64
  6. from odoo import http
  7. from odoo.http import request, Response
  8. from odoo.fields import Date
  9. class DocumentWebsite(http.Controller):
  10. @http.route("/documents/<int:oid>", auth="public", website=True)
  11. def get_document(self, oid=-1):
  12. """Render a http response for a document"""
  13. document_mgr = request.env["document_hosting.document"]
  14. doc = document_mgr.sudo().browse(oid)
  15. ir_http_mgr = request.env["ir.http"]
  16. status, headers, content = ir_http_mgr.sudo().binary_content(
  17. model=doc._name,
  18. id=oid,
  19. field="document",
  20. filename_field="filename",
  21. download=True,
  22. )
  23. if status == 304:
  24. return Response(status, headers)
  25. elif status == 301:
  26. # TODO: test this case not sure if this render the same
  27. # return werkzeug.utils.redirect(content, code=301)
  28. return request.redirect(content, code=301)
  29. elif status != 200:
  30. return request.not_found()
  31. content_base64 = base64.b64decode(content)
  32. headers.append(("Content-Length", len(content_base64)))
  33. return request.make_response(content_base64, headers)
  34. @http.route("/documents", auth="public", website=True)
  35. def template_website_document(self, date_begin=None, date_end=None, **kw):
  36. """
  37. """
  38. values = {}
  39. values.update(
  40. self.website_document_side_bar(
  41. date_begin=date_begin,
  42. date_end=date_end,
  43. user=request.env.user,
  44. )
  45. )
  46. values.update(
  47. self.display_categories_and_documents(
  48. date_begin=date_begin,
  49. date_end=date_end,
  50. user=request.env.user,
  51. )
  52. )
  53. values["size_to_str"] = self.size_to_str
  54. return request.render(
  55. "easy_my_coop_website_document.template_website_document", values,
  56. )
  57. def website_document_side_bar(
  58. self, date_begin=None, date_end=None, user=None
  59. ):
  60. domains = []
  61. # Show only doc that are published
  62. domains.append(("published", "=", True))
  63. # Show only authorized documents
  64. if not self._is_authorized_user(user):
  65. domains.append(("public", "=", True))
  66. # Show only doc in the time frame
  67. if date_begin and date_end:
  68. domains.append(("document_date", ">=", date_begin))
  69. domains.append(("document_date", "<", date_end))
  70. return {
  71. "archive_groups": self._get_archive_groups(
  72. "document_hosting.document",
  73. domains,
  74. fields=["name", "document_date"],
  75. groupby="document_date",
  76. order="document_date desc",
  77. ),
  78. }
  79. def display_categories_and_documents(
  80. self, date_begin=None, date_end=None, user=None
  81. ):
  82. """Prepare value for display_categories_and_documents template"""
  83. data = self._data_tree()
  84. # Show only doc that are published
  85. data = self._data_filter_document(data, lambda r: r.published)
  86. # Show only authorized documents
  87. if not self._is_authorized_user(user):
  88. data = self._data_filter_document(data, lambda r: r.public)
  89. # Show only doc in the time frame
  90. if date_begin and date_end:
  91. data = self._data_filter_document(
  92. data,
  93. lambda r: (
  94. r.document_date >= date_begin
  95. and r.document_date < date_end
  96. ),
  97. )
  98. # After all the filter, remove the empty categories
  99. data = self._data_remove_empty_category(data)
  100. return {
  101. "category_tree": data,
  102. }
  103. def size_to_str(self, size):
  104. units = ["o", "ko", "Mo", "Go", "To"]
  105. size_float = float(size)
  106. for unit in units:
  107. if size_float < 1000:
  108. return "%.01f %s" % (size_float, unit)
  109. size_float /= 1000
  110. def _data_tree(self, category=None):
  111. """Return a tree with categories and documents in it"""
  112. category_mgr = request.env["document_hosting.document.category"]
  113. document_mgr = request.env["document_hosting.document"]
  114. if category:
  115. categories = category.child_ids.sorted(key=lambda r: r.name)
  116. documents = category.document_ids
  117. else:
  118. categories = category_mgr.sudo().search(
  119. [("parent_id", "=", False)], order="name"
  120. )
  121. documents = document_mgr.sudo().search([("category", "=", False)])
  122. if categories.ids:
  123. tree = []
  124. for cat in categories:
  125. tree.append(self._data_tree(cat))
  126. return (category, tree, documents)
  127. else:
  128. return (category, [], documents)
  129. def _data_filter_document(self, data, filter_fun):
  130. category, child_data, documents = data
  131. tree = []
  132. for entry in child_data:
  133. tree.append(self._data_filter_document(entry, filter_fun))
  134. return (category, tree, documents.filtered(filter_fun))
  135. def _data_remove_empty_category(self, data):
  136. category, child_data, documents = data
  137. child_data = [
  138. self._data_remove_empty_category(c)
  139. for c in child_data
  140. if not self._data_is_empty(c)
  141. ]
  142. return (category, child_data, documents)
  143. def _data_is_empty(self, data):
  144. """Return True if data is empty"""
  145. _, child_data, documents = data
  146. # If there is documents, it's not empty.
  147. if documents.ids:
  148. return False
  149. # We are sure there is no documents.
  150. # If there is no child, it's empty.
  151. if not child_data:
  152. return True
  153. # We are sure there is childs
  154. for entry in child_data:
  155. # If a child is not empty, it's not empty
  156. if not self._data_is_empty(entry):
  157. return False
  158. # Else it's empty
  159. return True
  160. def _is_authorized_user(self, user=None):
  161. return user is not None and (
  162. user.has_group("base.group_portal")
  163. or user.has_group("base.group_user")
  164. )
  165. def _get_archive_groups(
  166. self,
  167. model,
  168. domain=None,
  169. fields=None,
  170. groupby="create_date",
  171. order="create_date desc",
  172. ):
  173. if not model:
  174. return []
  175. if domain is None:
  176. domain = []
  177. if fields is None:
  178. fields = ["name", "create_date"]
  179. groups = []
  180. for group in (
  181. request.env[model]
  182. .sudo()
  183. .read_group(domain, fields=fields, groupby=groupby, orderby=order)
  184. ):
  185. label = group[groupby]
  186. date_begin = date_end = None
  187. for leaf in group["__domain"]:
  188. if leaf[0] == groupby:
  189. if leaf[1] == ">=":
  190. date_begin = leaf[2]
  191. elif leaf[1] == "<":
  192. date_end = leaf[2]
  193. groups.append(
  194. {
  195. "date_begin": Date.to_string(Date.from_string(date_begin)),
  196. "date_end": Date.to_string(Date.from_string(date_end)),
  197. "name": label,
  198. "item_count": group[groupby + "_count"],
  199. }
  200. )
  201. return groups