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.

209 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(self.website_document_side_bar(
  40. date_begin=date_begin,
  41. date_end=date_end,
  42. user=request.env.user,
  43. ))
  44. values.update(self.display_categories_and_documents(
  45. date_begin=date_begin,
  46. date_end=date_end,
  47. user=request.env.user,
  48. ))
  49. values['size_to_str'] = self.size_to_str
  50. return request.render(
  51. 'easy_my_coop_website_document.template_website_document',
  52. values,
  53. )
  54. def website_document_side_bar(self, date_begin=None, date_end=None,
  55. user=None):
  56. domains = []
  57. # Show only doc that are published
  58. domains.append(('published', '=', True))
  59. # Show only authorized documents
  60. if not self._is_authorized_user(user):
  61. domains.append(('public', '=', True))
  62. # Show only doc in the time frame
  63. if date_begin and date_end:
  64. domains.append(('document_date', '>=', date_begin))
  65. domains.append(('document_date', '<', date_end))
  66. return {
  67. 'archive_groups': self._get_archive_groups(
  68. 'document_hosting.document',
  69. domains,
  70. fields=['name', 'document_date'],
  71. groupby='document_date',
  72. order='document_date desc'),
  73. }
  74. def display_categories_and_documents(self, date_begin=None, date_end=None,
  75. user=None):
  76. """Prepare value for display_categories_and_documents template"""
  77. data = self._data_tree()
  78. # Show only doc that are published
  79. data = self._data_filter_document(
  80. data,
  81. lambda r: r.published
  82. )
  83. # Show only authorized documents
  84. if not self._is_authorized_user(user):
  85. data = self._data_filter_document(
  86. data,
  87. lambda r: r.public
  88. )
  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: (r.document_date >= date_begin
  94. and r.document_date < date_end)
  95. )
  96. # After all the filter, remove the empty categories
  97. data = self._data_remove_empty_category(data)
  98. return {
  99. 'category_tree': data,
  100. }
  101. def size_to_str(self, size):
  102. units = ['o', 'ko', 'Mo', 'Go', 'To']
  103. size_float = float(size)
  104. for unit in units:
  105. if size_float < 1000:
  106. return '%.01f %s' % (size_float, unit)
  107. size_float /= 1000
  108. def _data_tree(self, category=None):
  109. """Return a tree with categories and documents in it"""
  110. category_mgr = request.env['document_hosting.document.category']
  111. document_mgr = request.env['document_hosting.document']
  112. if category:
  113. categories = category.child_ids.sorted(
  114. key=lambda r: r.name
  115. )
  116. documents = category.document_ids
  117. else:
  118. categories = category_mgr.sudo().search(
  119. [('parent_id', '=', False)],
  120. order="name"
  121. )
  122. documents = document_mgr.sudo().search(
  123. [('category', '=', False)]
  124. )
  125. if categories.ids:
  126. tree = []
  127. for cat in categories:
  128. tree.append(self._data_tree(cat))
  129. return (category, tree, documents)
  130. else:
  131. return (category, [], documents)
  132. def _data_filter_document(self, data, filter_fun):
  133. category, child_data, documents = data
  134. tree = []
  135. for entry in child_data:
  136. tree.append(
  137. self._data_filter_document(entry, filter_fun)
  138. )
  139. return (category, tree, documents.filtered(filter_fun))
  140. def _data_remove_empty_category(self, data):
  141. category, child_data, documents = data
  142. child_data = [
  143. self._data_remove_empty_category(c) for c in child_data
  144. if not self._data_is_empty(c)
  145. ]
  146. return (category, child_data, documents)
  147. def _data_is_empty(self, data):
  148. """Return True if data is empty"""
  149. _, child_data, documents = data
  150. # If there is documents, it's not empty.
  151. if documents.ids:
  152. return False
  153. # We are sure there is no documents.
  154. # If there is no child, it's empty.
  155. if not child_data:
  156. return True
  157. # We are sure there is childs
  158. for entry in child_data:
  159. # If a child is not empty, it's not empty
  160. if not self._data_is_empty(entry):
  161. return False
  162. # Else it's empty
  163. return True
  164. def _is_authorized_user(self, user=None):
  165. return user is not None and (user.has_group('base.group_portal')
  166. or user.has_group('base.group_user'))
  167. def _get_archive_groups(self, model, domain=None, fields=None,
  168. groupby="create_date", order="create_date desc"):
  169. if not model:
  170. return []
  171. if domain is None:
  172. domain = []
  173. if fields is None:
  174. fields = ['name', 'create_date']
  175. groups = []
  176. for group in request.env[model].sudo().read_group(
  177. domain, fields=fields, groupby=groupby, orderby=order):
  178. label = group[groupby]
  179. date_begin = date_end = None
  180. for leaf in group["__domain"]:
  181. if leaf[0] == groupby:
  182. if leaf[1] == ">=":
  183. date_begin = leaf[2]
  184. elif leaf[1] == "<":
  185. date_end = leaf[2]
  186. groups.append({
  187. 'date_begin': Date.to_string(Date.from_string(date_begin)),
  188. 'date_end': Date.to_string(Date.from_string(date_end)),
  189. 'name': label,
  190. 'item_count': group[groupby + '_count']
  191. })
  192. return groups