diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/LICENSE b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/LICENSE
deleted file mode 100644
index 5f7a2f3..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/LICENSE
+++ /dev/null
@@ -1,11 +0,0 @@
-Odoo Proprietary License v1.0
-
-This software and associated files (the “Software”) may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file).
-
-You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one).
-
-It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software.
-
-The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/README.rst b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/README.rst
deleted file mode 100644
index 04528de..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/README.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-==================
-Otoolkit Auth
-==================
-
-This module allows you to configure your Otoolkit account in odoo. You will then be able to use all the Otoolkit apps.
-
-
-Question and contact
-==========
-If you have any questions or recommendations about this module, please contact us at contact@otoolkit.app
-
-Installation
-============
-
-To install this module:
-
-1. Download and place the module in your Odoo addons directory.
-2. Access your Odoo server and navigate to the Apps menu.
-3. Enable debug mode, then refresh the list by selecting Update Apps List.
-4. Finally, click the Install button to complete the installation.
-
-Upgrade
-============
-
-To upgrade this module:
-
-1. Download the updated module and replace the existing one in your Odoo addons directory.
-2. Restart your Odoo server.
-3. Log in, go to the Apps menu, and click the Upgrade button for the module.
-
-
-Configuration
-=============
-
-To configure the module, follow these steps:
-
-1. Go to the Settings menu of your Odoo instance.
-2. Go to the Otoolkit section.
-3. Add your API Key from your Otoolkit account.
-
-How to Generate an API Key ?
-
-1. Visit https://otoolkit.app and create an account (if you don’t already have one).
-2. Once logged in, navigate to the Developers section in your Otoolkit dashboard.
-3. Generate a new API Key and copy it.
-4. Paste the copied key into the Otoolkit section in your Odoo settings.
-
-Credits
-=======
-
-Author & Maintainer
--------------------
-
-This module is maintained by the Otoolkit team.
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__init__.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__init__.py
deleted file mode 100644
index 0650744..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import models
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__manifest__.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__manifest__.py
deleted file mode 100644
index 5ace7df..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/__manifest__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- coding: utf-8 -*-
-{
- 'name': "O'Toolkit",
- 'summary': "This app is the basic block of the Otoolkit integration. It allows you to connect your Otoolkit account to your Odoo instance.",
- 'description': """""",
- 'author': "O'Solutions Company",
- 'website': "https://osolutions.app/products/o-toolkit",
- 'category': 'Other',
- 'version': '19.0.1.0.0',
- 'depends': [],
- "external_dependencies": {"python": ["requests"]},
- 'data': [
- # security
- "security/otoolkit_security.xml",
-
- # views
- "views/menu_views.xml",
- "views/res_config_settings_views.xml",
-
- # data
- "data/ir_config_parameter.xml"
- ],
- 'images': ['static/description/cover.jpeg'],
- 'license': 'OPL-1',
- 'installable': True,
- 'application': True,
-}
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/data/ir_config_parameter.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/data/ir_config_parameter.xml
deleted file mode 100644
index a08050b..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/data/ir_config_parameter.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
- otoolkit.api.endpoint
- https://api.otoolkit.app
-
-
-
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/doc/index.rst b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/doc/index.rst
deleted file mode 100644
index 04528de..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/doc/index.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-==================
-Otoolkit Auth
-==================
-
-This module allows you to configure your Otoolkit account in odoo. You will then be able to use all the Otoolkit apps.
-
-
-Question and contact
-==========
-If you have any questions or recommendations about this module, please contact us at contact@otoolkit.app
-
-Installation
-============
-
-To install this module:
-
-1. Download and place the module in your Odoo addons directory.
-2. Access your Odoo server and navigate to the Apps menu.
-3. Enable debug mode, then refresh the list by selecting Update Apps List.
-4. Finally, click the Install button to complete the installation.
-
-Upgrade
-============
-
-To upgrade this module:
-
-1. Download the updated module and replace the existing one in your Odoo addons directory.
-2. Restart your Odoo server.
-3. Log in, go to the Apps menu, and click the Upgrade button for the module.
-
-
-Configuration
-=============
-
-To configure the module, follow these steps:
-
-1. Go to the Settings menu of your Odoo instance.
-2. Go to the Otoolkit section.
-3. Add your API Key from your Otoolkit account.
-
-How to Generate an API Key ?
-
-1. Visit https://otoolkit.app and create an account (if you don’t already have one).
-2. Once logged in, navigate to the Developers section in your Otoolkit dashboard.
-3. Generate a new API Key and copy it.
-4. Paste the copied key into the Otoolkit section in your Odoo settings.
-
-Credits
-=======
-
-Author & Maintainer
--------------------
-
-This module is maintained by the Otoolkit team.
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/i18n/fr.po b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/i18n/fr.po
deleted file mode 100644
index 5a1ea6f..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/i18n/fr.po
+++ /dev/null
@@ -1,109 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * otoolkit_auth
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 17.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-01-16 10:59+0000\n"
-"PO-Revision-Date: 2025-01-16 10:59+0000\n"
-"Last-Translator: \n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: \n"
-"Plural-Forms: \n"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid ""
-"\n"
-" Open Website"
-msgstr ""
-"\n"
-"Aller sur le site"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "API Authentication"
-msgstr "Authentification"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "API Key"
-msgstr "Cléf API"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Available balance on the account"
-msgstr "Solde disponible sur votre compte"
-
-#. module: otoolkit_auth
-#: model:ir.model,name:otoolkit_auth.model_res_config_settings
-msgid "Config Settings"
-msgstr "Paramètres de configuration"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Enter an API key of your Otoolkit account here"
-msgstr "Entrez une clé API de votre compte Otoolkit ici"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Otoolkit"
-msgstr ""
-
-#. module: otoolkit_auth
-#: model:ir.model.fields,field_description:otoolkit_auth.field_res_config_settings__otoolkit_api_key
-msgid "Otoolkit API key"
-msgstr "Clés API Otoolkit"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Otoolkit Account"
-msgstr "Compte Otoolkit"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Otoolkit Tokens"
-msgstr "Crédits Otookit"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "Refresh token count"
-msgstr "Rafraîchir le nombre de crédits"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "The API key is invalid. Please update your settings."
-msgstr "La clé API n'est pas valide. Veuillez mettre à jour vos paramètres."
-
-#. module: otoolkit_auth
-#: model:ir.model.fields,help:otoolkit_auth.field_res_config_settings__otoolkit_api_key
-msgid "This API key allow you to communicate with the otoolkit api."
-msgstr "Cette clé API vous permet de communiquer avec l'API otoolkit."
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid ""
-"To generate an API key, you need to create an Otoolkit account. To do this, "
-"follow the link below."
-msgstr ""
-"Pour générer une clé API, vous devez créer un compte Otoolkit. Pour ce "
-"faire, suivez le lien ci-dessous."
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "To use otoolkit services, you need a valid api key."
-msgstr "Pour utiliser les services otoolkit, vous avez besoin d'une clé api valide."
-
-#. module: otoolkit_auth
-#: model:ir.model.fields,field_description:otoolkit_auth.field_res_config_settings__otoolkit_api_token_count
-msgid "Token Count"
-msgstr "Nombre de crédits"
-
-#. module: otoolkit_auth
-#: model_terms:ir.ui.view,arch_db:otoolkit_auth.res_config_settings_view_form
-msgid "tokens"
-msgstr "crédits"
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/__init__.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/__init__.py
deleted file mode 100644
index 8c9ac1b..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from . import res_config_settings
-from . import schema_builder
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/res_config_settings.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/res_config_settings.py
deleted file mode 100644
index 6335502..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/res_config_settings.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import logging
-import requests
-
-from odoo import models, fields, api
-
-_logger = logging.getLogger(__name__)
-
-# Sentinel values for token count status
-_NO_KEY = -1
-_ERROR = -2
-
-
-class ResConfigSettings(models.TransientModel):
- _inherit = 'res.config.settings'
-
- otoolkit_api_key = fields.Char(
- string="O'Toolkit API Key",
- config_parameter='otoolkit_api_key',
- help="API key from your O'Solutions portal (portal.osolutions.app).",
- )
-
- otoolkit_api_token_count = fields.Integer(
- string='Token Balance',
- compute='_compute_token_count',
- config_parameter='otoolkit_api_token_count',
- readonly=True,
- default=_NO_KEY,
- )
-
- otoolkit_key_status = fields.Selection(
- [('valid', 'Valid'), ('invalid', 'Invalid'), ('error', 'Connection Error'), ('none', 'No Key')],
- string='Key Status',
- compute='_compute_token_count',
- )
-
- def _get_token_balance(self, api_key):
- """Fetch token balance from O'Toolkit API (which validates via FastAPI)."""
- api_endpoint = self.env['ir.config_parameter'].sudo().get_param(
- 'otoolkit.api.endpoint', 'https://api.otoolkit.app'
- )
- if not api_key:
- return _NO_KEY, 'none'
-
- headers = {
- 'Odoo-Api-Key': api_key,
- 'Content-Type': 'application/json',
- }
- try:
- response = requests.get(
- f"{api_endpoint.rstrip('/')}/api/get-token-count/",
- headers=headers,
- timeout=10,
- )
- except requests.exceptions.RequestException as e:
- _logger.warning("O'Toolkit API connection error: %s", e)
- return _ERROR, 'error'
-
- if response.status_code == 200:
- data = response.json()
- return data.get('token_count', 0), 'valid'
- if response.status_code == 401:
- return 0, 'invalid'
-
- _logger.warning("O'Toolkit API returned %s: %s", response.status_code, response.text[:200])
- return _ERROR, 'error'
-
- @api.depends('otoolkit_api_key')
- def _compute_token_count(self):
- for record in self:
- api_key = record.otoolkit_api_key
- count, status = record._get_token_balance(api_key)
- record.otoolkit_api_token_count = count
- record.otoolkit_key_status = status
- self.env['ir.config_parameter'].sudo().set_param(
- 'otoolkit_api_token_count', str(count)
- )
-
- def refresh_token_count(self):
- self._compute_token_count()
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/schema_builder.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/schema_builder.py
deleted file mode 100644
index 1a7c1d2..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/models/schema_builder.py
+++ /dev/null
@@ -1,242 +0,0 @@
-import logging
-
-from odoo import models, api
-
-_logger = logging.getLogger(__name__)
-
-# Default business models, grouped by category.
-# Only included if the corresponding module is installed.
-_DEFAULT_BUSINESS_MODELS = {
- 'sale': ['sale.order', 'sale.order.line'],
- 'account': ['account.move', 'account.move.line', 'account.payment'],
- 'product': ['product.template', 'product.product', 'product.category'],
- 'base': ['res.partner'],
- 'stock': ['stock.picking', 'stock.move', 'stock.quant'],
- 'purchase': ['purchase.order', 'purchase.order.line'],
- 'crm': ['crm.lead'],
- 'project': ['project.project', 'project.task'],
- 'helpdesk': ['helpdesk.ticket'],
- 'hr': ['hr.employee', 'hr.leave'],
-}
-
-# Fields to always skip (technical/internal)
-_SKIP_FIELDS = {
- '__last_update', 'write_date', 'write_uid', 'create_date', 'create_uid',
- 'display_name', 'message_ids', 'message_follower_ids', 'message_partner_ids',
- 'message_channel_ids', 'message_attachment_count', 'message_has_error',
- 'message_has_error_counter', 'message_has_sms_error', 'message_is_follower',
- 'message_main_attachment_id', 'message_needaction', 'message_needaction_counter',
- 'message_unread', 'message_unread_counter', 'website_message_ids',
- 'activity_ids', 'activity_state', 'activity_user_id', 'activity_type_id',
- 'activity_date_deadline', 'activity_summary', 'activity_exception_decoration',
- 'activity_exception_icon', 'activity_type_icon', 'activity_calendar_event_id',
- 'rating_ids', 'rating_last_value', 'rating_last_feedback', 'rating_last_image',
- 'rating_count', 'rating_avg', 'rating_percentage_satisfaction',
- 'access_url', 'access_token', 'access_warning',
-}
-
-# Type abbreviations for compact format
-_TYPE_MAP = {
- 'char': 'char',
- 'text': 'text',
- 'html': 'html',
- 'integer': 'int',
- 'float': 'float',
- 'monetary': 'mon',
- 'boolean': 'bool',
- 'date': 'date',
- 'datetime': 'dt',
- 'binary': 'bin',
- 'selection': 'sel',
- 'many2one': 'm2o',
- 'one2many': 'o2m',
- 'many2many': 'm2m',
- 'reference': 'ref',
-}
-
-
-class SchemaBuilder(models.AbstractModel):
- _name = 'otk.schema.builder'
- _description = "O'Toolkit Schema Builder"
-
- @api.model
- def get_business_models(self):
- """Return list of business-relevant model names.
-
- Only includes models whose parent module is installed.
- Can be overridden via ir.config_parameter 'otoolkit.business_models'.
- """
- ICP = self.env['ir.config_parameter'].sudo()
- custom = ICP.get_param('otoolkit.business_models', '')
- if custom:
- return [m.strip() for m in custom.split(',') if m.strip()]
-
- result = []
- IrModule = self.env['ir.module.module'].sudo()
- for module_name, model_names in _DEFAULT_BUSINESS_MODELS.items():
- if module_name == 'base':
- result.extend(model_names)
- continue
- installed = IrModule.search([
- ('name', '=', module_name),
- ('state', '=', 'installed'),
- ], limit=1)
- if installed:
- # Verify model actually exists in registry
- for model_name in model_names:
- if model_name in self.env:
- result.append(model_name)
- return result
-
- @api.model
- def check_model_access(self, model_name):
- """Check if current user has read access to the given model."""
- try:
- self.env[model_name].check_access('read')
- return True
- except Exception:
- return False
-
- @api.model
- def build_model_schema(self, model_name, depth=1):
- """Build a schema dict for a model with field metadata.
-
- Args:
- model_name: Technical model name (e.g. 'sale.order')
- depth: How deep to follow relational fields (0 = no relations)
-
- Returns:
- dict with model info, fields list, and nested relation schemas
- """
- if model_name not in self.env:
- return None
-
- Model = self.env[model_name]
- model_desc = Model._description or model_name
-
- fields_info = Model.fields_get(attributes=[
- 'string', 'type', 'relation', 'selection', 'required',
- 'readonly', 'store',
- ])
-
- schema_fields = []
- related_schemas = {}
-
- for fname, finfo in sorted(fields_info.items()):
- if fname.startswith('_') or fname in _SKIP_FIELDS:
- continue
- if not finfo.get('store', True):
- continue
-
- field_data = {
- 'name': fname,
- 'type': finfo['type'],
- 'label': finfo.get('string', fname),
- }
-
- if finfo['type'] == 'selection' and finfo.get('selection'):
- field_data['selection'] = finfo['selection']
-
- if finfo['type'] in ('many2one', 'one2many', 'many2many') and finfo.get('relation'):
- field_data['relation'] = finfo['relation']
- if depth > 0 and finfo['relation'] not in related_schemas:
- related_schemas[finfo['relation']] = self.build_model_schema(
- finfo['relation'], depth=depth - 1
- )
-
- if finfo.get('required'):
- field_data['required'] = True
-
- schema_fields.append(field_data)
-
- return {
- 'model': model_name,
- 'description': model_desc,
- 'fields': schema_fields,
- 'related': related_schemas,
- }
-
- @api.model
- def compress_schema(self, schema):
- """Compress a schema dict into compact text format for API.
-
- Saves ~75% tokens vs JSON.
-
- Format:
- === sale.order (Sales Order) ===
- id:int name:char state:sel[draft,sent,sale] date_order:dt
- partner_id->res.partner amount_total:mon
- """
- if not schema:
- return ''
-
- lines = []
- lines.append(f"=== {schema['model']} ({schema['description']}) ===")
-
- field_parts = []
- for f in schema['fields']:
- ftype = _TYPE_MAP.get(f['type'], f['type'])
-
- if f['type'] == 'selection' and f.get('selection'):
- # Include labels for AI to understand meaning (key=Label)
- entries = [f"{s[0]}={s[1]}" for s in f['selection']]
- part = f"{f['name']}:sel[{','.join(entries)}]"
- elif f['type'] in ('many2one', 'one2many', 'many2many') and f.get('relation'):
- arrow = '->' if f['type'] == 'many2one' else ':o2m->' if f['type'] == 'one2many' else ':m2m->'
- if f['type'] == 'many2one':
- part = f"{f['name']}->{f['relation']}"
- else:
- part = f"{f['name']}:{ftype}->{f['relation']}"
- else:
- part = f"{f['name']}:{ftype}"
-
- field_parts.append(part)
-
- # Group field parts into lines of ~120 chars
- current_line = []
- current_len = 0
- for part in field_parts:
- if current_len + len(part) + 1 > 120 and current_line:
- lines.append(' '.join(current_line))
- current_line = []
- current_len = 0
- current_line.append(part)
- current_len += len(part) + 1
- if current_line:
- lines.append(' '.join(current_line))
-
- # Add related model schemas (depth-1 only, no nested relations)
- for rel_name, rel_schema in (schema.get('related') or {}).items():
- if rel_schema:
- lines.append('')
- lines.append(self.compress_schema(rel_schema))
-
- return '\n'.join(lines)
-
- @api.model
- def build_context_for_models(self, model_names=None, depth=1):
- """Build compressed schema context for a list of models.
-
- Args:
- model_names: List of model names. If None, uses get_business_models().
- depth: Relation traversal depth.
-
- Returns:
- Compressed schema string ready to send to API.
- """
- if model_names is None:
- model_names = self.get_business_models()
-
- parts = []
- seen = set()
- for model_name in model_names:
- if model_name in seen:
- continue
- seen.add(model_name)
- if not self.check_model_access(model_name):
- continue
- schema = self.build_model_schema(model_name, depth=depth)
- if schema:
- parts.append(self.compress_schema(schema))
-
- return '\n\n'.join(parts)
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/security/otoolkit_security.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/security/otoolkit_security.xml
deleted file mode 100644
index 0a2ac40..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/security/otoolkit_security.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- O'Toolkit
- 90
-
-
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/cover.jpeg b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/cover.jpeg
deleted file mode 100644
index 14f27b6..0000000
Binary files a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/cover.jpeg and /dev/null differ
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/index.html b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/index.html
deleted file mode 100644
index 17978ad..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
The Auto Translate Fields module enhances the translation process in Odoo by adding a convenient "Translate" button to the translation popup of any translatable field. When clicked, it automatically translates the field content into all configured languages in the system, using the current user's language as the source. This feature simplifies and accelerates the workflow for multilingual environments, ensuring that translations are consistent and up-to-date across the platform. Ideal for businesses that operate in multiple languages, this module improves efficiency by reducing manual translation efforts.
When you translate your fields, you'll find a new button called «Auto Translate». Click on it to translate your text into all the languages of your instance. The user's base language is used as the starting language.
-
-
-
-
-
-
-
-
- Also works with HTML fields
-
-
Automatic translation also works with HTML fields. This saves time by avoiding line-by-line translation.
-
-
-
-
-
-
-
-
-
Have any questions?
-
If you have any questions or need more information, feel free to visit our website or contact us directly.
-
-
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/json_pretty_field.js b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/json_pretty_field.js
deleted file mode 100644
index f715935..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/json_pretty_field.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/** @odoo-module **/
-
-import { standardFieldProps } from "@web/views/fields/standard_field_props";
-import { Component, xml } from "@odoo/owl";
-import { registry } from "@web/core/registry";
-
-export class JsonPrettyField extends Component {
- static template = xml`
-
-
-
- `;
- static props = standardFieldProps;
-
- get prettyJson() {
- try {
- const value = this.props.record.data[this.props.name];
- return JSON.stringify(value ?? {}, null, 4);
- } catch (e) {
- return "Invalid JSON";
- }
- }
-}
-
-registry.category("fields").add("json_pretty", { component: JsonPrettyField });
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/translation_dialog_auto_translate.js b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/translation_dialog_auto_translate.js
deleted file mode 100644
index d4c3302..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/js/translation_dialog_auto_translate.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/** @odoo-module **/
-
-import { TranslationDialog } from "@web/views/fields/translation_dialog";
-import { patch } from "@web/core/utils/patch";
-import { useService } from "@web/core/utils/hooks";
-import { _t } from "@web/core/l10n/translation";
-import { useState } from "@odoo/owl";
-
-patch(TranslationDialog.prototype, {
- setup() {
- super.setup(...arguments);
- this.orm = useService('orm');
- this.notification = useService("notification");
- this.action = useService("action");
- this.state = useState({ translating: false, translatingTermIds: {} });
- },
-
- /**
- * Find the best source term to translate from for a given target term.
- * Picks a term in a different language with the same source text.
- * Priority: any candidate with actual translated content > en_US > first
- * candidate. en_US is deprioritized because Odoo populates en_US from the
- * record's base value — which may itself be in another language (e.g. a
- * record edited primarily in French) and would mislabel the source to GPT.
- */
- _findSourceTerm(targetTerm) {
- const candidates = this.terms.filter(
- t => t.lang !== targetTerm.lang && t.source === targetTerm.source
- );
- if (candidates.length === 0) return null;
- return candidates.find(t => (this.updatedTerms[t.id] ?? t.value ?? "").trim())
- || candidates.find(t => t.lang === "en_US")
- || candidates[0];
- },
-
- /**
- * Handle translation error notifications.
- * Returns true if an error was displayed (caller should stop).
- */
- _handleTranslationNotification(result) {
- if (!result[0]) {
- if (result[2] === "credits") {
- this.notification.add(result[1], {
- type: "danger",
- buttons: [{
- onClick: () => window.open("https://osolutions.app/pricing"),
- primary: false,
- name: _t("Get tokens"),
- }],
- });
- } else if (result[2] === "settings") {
- this.notification.add(result[1], {
- type: "danger",
- buttons: [{
- onClick: () => this.action.doAction({
- type: "ir.actions.act_window",
- res_model: "res.config.settings",
- views: [[false, "form"]],
- target: "current",
- context: { module: "otoolkit_auth" },
- }),
- primary: false,
- name: _t("Open Settings"),
- }],
- });
- } else {
- this.notification.add(result[1], { type: "danger" });
- }
- return true;
- }
- return false;
- },
-
- /**
- * Apply translated terms to the dialog state.
- * Returns the count of terms updated.
- */
- _applyTranslationResults(translatedTerms) {
- let count = 0;
- for (const item of translatedTerms) {
- if (item.translation) {
- this.updatedTerms[item.id] = item.translation;
- const target = this.terms.find(t => t.id === item.id);
- if (target) {
- target.value = item.translation;
- count++;
- }
- }
- }
- return count;
- },
-
- /**
- * Whether any translation (bulk or single-term) is currently running.
- */
- get anyTranslating() {
- if (this.state.translating) return true;
- for (const id in this.state.translatingTermIds) {
- if (this.state.translatingTermIds[id]) return true;
- }
- return false;
- },
-
- /**
- * Bulk auto-translate all empty terms.
- */
- async autoTranslate() {
- this.state.translating = true;
- try {
- const result = await this._translateText(this.terms, this.updatedTerms, null, null);
- if (this._handleTranslationNotification(result)) return;
-
- if (result[1].length === 0) {
- return this.notification.add(
- _t("All translations are already filled."), { type: "info" }
- );
- }
-
- const count = this._applyTranslationResults(result[1]);
- this.render();
- if (count > 0) {
- this.notification.add(_t("Successfully translated"), { type: "success" });
- }
- } finally {
- this.state.translating = false;
- }
- },
-
- /**
- * Translate a single empty term.
- */
- async translateSingleTerm(targetTerm) {
- const sourceTerm = this._findSourceTerm(targetTerm);
- if (!sourceTerm) {
- return this.notification.add(
- _t("No other language available to translate from."), { type: "warning" }
- );
- }
-
- this.state.translatingTermIds[targetTerm.id] = true;
- try {
- const result = await this._translateText(
- [sourceTerm, targetTerm], this.updatedTerms,
- sourceTerm.lang, targetTerm.lang,
- );
- if (this._handleTranslationNotification(result)) return;
-
- if (result[1].length === 0) {
- return this.notification.add(
- _t("No translation returned for this term."), { type: "warning" }
- );
- }
-
- // Apply only the target term's translation. The API also returns
- // an "echo" entry for the source-language term (its `translation`
- // is the source text itself) — applying it would overwrite the
- // source row's displayed value, which is wrong when the source
- // peer is an empty row whose displayed `value` is empty (HTML
- // showSource case).
- const targetOnly = result[1].filter(item => item.id === targetTerm.id);
- const count = this._applyTranslationResults(targetOnly);
- this.render();
- if (count > 0) {
- this.notification.add(_t("Successfully translated"), { type: "success" });
- } else {
- this.notification.add(
- _t("No translation returned for this term."), { type: "warning" }
- );
- }
- } finally {
- delete this.state.translatingTermIds[targetTerm.id];
- }
- },
-
- async _translateText(terms, updated_terms, source_lang_hint = null, target_lang_hint = null) {
- return await this.orm.call(
- "translation.dialog", "translate_text",
- [terms, updated_terms, source_lang_hint, target_lang_hint],
- );
- },
-
- async onSave() {
- const translations = {};
-
- this.terms.forEach((term) => {
- const updatedTermValue = this.updatedTerms[term.id];
-
- if (term.id in this.updatedTerms && updatedTermValue !== term.originalValue) {
- if (this.props.showSource) {
- if (!translations[term.lang]) {
- translations[term.lang] = {};
- }
- const oldTermValue = term.originalValue ? term.originalValue : term.source;
- translations[term.lang][oldTermValue] = updatedTermValue || term.source;
- } else {
- translations[term.lang] = updatedTermValue || false;
- }
- }
- });
-
- await this.orm.call(this.props.resModel, "update_field_translations", [
- [this.props.resId],
- this.props.fieldName,
- translations,
- ]);
-
- await this.props.onSave();
- this.props.close();
- },
-});
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/xml/translation_dialog_auto_translate.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/xml/translation_dialog_auto_translate.xml
deleted file mode 100644
index 7fdabff..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/static/src/xml/translation_dialog_auto_translate.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_config_views.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_config_views.xml
deleted file mode 100644
index 59bbc61..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_config_views.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
- otk.translation.config.list
- otk.translation.config
-
-
-
-
-
-
-
-
-
-
-
- otk.translation.config.form
- otk.translation.config
-
-
-
-
-
-
- otk.translation.config.search
- otk.translation.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Translation Configuration
- otk.translation.config
- list,form
- {'search_default_active': 1}
-
-
- Configure models for bulk translation
-
-
- Add models here to enable the "Bulk translate" action on their list views.
- No code changes required - just select a model and it will automatically
- get the bulk translation feature.
-
-
-
-
-
-
- Enable All Translatable Models
-
- code
- action = model.action_enable_all_translatable_models()
-
-
-
-
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_views.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_views.xml
deleted file mode 100644
index d4df06d..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/views/translation_views.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
-
- otk.translation.action.list
- otk.translation.action
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- otk.translation.action.form
- otk.translation.action
-
-
-
-
-
-
- otk.translation.list
- otk.translation
-
-
-
-
-
-
-
-
-
-
-
-
-
- otk.translation.form
- otk.translation
-
-
-
-
-
-
- Translation actions
- otk.translation
- list,form
-
-
-
- Translation actions
- otk.translation.action
- list,form
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/__init__.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/__init__.py
deleted file mode 100644
index c408d2a..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import bulk_translate
\ No newline at end of file
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.py b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.py
deleted file mode 100644
index 0c000f9..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.py
+++ /dev/null
@@ -1,138 +0,0 @@
-from odoo import fields, models, api, _
-from odoo.exceptions import UserError
-
-from ..models.translation import _is_valid_translatable_value
-
-
-class BulkTranslate(models.TransientModel):
- _name = 'otk.translation.bulk.translate'
- _description = "Bulk translate Wizard"
-
- model_id = fields.Many2one('ir.model', string="Model", ondelete='cascade')
- base_language_id = fields.Many2one('res.lang', string="Base language", required=True, ondelete='cascade')
- target_language_ids = fields.Many2many('res.lang', string="Target languages", required=True, ondelete='cascade')
- field_ids = fields.Many2many(
- 'ir.model.fields',
- string="Fields",
- domain="[('translate', 'in', ['standard', 'html_translate', 'xml_translate']), ('model_id', '=', model_id), ('related', '=', False), ('store', '=', True)]",
- required=True
- )
- overwrite_existing = fields.Boolean(
- string="Overwrite existing translations",
- default=False,
- help="Re-translate every term, including terms that already have a "
- "translation in the target languages.",
- )
-
- @api.depends('model_id')
- def _compute_model_name(self):
- for record in self:
- record.model_name = record.model_id.model
-
- @api.model
- def default_get(self, fields_list):
- defaults = super().default_get(fields_list)
- active_model = self.env.context.get('active_model')
- if active_model:
- model = self.env['ir.model'].search([('model', '=', active_model)], limit=1)
- defaults['model_id'] = model.id
- defaults['base_language_id'] = self.env['res.lang'].search([('code', '=', self.env.user.lang)], limit=1)
- defaults['target_language_ids'] = self.env['res.lang'].search([('code', '!=', self.env.user.lang)])
- return defaults
-
- def _resolve_field_value(self, model_name, record_id, field_name, base_lang_code):
- """Resolve a translatable field value with language fallback.
-
- Tries base_lang first, then en_US. Handles html_translate fields that
- may return False for a specific lang context.
- """
- candidates = [base_lang_code]
- if base_lang_code != 'en_US':
- candidates.append('en_US')
-
- for try_lang in candidates:
- record = self.env[model_name].with_context(lang=try_lang).browse(record_id)
- if not record.exists():
- return False
- value = getattr(record, field_name, False)
- if _is_valid_translatable_value(value):
- return value
- return False
-
- def _pre_filter_records(self, active_ids):
- """Pre-filter records to separate translatable from empty ones.
-
- Uses language fallback (base_lang → en_US) to handle html_translate
- fields that may not resolve for a specific lang context.
-
- Returns:
- tuple: (translatable_ids, skipped_ids)
- """
- model_name = self.model_id.model
- base_lang_code = self.base_language_id.code
-
- translatable_ids = []
- skipped_ids = []
-
- for record_id in active_ids:
- has_content = False
- for field in self.field_ids:
- value = self._resolve_field_value(
- model_name, record_id, field.name, base_lang_code
- )
- if _is_valid_translatable_value(value):
- has_content = True
- break
- if has_content:
- translatable_ids.append(record_id)
- else:
- skipped_ids.append(record_id)
-
- return translatable_ids, skipped_ids
-
- def action_translate(self):
- active_ids = self.env.context.get('active_ids', [])
-
- if not active_ids:
- raise UserError(_("No records selected for translation."))
-
- # Pre-filter: separate records with content from empty ones
- translatable_ids, skipped_ids = self._pre_filter_records(active_ids)
-
- if not translatable_ids:
- raise UserError(_(
- "None of the %d selected records have translatable content "
- "in the selected fields (%s).\n\n"
- "Please check that the records have content in the base language (%s)."
- ) % (
- len(active_ids),
- ', '.join(self.field_ids.mapped('field_description')),
- self.base_language_id.name,
- ))
-
- self.env['otk.translation.action'].sudo().create({
- 'model_id': self.model_id.id,
- 'base_language_id': self.base_language_id.id,
- 'target_language_ids': self.target_language_ids.ids,
- 'field_ids': self.field_ids.ids,
- 'overwrite_existing': self.overwrite_existing,
- 'pending_record_ids': translatable_ids,
- 'skipped_record_ids': skipped_ids,
- 'translation_count': len(translatable_ids),
- })
-
- # Show summary notification if some records were skipped
- if skipped_ids:
- return {
- 'type': 'ir.actions.client',
- 'tag': 'display_notification',
- 'params': {
- 'title': _("Translation Started"),
- 'message': _(
- "%d records queued for translation.\n"
- "%d records skipped (no translatable content in selected fields)."
- ) % (len(translatable_ids), len(skipped_ids)),
- 'type': 'warning',
- 'sticky': True,
- }
- }
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.xml b/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.xml
deleted file mode 100644
index 1a15ccb..0000000
--- a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auto_translate_fields/wizards/bulk_translate.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
- translation.bulk.translate.wizard.form
- otk.translation.bulk.translate
-
-
-
-
-
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/icon.png b/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/icon.png
deleted file mode 100644
index 4008409..0000000
Binary files a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/icon.png and /dev/null differ
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/__init__.py b/otoolkit_seo_content/__init__.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/__init__.py
rename to otoolkit_seo_content/__init__.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/__manifest__.py b/otoolkit_seo_content/__manifest__.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/__manifest__.py
rename to otoolkit_seo_content/__manifest__.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/controllers/__init__.py b/otoolkit_seo_content/controllers/__init__.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/controllers/__init__.py
rename to otoolkit_seo_content/controllers/__init__.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/controllers/seo_content.py b/otoolkit_seo_content/controllers/seo_content.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/controllers/seo_content.py
rename to otoolkit_seo_content/controllers/seo_content.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/brand_voices.xml b/otoolkit_seo_content/data/brand_voices.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/brand_voices.xml
rename to otoolkit_seo_content/data/brand_voices.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/ir_cron.xml b/otoolkit_seo_content/data/ir_cron.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/ir_cron.xml
rename to otoolkit_seo_content/data/ir_cron.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/ir_module_category.xml b/otoolkit_seo_content/data/ir_module_category.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/ir_module_category.xml
rename to otoolkit_seo_content/data/ir_module_category.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/seo_templates.xml b/otoolkit_seo_content/data/seo_templates.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/seo_templates.xml
rename to otoolkit_seo_content/data/seo_templates.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/translation_configs.xml b/otoolkit_seo_content/data/translation_configs.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/data/translation_configs.xml
rename to otoolkit_seo_content/data/translation_configs.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/de.po b/otoolkit_seo_content/i18n/de.po
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/de.po
rename to otoolkit_seo_content/i18n/de.po
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/es.po b/otoolkit_seo_content/i18n/es.po
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/es.po
rename to otoolkit_seo_content/i18n/es.po
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/fr_BE.po b/otoolkit_seo_content/i18n/fr_BE.po
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/fr_BE.po
rename to otoolkit_seo_content/i18n/fr_BE.po
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/nl_BE.po b/otoolkit_seo_content/i18n/nl_BE.po
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/i18n/nl_BE.po
rename to otoolkit_seo_content/i18n/nl_BE.po
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/__init__.py b/otoolkit_seo_content/models/__init__.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/__init__.py
rename to otoolkit_seo_content/models/__init__.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/brand_voice.py b/otoolkit_seo_content/models/brand_voice.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/brand_voice.py
rename to otoolkit_seo_content/models/brand_voice.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/res_config_settings.py b/otoolkit_seo_content/models/res_config_settings.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/res_config_settings.py
rename to otoolkit_seo_content/models/res_config_settings.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content.py b/otoolkit_seo_content/models/seo_content.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content.py
rename to otoolkit_seo_content/models/seo_content.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_batch.py b/otoolkit_seo_content/models/seo_content_batch.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_batch.py
rename to otoolkit_seo_content/models/seo_content_batch.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_idea.py b/otoolkit_seo_content/models/seo_content_idea.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_idea.py
rename to otoolkit_seo_content/models/seo_content_idea.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_image.py b/otoolkit_seo_content/models/seo_content_image.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_content_image.py
rename to otoolkit_seo_content/models/seo_content_image.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_reference.py b/otoolkit_seo_content/models/seo_reference.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_reference.py
rename to otoolkit_seo_content/models/seo_reference.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_template.py b/otoolkit_seo_content/models/seo_template.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/models/seo_template.py
rename to otoolkit_seo_content/models/seo_template.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/security/ir.model.access.csv b/otoolkit_seo_content/security/ir.model.access.csv
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/security/ir.model.access.csv
rename to otoolkit_seo_content/security/ir.model.access.csv
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/security/seo_security.xml b/otoolkit_seo_content/security/seo_security.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/security/seo_security.xml
rename to otoolkit_seo_content/security/seo_security.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/batch-processing.gif b/otoolkit_seo_content/static/description/assets/batch-processing.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/batch-processing.gif
rename to otoolkit_seo_content/static/description/assets/batch-processing.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/batch-processing2.gif b/otoolkit_seo_content/static/description/assets/batch-processing2.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/batch-processing2.gif
rename to otoolkit_seo_content/static/description/assets/batch-processing2.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/blog-integration.gif b/otoolkit_seo_content/static/description/assets/blog-integration.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/blog-integration.gif
rename to otoolkit_seo_content/static/description/assets/blog-integration.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/generate-wizard.webp b/otoolkit_seo_content/static/description/assets/generate-wizard.webp
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/generate-wizard.webp
rename to otoolkit_seo_content/static/description/assets/generate-wizard.webp
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/ideas-queue.webp b/otoolkit_seo_content/static/description/assets/ideas-queue.webp
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/ideas-queue.webp
rename to otoolkit_seo_content/static/description/assets/ideas-queue.webp
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/image-generation.gif b/otoolkit_seo_content/static/description/assets/image-generation.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/image-generation.gif
rename to otoolkit_seo_content/static/description/assets/image-generation.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/image-styles.gif b/otoolkit_seo_content/static/description/assets/image-styles.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/image-styles.gif
rename to otoolkit_seo_content/static/description/assets/image-styles.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/multi-language.webp b/otoolkit_seo_content/static/description/assets/multi-language.webp
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/multi-language.webp
rename to otoolkit_seo_content/static/description/assets/multi-language.webp
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/references.gif b/otoolkit_seo_content/static/description/assets/references.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/references.gif
rename to otoolkit_seo_content/static/description/assets/references.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/seo-analysis.webp b/otoolkit_seo_content/static/description/assets/seo-analysis.webp
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/seo-analysis.webp
rename to otoolkit_seo_content/static/description/assets/seo-analysis.webp
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/templates.gif b/otoolkit_seo_content/static/description/assets/templates.gif
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/assets/templates.gif
rename to otoolkit_seo_content/static/description/assets/templates.gif
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/cover.png b/otoolkit_seo_content/static/description/cover.png
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/cover.png
rename to otoolkit_seo_content/static/description/cover.png
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/cover.svg b/otoolkit_seo_content/static/description/cover.svg
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/cover.svg
rename to otoolkit_seo_content/static/description/cover.svg
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/icon.png b/otoolkit_seo_content/static/description/icon.png
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_auth/static/description/icon.png
rename to otoolkit_seo_content/static/description/icon.png
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/icon.svg b/otoolkit_seo_content/static/description/icon.svg
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/icon.svg
rename to otoolkit_seo_content/static/description/icon.svg
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/index.html b/otoolkit_seo_content/static/description/index.html
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/description/index.html
rename to otoolkit_seo_content/static/description/index.html
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/css/seo_content.css b/otoolkit_seo_content/static/src/css/seo_content.css
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/css/seo_content.css
rename to otoolkit_seo_content/static/src/css/seo_content.css
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/js/seo_dashboard.js b/otoolkit_seo_content/static/src/js/seo_dashboard.js
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/js/seo_dashboard.js
rename to otoolkit_seo_content/static/src/js/seo_dashboard.js
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/xml/seo_dashboard.xml b/otoolkit_seo_content/static/src/xml/seo_dashboard.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/static/src/xml/seo_dashboard.xml
rename to otoolkit_seo_content/static/src/xml/seo_dashboard.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/brand_voice_views.xml b/otoolkit_seo_content/views/brand_voice_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/brand_voice_views.xml
rename to otoolkit_seo_content/views/brand_voice_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/menu_views.xml b/otoolkit_seo_content/views/menu_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/menu_views.xml
rename to otoolkit_seo_content/views/menu_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/res_config_settings_views.xml b/otoolkit_seo_content/views/res_config_settings_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/res_config_settings_views.xml
rename to otoolkit_seo_content/views/res_config_settings_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_batch_views.xml b/otoolkit_seo_content/views/seo_content_batch_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_batch_views.xml
rename to otoolkit_seo_content/views/seo_content_batch_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_idea_views.xml b/otoolkit_seo_content/views/seo_content_idea_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_idea_views.xml
rename to otoolkit_seo_content/views/seo_content_idea_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_image_views.xml b/otoolkit_seo_content/views/seo_content_image_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_image_views.xml
rename to otoolkit_seo_content/views/seo_content_image_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_views.xml b/otoolkit_seo_content/views/seo_content_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_content_views.xml
rename to otoolkit_seo_content/views/seo_content_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_dashboard_views.xml b/otoolkit_seo_content/views/seo_dashboard_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_dashboard_views.xml
rename to otoolkit_seo_content/views/seo_dashboard_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_reference_views.xml b/otoolkit_seo_content/views/seo_reference_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_reference_views.xml
rename to otoolkit_seo_content/views/seo_reference_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_template_views.xml b/otoolkit_seo_content/views/seo_template_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/views/seo_template_views.xml
rename to otoolkit_seo_content/views/seo_template_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/__init__.py b/otoolkit_seo_content/wizards/__init__.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/__init__.py
rename to otoolkit_seo_content/wizards/__init__.py
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/generate_content_views.xml b/otoolkit_seo_content/wizards/generate_content_views.xml
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/generate_content_views.xml
rename to otoolkit_seo_content/wizards/generate_content_views.xml
diff --git a/otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/generate_content_wizard.py b/otoolkit_seo_content/wizards/generate_content_wizard.py
similarity index 100%
rename from otoolkit_seo_content-19.0.1.0.1/otoolkit_seo_content/wizards/generate_content_wizard.py
rename to otoolkit_seo_content/wizards/generate_content_wizard.py