Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions vcp_github/models/vcp_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
class VcpRepository(models.Model):
_inherit = "vcp.repository"

def _get_repository_url(self):
result = super()._get_repository_url()
if not result and self.platform_id.host_id.type_id.code == "github":
return f"https://github.com/{self.platform_id.name}/{self.name}"
return result

def _update_branches_github(self):
self.ensure_one()
client = self.platform_id._get_github_clients()[0]
Expand Down
41 changes: 40 additions & 1 deletion vcp_github/models/vcp_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).


from odoo import models
import logging
from datetime import datetime

import github3

from odoo import fields, models
from odoo.exceptions import ValidationError

_logger = logging.getLogger(__name__)


class VcpUser(models.Model):
Expand All @@ -13,3 +21,34 @@ def _get_contributor_url(self):
if not result and self.host_id.type_id.code == "github":
return f"https://github.com/{self.external_id}"
return result

def _prepare_user_vals(self, user):
return {
"name": user.name or user.login,
"email": user.email,
"avatar_url": user.avatar_url,
"company": user.company,
}

def _update_information_github(self):
self.ensure_one()
# TODO maybe we should move the api key on the host ?
platform = self.env["vcp.platform"].search(
[("host_id", "=", self.host_id.id)], limit=1
)
client = platform._get_github_clients()[0]
try:
user = client.user(self.external_id)
self.write(self._prepare_user_vals(user))
except github3.exceptions.ForbiddenError as e:
_logger.error(e)
rate = client.rate_limit()
reset = fields.Datetime.to_string(
datetime.utcfromtimestamp(rate["resources"]["core"]["reset"])
)
raise ValidationError(self.env._(f"Reset on {reset}")) from e
except github3.exceptions.NotFoundError:
_logger.warning(
"The user %s do not exist anymore, inactive it", self.external_id
)
self.active = False
9 changes: 9 additions & 0 deletions vcp_management/data/ir_cron.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@
<field name="interval_type">days</field>
<field name="active">False</field>
</record>
<record model="ir.cron" id="cron_user_update">
<field name="name">VCP: User Update</field>
<field name="model_id" ref="model_vcp_user" />
<field name="state">code</field>
<field name="code">model._cron_update_users(limit=100)</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="active">False</field>
</record>
</odoo>
33 changes: 33 additions & 0 deletions vcp_management/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).


import base64

import requests

from odoo import api, fields, models
from odoo.exceptions import UserError


class ResPartner(models.Model):
Expand Down Expand Up @@ -32,6 +37,34 @@ class ResPartner(models.Model):
"vcp.organization",
inverse_name="partner_id",
)
image_1920 = fields.Image(
compute="_compute_image_1920",
store=True,
readonly=False,
)

@api.depends(
"vcp_user_ids.sync_image_to_partner",
"vcp_user_ids.avatar_url",
)
def _compute_image_1920(self):
for record in self:
sync_user = record.vcp_user_ids.filtered("sync_image_to_partner")
if len(sync_user) > 1:
raise UserError(
self.env._(
"Only one Vcp User can be use for synchronising the main image"
)
)
elif sync_user.avatar_url:
try:
response = requests.get(sync_user.avatar_url, timeout=10)
response.raise_for_status()
except Exception as e:
raise UserError(
self.env._("Fail to download avatar, %s.please retry".format())
) from e
record.image_1920 = base64.b64encode(response.content).decode("utf-8")

@api.depends()
def _compute_vcp_contributions(self):
Expand Down
34 changes: 27 additions & 7 deletions vcp_management/models/vcp_repository_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import os
import re
import traceback

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
Expand All @@ -11,6 +12,7 @@ class VcpRepositoryBranch(models.Model):
_name = "vcp.repository.branch"
_inherit = ["vcp.rule.information.mixin"]
_description = "Links Branches with Repositories"
_order = "rule_failure_msg, repository_id, branch_id"

branch_id = fields.Many2one(
"vcp.branch",
Expand Down Expand Up @@ -39,9 +41,14 @@ class VcpRepositoryBranch(models.Model):
default=fields.Datetime.now,
required=True,
)
rule_failure_msg = fields.Text()

def _cron_process_branch_rules(self, limit):
branches = self.search([], limit=limit, order="update_rule_processing_date asc")
branches = self.search(
[],
limit=limit,
order="update_rule_processing_date asc",
)
for branch in branches:
branch.process_rules()

Expand All @@ -65,12 +72,25 @@ def _get_local_path(self):
def process_rules(self):
for record in self:
rules = record._get_rules()
# This parameters dict can be used to store parameters that will
# be used by other rules.
parameters = {}
for rule in rules:
if re.match(rule.branch_pattern, record.branch_id.name):
rule._process_rule(record, parameters)
try:
with self.env.cr.savepoint():
# This parameters dict can be used to store parameters that will
# be used by other rules.
parameters = {}
for rule in rules:
if re.match(rule.branch_pattern, record.branch_id.name):
rule._process_rule(record, parameters)
except Exception as e:
record.rule_failure_msg = (
f"error: {e}\n\n traceback: {traceback.format_exc()}"
)
# we need to purge the cache as _get_odoo_module keep the module name
# in cache and if a module have been creating during the try
# as this have been rollbacked we need to purge it from the cache
self.env.registry.clear_cache()
else:
record.rule_failure_msg = False
record.update_rule_processing_date = fields.Datetime.now()

def _download_code(self):
result = super()._download_code()
Expand Down
23 changes: 23 additions & 0 deletions vcp_management/models/vcp_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ class VcpUser(models.Model):
partner_id = fields.Many2one(
"res.partner",
)
sync_image_to_partner = fields.Boolean(
help="Use the image user as image on the partner"
)
user_update_date = fields.Datetime(readonly=True, default=fields.Datetime.now)
avatar_url = fields.Char(readonly=True)
email = fields.Char(readonly=True)
company = fields.Char(readonly=True)
active = fields.Boolean(readonly=True, default=True)

_sql_constraints = [
(
Expand All @@ -40,3 +48,18 @@ def _get_contributor_url(self):

def _get_contributors_name(self, kind, **kwargs):
return self.partner_id.name or self.name

def update_information(self):
self.ensure_one()
now = fields.Datetime.now()
getattr(self, f"_update_information_{self.host_id.type_id.code}")()
self.user_update_date = now

def _cron_update_users(self, limit):
users = self.search(
[],
limit=limit,
order="user_update_date ASC",
)
for user in users:
user.update_information()
2 changes: 1 addition & 1 deletion vcp_management/views/vcp_platform.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<button
name="update_information"
type="object"
string="Update Information"
string="update information"
class="oe_highlight"
/>
</header>
Expand Down
30 changes: 30 additions & 0 deletions vcp_management/views/vcp_repository_branch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@
<field name="model">vcp.repository.branch</field>
<field name="arch" type="xml">
<form>
<header>
<button
name="process_rules"
type="object"
string="Process Rules"
class="oe_highlight"
/>
</header>
<div
class="alert alert-danger"
role="alert"
style="margin-bottom:0px;"
invisible="not rule_failure_msg"
>
<p>
<strong
>There is an exception blocking the rule processing:</strong>
</p>
<field name="rule_failure_msg" />
</div>
<sheet>
<group>
<field name="repository_id" />
Expand All @@ -29,6 +49,11 @@
<field name="model">vcp.repository.branch</field>
<field name="arch" type="xml">
<search>
<filter
string="Process Rule Error"
name="error"
domain="[('rule_failure_msg', '!=', False)]"
/>
<field name="repository_id" />
<field name="branch_id" />
<field name="platform_id" />
Expand All @@ -43,6 +68,11 @@
<field name="platform_id" />
<field name="repository_id" />
<field name="branch_id" />
<field
name="update_rule_processing_date"
decoration-danger="rule_failure_msg!=False"
/>
<field name="rule_failure_msg" column_invisible="True" />
</list>
</field>
</record>
Expand Down
14 changes: 13 additions & 1 deletion vcp_management/views/vcp_user.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@
<form>
<header />
<sheet>
<div class="oe_title">
<h1>
<field name="name" />
</h1>
</div>
<group>
<field name="name" />
<field name="avatar_url" widget='url' />
<field name="external_id" />
<field name="email" />
<field name="company" />
<field name="host_id" />
<field name="partner_id" />
<field
name="sync_image_to_partner"
invisible="not partner_id"
/>
</group>
</sheet>
</form>
Expand All @@ -36,6 +47,7 @@
<field name="name" />
<field name="external_id" />
<field name="host_id" />
<field name="sync_image_to_partner" />
</list>
</field>
</record>
Expand Down
2 changes: 2 additions & 0 deletions vcp_odoo/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
"views/vcp_odoo_module_version.xml",
"views/vcp_odoo_bin_package.xml",
"views/vcp_odoo_python_library.xml",
"views/vcp_odoo_author.xml",
"views/vcp_rule.xml",
"views/menu.xml",
"views/res_partner.xml",
"data/vcp_rule.xml",
],
"demo": [],
Expand Down
2 changes: 2 additions & 0 deletions vcp_odoo/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from . import vcp_rule
from . import vcp_odoo_module
from . import vcp_odoo_author
from . import vcp_odoo_module_version
from . import vcp_odoo_bin_package
from . import vcp_odoo_python_library
from . import res_partner
42 changes: 42 additions & 0 deletions vcp_odoo/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2026 Akretion (https://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).


from odoo import fields, models


class ResPartner(models.Model):
_inherit = "res.partner"

modules_maintained_count = fields.Integer(
compute="_compute_modules_maintained_count"
)

modules_author_count = fields.Integer(compute="_compute_modules_author_count")

def _compute_modules_maintained_count(self):
for record in self:
record.modules_maintained_count = self.env["vcp.odoo.module"].search_count(
[("version_ids.maintainer_ids.partner_id", "=", record.id)],
)

def action_view_maintained_modules(self):
action = self.env["ir.actions.actions"]._for_xml_id(
"vcp_odoo.vcp_odoo_module_act_window"
)
action["domain"] = [("version_ids.maintainer_ids.partner_id", "=", self.id)]
return action

def _compute_modules_author_count(self):
for record in self:
record.modules_author_count = self.env["vcp.odoo.module"].search_count(
[("version_ids.author_ids.partner_id", "=", record.id)],
)

def action_view_author_modules(self):
action = self.env["ir.actions.actions"]._for_xml_id(
"vcp_odoo.vcp_odoo_module_act_window"
)
action["domain"] = [("version_ids.author_ids.partner_id", "=", self.id)]
return action
Loading
Loading