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.

105 lines
3.3 KiB

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