Files
encoach_frontend_new_v3/odoo/addons/mail/controllers/discuss/gif.py
Yamen Ahmad 3e83d8d7d5 feat: add complete EnCoach backend — Odoo 19 + all addons
Includes:
- Odoo 19 framework (odoo/)
- 27 custom EnCoach addons (new_project/custom_addons/)
  - encoach_core, encoach_api, encoach_lms_api, encoach_adaptive_api
  - encoach_exam, encoach_taxonomy, encoach_adaptive, encoach_assignment
  - encoach_ai, encoach_ai_grading, encoach_ai_generation, encoach_ai_media
  - encoach_courseware, encoach_communication, encoach_subscription
  - encoach_notification, encoach_approval, encoach_branding
  - encoach_classroom, encoach_registration, encoach_stats
  - encoach_faq, encoach_ticket, encoach_training, encoach_resources
  - encoach_adaptive_ai, encoach_sis
- 21 OpenEduCat Enterprise modules (new_project/enterprise-19/)
- 14 OpenEduCat Community modules (new_project/openeducat_erp-19.0/)
- Configuration: odoo.conf, requirements.txt, scripts
- 200+ REST API endpoints with JWT authentication
- SRS and test documentation

Made-with: Cursor
2026-04-01 17:10:04 +04:00

105 lines
4.0 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import requests
import urllib3
import werkzeug.urls
from werkzeug.exceptions import BadRequest
from odoo.http import request, route, Controller
TENOR_CONTENT_FILTER = "medium"
TENOR_GIF_LIMIT = 8
_logger = logging.getLogger(__name__)
class DiscussGifController(Controller):
def _request_gifs(self, endpoint):
response = None
try:
response = requests.get(
f"https://tenor.googleapis.com/v2/{endpoint}", timeout=3
)
response.raise_for_status()
except (urllib3.exceptions.MaxRetryError, requests.exceptions.HTTPError):
_logger.error("Exceeded the request's maximum size for a searching term.")
if not response:
raise BadRequest()
return response
@route("/discuss/gif/search", type="jsonrpc", auth="user")
def search(self, search_term, locale="en", country="US", position=None, readonly=True):
# sudo: ir.config_parameter - read keys are hard-coded and values are only used for server requests
ir_config = request.env["ir.config_parameter"].sudo()
query_string = werkzeug.urls.url_encode(
{
"q": search_term,
"key": ir_config.get_param("discuss.tenor_api_key"),
"client_key": request.env.cr.dbname,
"limit": TENOR_GIF_LIMIT,
"contentfilter": TENOR_CONTENT_FILTER,
"locale": locale,
"country": country,
"media_filter": "tinygif",
"pos": position,
}
)
response = self._request_gifs(f"search?{query_string}")
if response:
return response.json()
@route("/discuss/gif/categories", type="jsonrpc", auth="user", readonly=True)
def categories(self, locale="en", country="US"):
# sudo: ir.config_parameter - read keys are hard-coded and values are only used for server requests
ir_config = request.env["ir.config_parameter"].sudo()
query_string = werkzeug.urls.url_encode(
{
"key": ir_config.get_param("discuss.tenor_api_key"),
"client_key": request.env.cr.dbname,
"limit": TENOR_GIF_LIMIT,
"contentfilter": TENOR_CONTENT_FILTER,
"locale": locale,
"country": country,
}
)
response = self._request_gifs(f"categories?{query_string}")
if response:
return response.json()
@route("/discuss/gif/add_favorite", type="jsonrpc", auth="user")
def add_favorite(self, tenor_gif_id):
request.env["discuss.gif.favorite"].create({"tenor_gif_id": tenor_gif_id})
def _gif_posts(self, ids):
# sudo: ir.config_parameter - read keys are hard-coded and values are only used for server requests
ir_config = request.env["ir.config_parameter"].sudo()
query_string = werkzeug.urls.url_encode(
{
"ids": ",".join(ids),
"key": ir_config.get_param("discuss.tenor_api_key"),
"client_key": request.env.cr.dbname,
"media_filter": "tinygif",
}
)
response = self._request_gifs(f"posts?{query_string}")
if response:
return response.json()["results"]
@route("/discuss/gif/favorites", type="jsonrpc", auth="user", readonly=True)
def get_favorites(self, offset=0):
tenor_gif_ids = request.env["discuss.gif.favorite"].search(
[("create_uid", "=", request.env.user.id)], limit=20, offset=offset
)
return (self._gif_posts(tenor_gif_ids.mapped("tenor_gif_id")) or [],)
@route("/discuss/gif/remove_favorite", type="jsonrpc", auth="user")
def remove_favorite(self, tenor_gif_id):
request.env["discuss.gif.favorite"].search(
[
("create_uid", "=", request.env.user.id),
("tenor_gif_id", "=", tenor_gif_id),
]
).unlink()