Blame model/repositories.py

e5b0ac
e5b0ac
import exception
e5b0ac
e5b0ac
from model.base import ModelBase
e5b0ac
e5b0ac
e5b0ac
class Repository(ModelBase):
e5b0ac
  def __init__(self, repositories, row, user = None):
e5b0ac
    self.repositories = repositories
e5b0ac
    super().__init__(self.repositories.model)
e5b0ac
    
e5b0ac
    self.id = int(row['id'])
e5b0ac
    self.user_id = int(row['user_id'])
e5b0ac
    self.name = str(row['name'])
e5b0ac
    self.type = str(row['type'])
e5b0ac
    self.title = str(row['title'])
e5b0ac
    self.description = str(row['description'])
e5b0ac
    
e5b0ac
    assert(not user or user.id == self.user_id)
e5b0ac
    self.user = user
e5b0ac
    self.repotype = self.repositories.repotypes[self.type]
e5b0ac
e5b0ac
  def get_user(self):
e5b0ac
    if self.user == None:
e5b0ac
      self.user = self.model.users.get_by_id(self.user_id)
e5b0ac
    assert(self.user)
e5b0ac
    assert(self.user.id == self.user_id)
e5b0ac
    return self.user
e5b0ac
e5b0ac
  def reset_cache(self):
e5b0ac
    self.repositories.reset_cache(self.id, self.user_id, self.name)
e5b0ac
    
e5b0ac
  def gen_subpath(self):
e5b0ac
    return self.repositories.gen_subpath(self.get_user().login, self.name)
e5b0ac
e5b0ac
  def gen_internalurl(self):
e5b0ac
    return self.repotype.gen_internalurl( self.gen_subpath() )
e5b0ac
    
e5b0ac
  def can_update(self):
e5b0ac
    return self.user_id == self.rights.user_id or self.rights.issuperuser()
e5b0ac
  
e5b0ac
  def update(self, title, description):
e5b0ac
    if self.can_update():
e5b0ac
      self.connection.execute(
e5b0ac
        'UPDATE %T SET `title`=%s, `description`=%s WHERE `id`=%d',
e5b0ac
        self.repositories.TABLE, title, description, self.id )
e5b0ac
      self.reset_cache()
e5b0ac
    else:
e5b0ac
      raise exception.ModelDeny()
e5b0ac
e5b0ac
  def can_delete(self):
e5b0ac
    return self.user_id == self.rights.user_id or self.rights.issuperuser()
e5b0ac
e5b0ac
  def delete(self, password = None):
e5b0ac
    if self.can_delete():
e5b0ac
      self.connection.execute(
e5b0ac
        'DELETE FROM %T WHERE `id`=%d',
e5b0ac
        self.repositories.TABLE, self.id )
e5b0ac
      self.reset_cache()
e5b0ac
      self.connection.call_on_commit(self.repotype.delete, self.gen_subpath())
e5b0ac
    else:
e5b0ac
      raise exception.ModelDeny()
e5b0ac
e5b0ac
e5b0ac
class Repositories(ModelBase):
e5b0ac
  TABLE = 'repositories'
e5b0ac
  
e5b0ac
  def __init__(self, model):
e5b0ac
    super().__init__(model)
e5b0ac
    self.repotypes = self.server.repotypes
e5b0ac
    
e5b0ac
  def reset_cache(self, id, user_id, name):
e5b0ac
    self.connection.cache.reset_row(self.TABLE, id)
e5b0ac
    self.connection.cache.reset(self.TABLE, {'user_id': user_id, 'name': name})
e5b0ac
e5b0ac
  def verify_name(self, name):
e5b0ac
    return self.model.verify_identifier(name)
e5b0ac
e5b0ac
  def gen_subpath(self, login, name):
e5b0ac
    assert( self.model.verify_path_entry(login) )
e5b0ac
    assert( self.model.verify_path_entry(name) )
e5b0ac
    return login + '/' + name
e5b0ac
e5b0ac
  def can_create(self, user_id):
e5b0ac
    assert(type(user_id) is int and user_id)
e5b0ac
    return user_id == self.rights.user_id or self.rights.issuperuser()
e5b0ac
e5b0ac
  def create(self, user_id, name, repotype, title, description, user = None):
e5b0ac
    assert(not user or user.id == user_id)
e5b0ac
    if not self.can_create(user_id):
e5b0ac
      raise exception.ModelDeny()
e5b0ac
    if not self.verify_name(name):
e5b0ac
      raise exception.ModelWrongData(self.t('Repository name is incorrect'))
e5b0ac
    if not type(repotype) is str or not repotype in self.repotypes:
e5b0ac
      raise exception.ModelWrongData(self.t('Repository type is incorrect'))
e5b0ac
    if self.get_by_name(user_id, name):
e5b0ac
      raise exception.ModelWrongData(self.t('Repository already exists'))
e5b0ac
    
e5b0ac
    if not user:
e5b0ac
      user = self.model.users.get_by_id(user_id)
e5b0ac
      if not user:
e5b0ac
        raise exception.ModelWrongData(self.t('User not found'))
e5b0ac
    
e5b0ac
    self.connection.execute(
e5b0ac
      'INSERT INTO %T SET `user_id`=%d, `name`=%s, `type`=%s, `title`=%s, `description`=%s',
e5b0ac
      self.TABLE, user_id, name, repotype, title, description )
e5b0ac
    id = self.connection.insert_id()
e5b0ac
    self.reset_cache(id, user_id, name)
e5b0ac
    
e5b0ac
    subpath = self.gen_subpath(user.login, name)
e5b0ac
    repotype_instance = self.repotypes[repotype]
e5b0ac
    self.connection.call_on_rollback(repotype_instance.delete, subpath)
e5b0ac
    repotype_instance.create(subpath)
e5b0ac
e5b0ac
    return self.get_by_id(id, user)
e5b0ac
e5b0ac
  def get_by_id(self, id, user = None):
e5b0ac
    assert(type(id) is int)
e5b0ac
    row = self.connection.cache.row(self.TABLE, id)
e5b0ac
    if not row:
e5b0ac
      return None
e5b0ac
    if not user:
e5b0ac
      user = self.model.users.get_by_id(row['user_id'])
e5b0ac
      if not user:
e5b0ac
        return None
e5b0ac
    return Repository(self, row, user)
e5b0ac
    
e5b0ac
  def get_by_name(self, user_id, name, user = None):
e5b0ac
    assert(not user or user.id == user_id)
e5b0ac
    assert(type(user_id) is int)
e5b0ac
    assert(type(name) is str)
e5b0ac
    
e5b0ac
    rows = self.connection.cache.select(self.TABLE, {'user_id': user_id, 'name': name})
e5b0ac
    if not rows or len(rows) > 1:
e5b0ac
      return None
e5b0ac
    row = rows[0]
e5b0ac
    if not user:
e5b0ac
      user = self.model.users.get_by_id(row['user_id'])
e5b0ac
      if not user:
e5b0ac
        return None
e5b0ac
    return Repository(self, row, user)
e5b0ac
  
e5b0ac
  def get_list(self, user):
e5b0ac
    assert(user)
e5b0ac
    result = list()
e5b0ac
    rows = self.connection.query_dict('SELECT * FROM %T WHERE `user_id`=%d ORDER BY `name`', self.TABLE, user.id)
e5b0ac
    for row in rows:
e5b0ac
      result.append(Repository(self, row, user))
e5b0ac
    return result
e5b0ac