You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.3 KiB

  1. # -*- coding: utf-8 -*-
  2. import os
  3. import random
  4. import shutil
  5. import string
  6. import subprocess
  7. from odoo import models, fields, api, http
  8. from odoo.exceptions import ValidationError
  9. from odoo.tools import config, which
  10. class Repository(models.Model):
  11. _name = 'galicea_git.repository'
  12. state = fields.Selection(
  13. [('draft', 'Draft'), ('created', 'Created')],
  14. default='draft'
  15. )
  16. name = fields.Char('User-friendly name', required=True)
  17. system_name = fields.Char(
  18. 'Directory name',
  19. required=True,
  20. readonly=True,
  21. index=True,
  22. states={'draft': [('readonly', False)]}
  23. )
  24. collaborator_ids = fields.Many2many(
  25. 'res.users',
  26. string='Collaborators'
  27. )
  28. local_directory = fields.Char(
  29. 'Local directory on server',
  30. compute='_compute_local_directory',
  31. groups='galicea_git.group_admin'
  32. )
  33. url = fields.Char(
  34. 'Clone',
  35. compute='_compute_url'
  36. )
  37. @api.one
  38. @api.depends('system_name')
  39. def _compute_url(self):
  40. base_url = http.request.httprequest.host_url if http.request \
  41. else env['ir.config_parameter'].get_param('web.base.url') + '/'
  42. self.url = u'{}git/{}'.format(base_url, self.system_name)
  43. @api.one
  44. @api.depends('system_name')
  45. def _compute_local_directory(self):
  46. if self.system_name:
  47. self.local_directory = os.path.join(config['data_dir'], 'git', self.system_name)
  48. @api.constrains('system_name')
  49. def _validate_system_name(self):
  50. allowed_characters = string.ascii_lowercase + string.digits + '-'
  51. if not all(c in allowed_characters for c in self.system_name):
  52. raise ValidationError(
  53. 'Only lowercase, digits and hyphens (-) are allowed in directory name'
  54. )
  55. @api.constrains('collaborator_ids')
  56. def _validate_collaborator_ids(self):
  57. invalid_collaborators = self.collaborator_ids.filtered(lambda c: not c.has_group('galicea_git.group_collaborator'))
  58. if invalid_collaborators:
  59. raise ValidationError(
  60. 'User {} does not have the {} role. Contact your Administrator'.format(
  61. invalid_collaborators[0].name,
  62. self.env.ref('galicea_git.group_collaborator').full_name
  63. )
  64. )
  65. @api.model
  66. def create(self, values):
  67. values['state'] = 'created'
  68. ret = super(Repository, self).create(values)
  69. ret.__initialize_repo()
  70. return ret
  71. @api.multi
  72. def unlink(selfs):
  73. directories_to_move = selfs.mapped(lambda r: r.local_directory)
  74. ret = super(Repository, selfs).unlink()
  75. for directory in directories_to_move:
  76. if os.path.exists(directory):
  77. suffix = ''.join(random.choice(string.ascii_lowercase) for _ in range(8))
  78. new_directory = directory + '-deleted-' + suffix
  79. shutil.move(directory, new_directory)
  80. @api.multi
  81. def __initialize_repo(self):
  82. self.ensure_one()
  83. if os.path.exists(self.local_directory):
  84. raise ValidationError(
  85. 'Repository {} already exists, choose a different name!'.format(self.system_name)
  86. )
  87. subprocess.check_call([which('git'), 'init', '--bare', self.local_directory])