From 75c390d1a4f708d0f846e43b360f817f4528e5f2 Mon Sep 17 00:00:00 2001 From: cerenX9 Date: Mon, 27 Jul 2026 12:46:58 +0300 Subject: [PATCH] feat: Initialize project and Phase 1 MyMach Social Next-Gen module structure --- .gitignore | 12 ++++++ Dockerfile | 12 ++++++ config/odoo.conf | 12 ++++++ docker-compose.yml | 35 ++++++++++++++++ .../mymach_social_nextgen/__init__.py | 1 + .../mymach_social_nextgen/__manifest__.py | 33 +++++++++++++++ .../mymach_social_nextgen/models/__init__.py | 4 ++ .../models/social_account.py | 31 ++++++++++++++ .../models/social_competitor.py | 26 ++++++++++++ .../models/social_media.py | 27 ++++++++++++ .../models/social_post.py | 42 +++++++++++++++++++ .../security/ir.model.access.csv | 9 ++++ requirements.txt | 13 ++++++ 13 files changed, 257 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 config/odoo.conf create mode 100644 docker-compose.yml create mode 100644 extra-addons/mymach_social_nextgen/__init__.py create mode 100644 extra-addons/mymach_social_nextgen/__manifest__.py create mode 100644 extra-addons/mymach_social_nextgen/models/__init__.py create mode 100644 extra-addons/mymach_social_nextgen/models/social_account.py create mode 100644 extra-addons/mymach_social_nextgen/models/social_competitor.py create mode 100644 extra-addons/mymach_social_nextgen/models/social_media.py create mode 100644 extra-addons/mymach_social_nextgen/models/social_post.py create mode 100644 extra-addons/mymach_social_nextgen/security/ir.model.access.csv create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b492b14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +venv/ +.venv/ +env/ +.env + +# Docker / Veritabanı Volume verileri (Sadece klasör açılmışsa) +odoo-web-data/ +odoo-db-data/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ab15a7a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM odoo:19.0 + +USER root + +# Gereksinimleri Odoo container'ı içine kopyala +COPY requirements.txt /etc/odoo/ + +# Gerekli Python paketlerini kur +RUN pip3 install --no-cache-dir -r /etc/odoo/requirements.txt + +# Odoo kullanıcısına geri dön +USER odoo diff --git a/config/odoo.conf b/config/odoo.conf new file mode 100644 index 0000000..828b218 --- /dev/null +++ b/config/odoo.conf @@ -0,0 +1,12 @@ +[options] +addons_path = /mnt/extra-addons +data_dir = /var/lib/odoo +admin_passwd = mymach_master_admin_password_123 +db_host = db +db_port = 5432 +db_user = odoo +db_password = odoo_secret_db_pass +# Geliştirme modunu ve log seviyesini açıyoruz +log_level = info +limit_time_cpu = 600 +limit_time_real = 1200 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0b61242 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +version: '3.8' + +services: + web: + build: . + container_name: mymach_odoo19 + depends_on: + - db + ports: + - "8069:8069" # Odoo Web Arayüzü (http://localhost:8069) + - "8072:8072" # Longpolling / Websocket Portu (Canlı sohbet/bildirimler) + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./extra-addons:/mnt/extra-addons + environment: + - HOST=db + - USER=odoo + - PASSWORD=odoo_secret_db_pass + restart: always + + db: + image: postgres:16 + container_name: mymach_postgres16 + environment: + - POSTGRES_DB=postgres + - POSTGRES_USER=odoo + - POSTGRES_PASSWORD=odoo_secret_db_pass + volumes: + - odoo-db-data:/var/lib/postgresql/data + restart: always + +volumes: + odoo-web-data: + odoo-db-data: diff --git a/extra-addons/mymach_social_nextgen/__init__.py b/extra-addons/mymach_social_nextgen/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/extra-addons/mymach_social_nextgen/__manifest__.py b/extra-addons/mymach_social_nextgen/__manifest__.py new file mode 100644 index 0000000..501f246 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/__manifest__.py @@ -0,0 +1,33 @@ +{ + 'name': 'MyMach Next-Gen Social Engine', + 'version': '1.0.0', + 'category': 'Marketing', + 'summary': 'Advanced Social Media Management, AI Assistant, and CRM Integration', + 'description': """ +MyMach Next-Gen Social Engine +============================== +A complete social media automation tool that does not require Enterprise licenses. + +Features: +- Multi-Platform API & OAuth2 Connection (Meta, LinkedIn, X, YouTube) +- Drag-and-Drop Scheduler & Calendar +- AI-Based Text and Trend Hashtag Assistant +- Dynamic Templates & Auto Watermarking +- Vertical Video Render Engine +- Otonom Trend Analytics +- Competitor Social Media Tracking +- Social Listening & CRM Lead Generation +- Approval Workflow +- n8n Webhook & External Service Triggering + """, + 'author': 'MyMach', + 'website': 'https://www.mymach.com', + 'depends': ['base', 'web', 'crm', 'mail'], + 'data': [ + 'security/ir.model.access.csv', + ], + 'installable': True, + 'application': True, + 'auto_install': False, + 'license': 'LGPL-3', +} diff --git a/extra-addons/mymach_social_nextgen/models/__init__.py b/extra-addons/mymach_social_nextgen/models/__init__.py new file mode 100644 index 0000000..11c61b8 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/models/__init__.py @@ -0,0 +1,4 @@ +from . import social_account +from . import social_post +from . import social_media +from . import social_competitor diff --git a/extra-addons/mymach_social_nextgen/models/social_account.py b/extra-addons/mymach_social_nextgen/models/social_account.py new file mode 100644 index 0000000..f2e6c5a --- /dev/null +++ b/extra-addons/mymach_social_nextgen/models/social_account.py @@ -0,0 +1,31 @@ +from odoo import models, fields, api + +class SocialAccount(models.Model): + _name = 'social.account' + _description = 'Social Media Account' + + name = fields.Char(string='Account Name', required=True) + platform = fields.Selection([ + ('facebook', 'Facebook'), + ('instagram', 'Instagram'), + ('linkedin', 'LinkedIn'), + ('x', 'X (Twitter)'), + ('youtube', 'YouTube') + ], string='Platform', required=True) + + active = fields.Boolean(default=True) + access_token = fields.Char(string='Access Token', groups="base.group_system") + refresh_token = fields.Char(string='Refresh Token', groups="base.group_system") + token_expiration = fields.Datetime(string='Token Expiration Date') + + # Optional fields for user info + platform_account_id = fields.Char(string='Platform Account ID') + profile_image_url = fields.Char(string='Profile Image URL') + + def action_authenticate(self): + # Placeholder for OAuth2 authentication flow + pass + + def action_refresh_token(self): + # Placeholder for refreshing the OAuth2 token + pass diff --git a/extra-addons/mymach_social_nextgen/models/social_competitor.py b/extra-addons/mymach_social_nextgen/models/social_competitor.py new file mode 100644 index 0000000..ebc7761 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/models/social_competitor.py @@ -0,0 +1,26 @@ +from odoo import models, fields, api + +class SocialCompetitor(models.Model): + _name = 'social.competitor' + _description = 'Social Media Competitor Analysis' + + name = fields.Char(string='Competitor Name', required=True) + platform = fields.Selection([ + ('facebook', 'Facebook'), + ('instagram', 'Instagram'), + ('linkedin', 'LinkedIn'), + ('x', 'X (Twitter)'), + ('youtube', 'YouTube') + ], string='Platform', required=True) + + profile_url = fields.Char(string='Profile URL', required=True) + followers_count = fields.Integer(string='Followers Count', readonly=True) + engagement_rate = fields.Float(string='Engagement Rate (%)', readonly=True) + + last_scraped = fields.Datetime(string='Last Scraped Date', readonly=True) + + notes = fields.Text(string='Analysis Notes') + + def action_scrape_data(self): + # Placeholder for BeautifulSoup / Scrapy scraping logic + pass diff --git a/extra-addons/mymach_social_nextgen/models/social_media.py b/extra-addons/mymach_social_nextgen/models/social_media.py new file mode 100644 index 0000000..0d8774d --- /dev/null +++ b/extra-addons/mymach_social_nextgen/models/social_media.py @@ -0,0 +1,27 @@ +from odoo import models, fields, api + +class SocialMedia(models.Model): + _name = 'social.media' + _description = 'Social Media Library' + + name = fields.Char(string='File Name', required=True) + media_type = fields.Selection([ + ('image', 'Image'), + ('video', 'Video'), + ('template', 'Dynamic Template') + ], string='Media Type', required=True) + + file_data = fields.Binary(string='File', required=True) + mimetype = fields.Char(string='Mime Type') + + # AI/Dynamic generation specific fields + is_ai_generated = fields.Boolean(string='AI Generated', default=False) + template_id = fields.Many2one('social.media', string='Source Template', domain=[('media_type', '=', 'template')]) + + def action_generate_watermark(self): + # Placeholder for PIL watermark logic + pass + + def action_generate_video(self): + # Placeholder for MoviePy video generation + pass diff --git a/extra-addons/mymach_social_nextgen/models/social_post.py b/extra-addons/mymach_social_nextgen/models/social_post.py new file mode 100644 index 0000000..e61f7b6 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/models/social_post.py @@ -0,0 +1,42 @@ +from odoo import models, fields, api + +class SocialPost(models.Model): + _name = 'social.post' + _description = 'Social Media Post' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='Post Title', required=True, tracking=True) + content = fields.Text(string='Content', tracking=True) + + state = fields.Selection([ + ('draft', 'Draft'), + ('approval', 'Waiting for Approval'), + ('scheduled', 'Scheduled'), + ('published', 'Published'), + ('failed', 'Failed') + ], string='Status', default='draft', tracking=True) + + scheduled_date = fields.Datetime(string='Scheduled Date', tracking=True) + published_date = fields.Datetime(string='Published Date', readonly=True) + + account_ids = fields.Many2many('social.account', string='Social Accounts', required=True) + media_ids = fields.Many2many('social.media', string='Media Files') + + error_message = fields.Text(string='Error Message', readonly=True) + + def action_submit_for_approval(self): + for record in self: + record.state = 'approval' + + def action_approve(self): + for record in self: + if record.scheduled_date: + record.state = 'scheduled' + else: + record.action_publish() + + def action_publish(self): + for record in self: + # Placeholder for publishing logic + record.state = 'published' + record.published_date = fields.Datetime.now() diff --git a/extra-addons/mymach_social_nextgen/security/ir.model.access.csv b/extra-addons/mymach_social_nextgen/security/ir.model.access.csv new file mode 100644 index 0000000..6fdb3c1 --- /dev/null +++ b/extra-addons/mymach_social_nextgen/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_social_account_user,social.account.user,model_social_account,base.group_user,1,1,1,0 +access_social_account_manager,social.account.manager,model_social_account,base.group_system,1,1,1,1 +access_social_post_user,social.post.user,model_social_post,base.group_user,1,1,1,0 +access_social_post_manager,social.post.manager,model_social_post,base.group_system,1,1,1,1 +access_social_media_user,social.media.user,model_social_media,base.group_user,1,1,1,0 +access_social_media_manager,social.media.manager,model_social_media,base.group_system,1,1,1,1 +access_social_competitor_user,social.competitor.user,model_social_competitor,base.group_user,1,1,1,0 +access_social_competitor_manager,social.competitor.manager,model_social_competitor,base.group_system,1,1,1,1 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7c8a4e9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,13 @@ +# Aşama 2: API & OAuth +httpx +requests + +# Aşama 4: AI & Medya İşleme +openai +anthropic +Pillow +moviepy + +# Aşama 5: Scraping & Trend +beautifulsoup4 +scrapy