diff --git a/mail_discuss_channel_giphy/README.rst b/mail_discuss_channel_giphy/README.rst new file mode 100644 index 0000000000..41e83848ef --- /dev/null +++ b/mail_discuss_channel_giphy/README.rst @@ -0,0 +1,99 @@ +========================== +Mail Discuss Channel GIPHY +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9b6ca9b608ff0d44bff4e7196bdbca2edac8350bbb2b63316c6afba1a49b8670 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/17.0/mail_discuss_channel_giphy + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-17-0/social-17-0-mail_discuss_channel_giphy + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module changes the tenor API for Giphy to use it con discuss +channels + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +You just need to set up your Giphy API key under Settings → GIPHY API +Key. + +You can especify rating and fetch limit under Settings → GIPHY Rating +and Settings → GIPHY GIF Limits + +**Important** After installing this module, only Giphy will be available +for use. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* APSL-Nagarro + +Contributors +------------ + +`APSL-Nagarro `__: + +- Bernat Obrador + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-BernatObrador| image:: https://github.com/BernatObrador.png?size=40px + :target: https://github.com/BernatObrador + :alt: BernatObrador + +Current `maintainer `__: + +|maintainer-BernatObrador| + +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_discuss_channel_giphy/__init__.py b/mail_discuss_channel_giphy/__init__.py new file mode 100644 index 0000000000..f7209b1710 --- /dev/null +++ b/mail_discuss_channel_giphy/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import controllers diff --git a/mail_discuss_channel_giphy/__manifest__.py b/mail_discuss_channel_giphy/__manifest__.py new file mode 100644 index 0000000000..2cc020e39c --- /dev/null +++ b/mail_discuss_channel_giphy/__manifest__.py @@ -0,0 +1,15 @@ +{ + "name": "Mail Discuss Channel GIPHY", + "summary": ("Use Giphy instead of tenor for gifs in discuss channels"), + "category": "Discuss", + "author": "APSL-Nagarro, Odoo Community Association (OCA)", + "version": "17.0.1.0.0", + "depends": ["mail"], + "maintainers": ["BernatObrador"], + "data": [ + "views/res_config_settings.xml", + ], + "website": "https://github.com/OCA/social", + "license": "LGPL-3", + "application": False, +} diff --git a/mail_discuss_channel_giphy/controllers/__init__.py b/mail_discuss_channel_giphy/controllers/__init__.py new file mode 100644 index 0000000000..bff507a569 --- /dev/null +++ b/mail_discuss_channel_giphy/controllers/__init__.py @@ -0,0 +1 @@ +from . import giphy_gif diff --git a/mail_discuss_channel_giphy/controllers/giphy_gif.py b/mail_discuss_channel_giphy/controllers/giphy_gif.py new file mode 100644 index 0000000000..d6a79340ba --- /dev/null +++ b/mail_discuss_channel_giphy/controllers/giphy_gif.py @@ -0,0 +1,115 @@ +# Copyright 2026 Bernat Obrador APSL-Nagarro +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import requests + +from odoo import http +from odoo.http import request + +from odoo.addons.mail.controllers.discuss.gif import DiscussGifController + + +class GiphyGifController(DiscussGifController): + """ + Inherit to add the logic for giphy api. + It replace the calls needed to work with giphy. + It will still use fields that are used for tenor + for handeling favorites gifs + """ + + def _get_api_key(self): + return ( + request.env["ir.config_parameter"].sudo().get_param("discuss.giphy_api_key") + ) + + def _normalize_gif(self, gif): + images = gif.get("images", {}) + # Use fixed_height_small for thumbnails (similar to Tenor tinygif) + tiny = ( + images.get("fixed_height_small") + or images.get("fixed_height") + or images.get("downsized") + or images.get("original") + ) + url = tiny.get("url") if tiny else None + dims = [ + int(tiny.get("width", 0)) if tiny else 0, + int(tiny.get("height", 0)) if tiny else 0, + ] + send_url = ( + images.get("original") or images.get("downsized") or tiny or {} + ).get("url") + return { + "id": gif.get("id"), + "title": gif.get("title") or "", + "media_formats": { + "tinygif": { + "url": url, + "dims": dims, + } + }, + "url": send_url, + } + + @http.route("/discuss/gif/search", type="json", auth="user") + def search(self, search_term, locale="en", country="US", position=None): + api_key = self._get_api_key() + if not api_key: + return {"results": [], "next": None} + ir_config = request.env["ir.config_parameter"].sudo() + + rating = ir_config.get_param("discuss.giphy_rating") + rating = rating if rating != "any" else "" + params = { + "api_key": api_key, + "q": search_term, + "limit": ir_config.get_param("discuss.giphy_gif_limit"), + "rating": rating, + "offset": int(position or 0), + "lang": locale[:2] if locale else "en", + "country_code": country, + } + resp = requests.get( + "https://api.giphy.com/v1/gifs/search", params=params, timeout=8 + ) + resp.raise_for_status() + data = resp.json() + results = [self._normalize_gif(g) for g in data.get("data", [])] + pagination = data.get("pagination", {}) + next_offset = None + if pagination: + offset = pagination.get("offset") or 0 + count = pagination.get("count") or 0 + total_count = pagination.get("total_count") or 0 + if offset + count < total_count: + next_offset = offset + count + return {"results": results, "next": next_offset} + + @http.route("/discuss/gif/categories", type="json", auth="user") + def categories(self, locale="en", country="US"): + # Giphy does not have a stable categories endpoint like tenor, + # so we return an empty list. + return {"tags": []} + + def _gif_posts(self, ids): + api_key = self._get_api_key() + if not api_key or not ids: + return [] + resp = requests.get( + "https://api.giphy.com/v1/gifs", + params={"api_key": api_key, "ids": ",".join(ids)}, + timeout=8, + ) + resp.raise_for_status() + data = resp.json() + return [self._normalize_gif(g) for g in data.get("data", [])] + + @http.route("/discuss/gif/favorites", type="json", auth="user") + def get_favorites(self, offset=0): + gif_ids = ( + request.env["discuss.gif.favorite"] + .sudo() + .search([("create_uid", "=", request.env.user.id)], limit=20, offset=offset) + .mapped("tenor_gif_id") + ) + return (self._gif_posts(gif_ids),) diff --git a/mail_discuss_channel_giphy/models/__init__.py b/mail_discuss_channel_giphy/models/__init__.py new file mode 100644 index 0000000000..0a9191cf61 --- /dev/null +++ b/mail_discuss_channel_giphy/models/__init__.py @@ -0,0 +1,3 @@ +from . import res_config_settings +from . import mail_guest +from . import res_users diff --git a/mail_discuss_channel_giphy/models/mail_guest.py b/mail_discuss_channel_giphy/models/mail_guest.py new file mode 100644 index 0000000000..dcb1a5cbac --- /dev/null +++ b/mail_discuss_channel_giphy/models/mail_guest.py @@ -0,0 +1,15 @@ +# Copyright 2026 Bernat Obrador APSL-Nagarro +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class MailGuest(models.Model): + _inherit = "mail.guest" + + def _init_messaging(self): + res = super()._init_messaging() + res["hasGifPickerFeature"] = bool( + self.env["ir.config_parameter"].sudo().get_param("discuss.giphy_api_key") + ) + return res diff --git a/mail_discuss_channel_giphy/models/res_config_settings.py b/mail_discuss_channel_giphy/models/res_config_settings.py new file mode 100644 index 0000000000..5a732f92cc --- /dev/null +++ b/mail_discuss_channel_giphy/models/res_config_settings.py @@ -0,0 +1,23 @@ +# Copyright 2026 Bernat Obrador APSL-Nagarro +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + giphy_api_key = fields.Char( + string="GIPHY API Key", + config_parameter="discuss.giphy_api_key", + ) + giphy_gif_limit = fields.Integer( + default=8, + config_parameter="discuss.giphy_gif_limit", + help="Fetch up to the specified number of GIF.", + ) + giphy_rating = fields.Selection( + [("g", "G"), ("pg", "PG"), ("pg-13", "PG-13"), ("r", "R"), ("any", "Any")], + config_parameter="discuss.giphy_rating", + default="pg", + ) diff --git a/mail_discuss_channel_giphy/models/res_users.py b/mail_discuss_channel_giphy/models/res_users.py new file mode 100644 index 0000000000..66d94f47c3 --- /dev/null +++ b/mail_discuss_channel_giphy/models/res_users.py @@ -0,0 +1,15 @@ +# Copyright 2026 Bernat Obrador APSL-Nagarro +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class ResUsers(models.Model): + _inherit = "res.users" + + def _init_messaging(self): + res = super()._init_messaging() + res["hasGifPickerFeature"] = bool( + self.env["ir.config_parameter"].sudo().get_param("discuss.giphy_api_key") + ) + return res diff --git a/mail_discuss_channel_giphy/pyproject.toml b/mail_discuss_channel_giphy/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/mail_discuss_channel_giphy/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_discuss_channel_giphy/readme/CONTRIBUTORS.md b/mail_discuss_channel_giphy/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..a555a7d7ea --- /dev/null +++ b/mail_discuss_channel_giphy/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +[APSL-Nagarro](https://apsl.tech): + - Bernat Obrador \<\> diff --git a/mail_discuss_channel_giphy/readme/DESCRIPTION.md b/mail_discuss_channel_giphy/readme/DESCRIPTION.md new file mode 100644 index 0000000000..ad8726a55d --- /dev/null +++ b/mail_discuss_channel_giphy/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module changes the tenor API for Giphy to use it con discuss channels \ No newline at end of file diff --git a/mail_discuss_channel_giphy/readme/USAGE.md b/mail_discuss_channel_giphy/readme/USAGE.md new file mode 100644 index 0000000000..6592831082 --- /dev/null +++ b/mail_discuss_channel_giphy/readme/USAGE.md @@ -0,0 +1,6 @@ +You just need to set up your Giphy API key under Settings → GIPHY API Key. + +You can especify rating and fetch limit under Settings → GIPHY Rating and Settings → GIPHY GIF Limits + +**Important** +After installing this module, only Giphy will be available for use. diff --git a/mail_discuss_channel_giphy/static/description/icon.png b/mail_discuss_channel_giphy/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/mail_discuss_channel_giphy/static/description/icon.png differ diff --git a/mail_discuss_channel_giphy/static/description/index.html b/mail_discuss_channel_giphy/static/description/index.html new file mode 100644 index 0000000000..36597066a5 --- /dev/null +++ b/mail_discuss_channel_giphy/static/description/index.html @@ -0,0 +1,437 @@ + + + + + +Mail Discuss Channel GIPHY + + + +
+

Mail Discuss Channel GIPHY

+ + +

Beta License: LGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module changes the tenor API for Giphy to use it con discuss +channels

+

Table of contents

+ +
+

Usage

+

You just need to set up your Giphy API key under Settings → GIPHY API +Key.

+

You can especify rating and fetch limit under Settings → GIPHY Rating +and Settings → GIPHY GIF Limits

+

Important After installing this module, only Giphy will be available +for use.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • APSL-Nagarro
  • +
+
+
+

Contributors

+

APSL-Nagarro:

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

BernatObrador

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mail_discuss_channel_giphy/views/res_config_settings.xml b/mail_discuss_channel_giphy/views/res_config_settings.xml new file mode 100644 index 0000000000..544accf04f --- /dev/null +++ b/mail_discuss_channel_giphy/views/res_config_settings.xml @@ -0,0 +1,45 @@ + + + + res.config.settings.view.form.giphy + res.config.settings + + + + True + + + True + + + True + + + + + + + + + + + + + + +