diff --git a/bemade_odoo_partner_scrapper/__init__.py b/bemade_odoo_partner_scrapper/__init__.py
new file mode 100644
index 0000000..5305644
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import models
\ No newline at end of file
diff --git a/bemade_odoo_partner_scrapper/__manifest__.py b/bemade_odoo_partner_scrapper/__manifest__.py
new file mode 100644
index 0000000..39d426f
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/__manifest__.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+{
+ 'name': 'Bemade Odoo Partner Scrapper',
+ 'version': '1.0.0',
+ 'category': 'Administration',
+ 'summary': 'Module for scraping partners from odoo.com.',
+ 'description': """
+ This module enables the scraping of partners from odoo.com. It allows for the collection and management of partner contact information.
+
+ Main Features:
+ * Automatically scrape partners from odoo.com.
+ * Extracts partner name, website, and contact information.
+ * Manage contact information of partners.
+ """,
+ 'sequence': 10,
+ 'license': 'GPL-3',
+ 'author': 'Bemade',
+ 'website': 'https://www.bemade.org',
+ 'depends': [],
+ 'data': [
+ # No security
+ 'views/res_partner_views.xml',
+ ],
+ "assets": {
+ "web.assets_backend": [
+ "bemade_odoo_partner_scrapper/static/src/js/odoo_scrapper.js",
+ ],
+ "web.assets_qweb": [
+ "bemade_odoo_partner_scrapper/static/src/xml/odoo_scrapper_templates.xml",
+ ],
+ },
+ 'demo': [],
+ 'installable': True,
+ 'application': False,
+ 'auto_install': False
+}
diff --git a/bemade_odoo_partner_scrapper/models/__init__.py b/bemade_odoo_partner_scrapper/models/__init__.py
new file mode 100644
index 0000000..cd5f4d8
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/models/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import res_partner
\ No newline at end of file
diff --git a/bemade_odoo_partner_scrapper/models/res_partner.py b/bemade_odoo_partner_scrapper/models/res_partner.py
new file mode 100644
index 0000000..c341589
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/models/res_partner.py
@@ -0,0 +1,86 @@
+from odoo import models, fields, api, _
+import requests
+from bs4 import BeautifulSoup
+
+
+class ResPartner(models.Model):
+ _inherit = 'res.partner'
+
+ is_odoo_partner = fields.Boolean(string="Is Odoo Partner", default=False)
+ is_odoo_user = fields.Boolean(string="Is Odoo User", default=False)
+
+ @api.model
+ def get_odoo_partner(self):
+ # Load the webpage at the given url
+ page = requests.get("https://www.odoo.com/fr_FR/partners/country/canada-36")
+ # Parse the HTML content
+ soup = BeautifulSoup(page.content, 'html.parser')
+ div = soup.find(id="ref_content")
+ partners_url = set()
+ other_pages = set()
+
+ for link in div.find_all('a'):
+ href = link.get('href')
+ if href is not None:
+ # Ignore any URL containing 'country/canada-36'
+ if '/page/' in href:
+ # Add to set. Duplicates will be ignored automatically.
+ other_pages.add(href)
+
+ for link in div.find_all('a'):
+ href = link.get('href')
+ if href is not None and href != '':
+ # Ignore any URL containing 'country/canada-36'
+ if 'country/canada-36' not in href:
+ # Add to set. Duplicates will be ignored automatically.
+ partners_url.add(href.split('#', 1)[0].split('?', 1)[0])
+
+ for other_page in other_pages:
+ page = requests.get("https://www.odoo.com" + other_page)
+ soup = BeautifulSoup(page.content, 'html.parser')
+ div = soup.find(id="ref_content")
+ for link in div.find_all('a'):
+ href = link.get('href')
+ if href is not None and href != '':
+ # Ignore any URL containing 'country/canada-36'
+ if 'country/canada-36' not in href:
+ # Add to set. Duplicates will be ignored automatically.
+ partners_url.add(href.split('#', 1)[0].split('?', 1)[0])
+
+ for partner_url in partners_url:
+ page = requests.get("https://www.odoo.com" + partner_url)
+ soup = BeautifulSoup(page.content, 'html.parser')
+ partner_name = soup.find(id="partner_name")
+ address_div = soup.find('span', itemprop='streetAddress')
+ email_div = soup.find('span', itemprop='email')
+ phone_div = soup.find('span', itemprop='telephone')
+ website_div = soup.find('span', itemprop='website')
+ if address_div is not None:
+ # Extract address components
+ address_parts = address_div.get_text(separator="\n").split("\n")
+ street_address = address_parts[0]
+ city_state_postal = address_parts[len(address_parts)-2].split(', ')
+ city = city_state_postal[0]
+ state_postal = city_state_postal[1].split(' ')
+ state = state_postal[0]
+ postal_code = state_postal[1] + state_postal[2]
+ country = address_parts[len(address_parts)-1]
+ if email_div and email_div.string:
+ email = email_div.string
+ if phone_div and phone_div.string:
+ phone = phone_div.string
+ if website_div and website_div.string:
+ website = website_div.string
+
+ # self.env['res.partner'].create({
+ # 'name': partner_name,
+ # 'street': street_address,
+ # 'city': city,
+ # 'state_id': state,
+ # 'zip': postal_code,
+ # 'country_id': country,
+ # 'email': email,
+ # 'phone': phone,
+ # 'website': website,
+ # 'is_odoo_partner': True,
+ # })
\ No newline at end of file
diff --git a/bemade_odoo_partner_scrapper/static/src/js/odoo_scrapper.js b/bemade_odoo_partner_scrapper/static/src/js/odoo_scrapper.js
new file mode 100644
index 0000000..6f7f7c0
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/static/src/js/odoo_scrapper.js
@@ -0,0 +1,34 @@
+/** @odoo-module **/
+
+import ListController from 'web.ListController';
+import ListView from 'web.ListView';
+const viewRegistry = require('web.view_registry');
+
+const OdooScrapperListController = ListController.extend({
+ // buttons_template must match the t-name on the template for the button (static xml)
+ buttons_template: 'odoo_scrapper.list_view_buttons',
+ events: _.extend({}, ListController.prototype.events, {
+ 'click .o_button_get_partner': '_onGetPartnerClick',
+ }),
+ // This may need to be async function() if there needs to be an await this._rpc({ ... }); call to not reload early
+ _onGetPartnerClick: function () {
+ this._rpc({
+ model: 'res.partner',
+ method: 'get_odoo_partner',
+ args: [],
+ }).then(() => {
+ this.reload();
+ });
+ // Couldn't test this for real, but it runs the action. May need a this.reload()
+ },
+});
+
+const OdooScrapperListView = ListView.extend({
+ config: _.extend({}, ListView.prototype.config, {
+ Controller: OdooScrapperListController,
+ }),
+});
+
+// key must match with the js_class attribute of the tree view you want to modify
+viewRegistry.add('res_partner_odoo_scrapper_tree', OdooScrapperListView);
+
diff --git a/bemade_odoo_partner_scrapper/static/src/xml/odoo_scrapper_templates.xml b/bemade_odoo_partner_scrapper/static/src/xml/odoo_scrapper_templates.xml
new file mode 100644
index 0000000..1a33faa
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/static/src/xml/odoo_scrapper_templates.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bemade_odoo_partner_scrapper/views/res_partner_views.xml b/bemade_odoo_partner_scrapper/views/res_partner_views.xml
new file mode 100644
index 0000000..10a55ed
--- /dev/null
+++ b/bemade_odoo_partner_scrapper/views/res_partner_views.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ res.partner.tree.inherit
+ res.partner
+
+
+
+ res_partner_odoo_scrapper_tree
+
+
+
+
+
+
+
+