25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
calculate-utils-3-update/pym/update/profile.py

247 satır
8.1 KiB

Bu dosya muğlak Evrensel Kodlu karakter içeriyor!

Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek muğlak Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Bu karakterleri göstermek için Kaçış düğmesine tıklayın.

#-*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from os import path
import shutil
import os
from calculate.lib.utils.files import listDirectory, readFile, readLinesFile, \
makeDirectory, removeDir
from package_tools import Git
from update import UpdateError
from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__])
DEFAULT_BRANCH = "master"
class RepositoryStorage(object):
directory = '/tmp'
def __init__(self, directory):
self.directory = directory
makeDirectory(directory)
def __iter__(self):
git = Git()
for dn in listDirectory(self.directory, onlyDir=True, fullPath=True):
if git.is_git(dn):
yield ProfileRepository(path.basename(dn), self)
def get_profiles(self, url, branch=DEFAULT_BRANCH):
return []
class ProfileStorage(RepositoryStorage):
def get_profiles(self, url, branch=DEFAULT_BRANCH):
rep = self.get_repository(url, branch)
if rep:
return rep.get_profiles()
return None
def get_repository(self, url, branch=DEFAULT_BRANCH):
return None
class LocalStorage(ProfileStorage):
"""
Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные
репозитории если находит подходящий - возвращает его профили
"""
def get_repository(self, url, branch=DEFAULT_BRANCH):
for rep in self:
if rep.is_like(url, branch):
return rep
class CacheStorage(ProfileStorage):
"""
Хранилище репозиториев, при запросе по урлу смотрит, доступные
репозитории если находит подходящий - возвращает его профили,
если не находит - скачивает и возвращает профили
"""
def get_repository(self, url, branch=DEFAULT_BRANCH):
for rep in self:
if rep.is_like(url, branch):
return rep
else:
return ProfileRepository.clone(url, self, branch)
class RepositoryStorageSet(RepositoryStorage):
"""
Набор хранилищ репозиториев
"""
def __init__(self):
self.storages = [LocalStorage('/var/lib/layman'),
CacheStorage('/var/calculate/tmp/update')]
def get_profiles(self, url, branch=DEFAULT_BRANCH):
"""
Получить профили из указанного репозитория
"""
for storage in self.storages:
profiles = storage.get_profiles(url, branch)
if profiles is not None:
return profiles
return None
def __iter__(self):
for storage in self.storages:
for rep in storage:
yield rep
def get_repository(self, url, branch=DEFAULT_BRANCH):
"""
Получить репозиторий по параметрам
"""
for rep in self:
if rep.is_like(url, branch):
return rep
return None
def is_local(self, url, branch=DEFAULT_BRANCH):
"""
Проверить является ли репозиторий с указанными параметрами
локальным
"""
rep = self.get_repository(url, branch)
if rep and isinstance(rep.storage, LocalStorage):
return True
return False
def __repr__(self):
return "Repository set"
class Profile(object):
"""
Профиль репозитория
"""
available_arch = ["amd64", "x86"]
def __init__(self, repository, profile, arch):
self.repository = repository
self.profile = profile
self.arch = arch
@property
def path(self):
return path.join(self.repository.directory,"profiles", self.profile)
@classmethod
def from_string(cls, repository, s):
parts = filter(None, s.split())
if len(parts) == 3 and parts[0] in cls.available_arch:
return Profile(repository, parts[1], parts[0])
return None
def __repr__(self):
return "<Profile (%s) %s:%s from %s>" % (self.arch,
self.repository.repo_name,
self.profile,
self.repository.directory)
class ProfileRepository(object):
"""
Репозиторий либо скачивается, либо берется из кэша
"""
def __init__(self, name, storage):
self._storage = storage
self.name = name
@property
def storage(self):
return self._storage
@storage.setter
def storage(self, storage):
if storage.directory != self._storage.directory:
newpath = path.join(storage.directory, self.name)
if self.directory == newpath:
return
try:
if path.exists(newpath):
removeDir(newpath)
shutil.move(self.directory, newpath)
self._storage = storage
except OSError as e:
raise UpdateError(_("Failed to move the profile: %s") %
str(e))
@classmethod
def clone(cls, url, storage, branch=DEFAULT_BRANCH):
name = path.basename(url)
if name.endswith(".git"):
name = name[:-4]
git = Git()
rpath = path.join(storage.directory, name)
if path.exists(rpath):
removeDir(rpath)
git.cloneRepository(url, rpath, branch)
pr = cls(name, storage)
repo_name = pr.repo_name
if name != repo_name:
rpath_new = path.join(storage.directory, repo_name)
if not path.exists(rpath_new):
os.rename(rpath, rpath_new)
pr = cls(repo_name, storage)
return pr
@property
def repo_name(self):
return readFile(path.join(self.directory,
"profiles/repo_name")).strip()
def is_like(self, url, branch=DEFAULT_BRANCH):
if self.url == url and (branch is None or self.branch == branch):
return True
return False
@property
def directory(self):
"""
Получить локальную директорию на данные репозитория
"""
return path.join(self.storage.directory, self.name)
@property
def url(self):
git = Git()
return git.get_url(self.directory, "origin")
@property
def branch(self):
git = Git()
return git.getBranch(self.directory)
def sync(self):
"""
Синхронизировать репозиторий
"""
git = Git()
if not git.pullRepository(self.directory, quiet_error=True):
git.resetRepository(self.directory, to_origin=True)
git.pullRepository(self.directory, quiet_error=True)
def get_profiles(self):
"""
Получить список профилей репозитория
"""
profiles_desc = path.join(self.directory, "profiles/profiles.desc")
return filter(None, (Profile.from_string(self, line)
for line in readLinesFile(profiles_desc)))
def __repr__(self):
return "<ProfileRepository %s url=%s>" % (self.directory, self.url)