Рефакторинг

develop 3.4.1.2
Mike Khiretskiy 9 years ago
parent 66cd9596d7
commit b3ca8fed9c

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,14 +14,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
__app__ = 'calculate-update' __app__ = 'calculate-update'
__version__ = '3.1.8' __version__ = '3.4.1'
import os
import sys import sys
from calculate.lib.datavars import DataVars from calculate.lib.datavars import DataVars
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_update3',sys.modules[__name__])
setLocalTranslate('cl_update3', sys.modules[__name__])
class DataVarsUpdate(DataVars): class DataVarsUpdate(DataVars):
"""Variable class for desktop package""" """Variable class for desktop package"""
@ -31,4 +31,3 @@ class DataVarsUpdate(DataVars):
self.importVariables() self.importVariables()
self.importVariables('calculate.update.variables') self.importVariables('calculate.update.variables')
self.defaultModule = "update" self.defaultModule = "update"

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import hashlib import hashlib
import os import os
@ -22,13 +23,15 @@ import re
import sys import sys
from calculate.lib.utils.colortext.palette import TextState from calculate.lib.utils.colortext.palette import TextState
from calculate.lib.utils.tools import ignore from calculate.lib.utils.tools import ignore
from calculate.lib.utils.portage import EmergePackage, PackageList, EmergeUpdateInfo, \ from calculate.lib.utils.portage import (EmergePackage, PackageList,
EmergeRemoveInfo, Git, GitError EmergeUpdateInfo,
EmergeRemoveInfo, Git, GitError)
Colors = TextState.Colors Colors = TextState.Colors
import pexpect import pexpect
from calculate.lib.utils.files import getProgPath, readLinesFile, listDirectory, \ from calculate.lib.utils.files import (getProgPath, readLinesFile,
writeFile, readFile listDirectory,
writeFile, readFile)
from calculate.lib.utils.colortext.output import XmlOutput from calculate.lib.utils.colortext.output import XmlOutput
from calculate.lib.utils.colortext.converter import (ConsoleCodes256Converter, from calculate.lib.utils.colortext.converter import (ConsoleCodes256Converter,
XmlConverter) XmlConverter)
@ -39,7 +42,7 @@ from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
linux_term_env = {'TERM':'linux'} linux_term_env = {'TERM': 'linux'}
class EmergeError(Exception): class EmergeError(Exception):
""" """
@ -98,20 +101,6 @@ class CommandExecutor(object):
if self.child: if self.child:
self.child.send(s) self.child.send(s)
class ChrootCommandExecutor(CommandExecutor):
"""
Команда запускаемая в chroot
"""
def __init__(self, chroot_path, cmd, params, env=None, cwd=None,
logfile=None):
self.chroot_path = chroot_path
super(ChrootCommandExecutor, self).__init__(cmd, params, env=env,
cwd=cwd, logfile=logfile)
def get_command(self):
chrootCmd = '/usr/bin/chroot'
return [chrootCmd, self.chroot_path, self.cmd] + self.params
class EmergeCommand(CommandExecutor): class EmergeCommand(CommandExecutor):
""" """
@ -119,54 +108,29 @@ class EmergeCommand(CommandExecutor):
""" """
# параметры по умолчанию # параметры по умолчанию
default_params = ["-av", "--color=y", "--nospinner"] default_params = ["-av", "--color=y", "--nospinner"]
cmd = getProgPath("/usr/bin/emerge") emerge_cmd = getProgPath("/usr/bin/emerge")
def __init__(self, packages, extra_params=None, env=None, cwd=None, def __init__(self, packages, extra_params=None, env=None, cwd=None,
logfile=None, emerge_default_opts=None, use=""): logfile=None, emerge_default_opts=None, use=""):
extra_params = extra_params or [] extra_params = extra_params or []
self.child = None if env is None:
self.packages = packages if emerge_default_opts is None:
self.params = self.default_params + extra_params env = {'CLEAN_DELAY': '0'}
if emerge_default_opts is None: else:
default_env = {'CLEAN_DELAY': '0'} env = {
else: 'CLEAN_DELAY': '0',
default_env = { 'EMERGE_DEFAULT_OPTS': re.sub(
'CLEAN_DELAY': '0', r'(?:^|\s)(--columns)(?=\s|$)', '',
'EMERGE_DEFAULT_OPTS': re.sub(r'(?:^|\s)(--columns)(?=\s|$)','', emerge_default_opts)
emerge_default_opts) }
} if use:
if use: env["USE"] = use
default_env["USE"] = use env.update(os.environ)
default_env.update(os.environ)
self.env = env or default_env
self.env.update(linux_term_env)
self.cwd = cwd
if logfile:
self.logfile = logfile
def get_command(self):
return [self.cmd] + self.params + self.packages
class ChrootEmergeCommand(EmergeCommand): params = self.default_params + extra_params + packages
def __init__(self, chroot_path, *args, **kw): super(EmergeCommand, self).__init__(self.emerge_cmd, params=params,
self.chroot_path = chroot_path env=env, cwd=cwd, logfile=logfile)
super(ChrootEmergeCommand, self).__init__(*args, **kw)
def get_command(self):
chrootCmd = '/usr/bin/chroot'
bashCmd = '/bin/bash'
bash_command = (
"env-update &>/dev/null;"
"source /etc/profile &>/dev/null;"
"{emerge_command} {params} {packages}".format(
emerge_command=self.cmd,
params=" ".join(self.params),
packages=" ".join(self.packages)
))
return [chrootCmd, self.chroot_path, bashCmd, "-c",
bash_command]
def Chroot(chroot_path, obj): def Chroot(chroot_path, obj):
""" """
@ -203,19 +167,36 @@ def Linux32(obj):
return obj return obj
class EmergeInformationBlock(object): class InfoBlockInterface(object):
"""
Интерфейс для информационного блока
"""
action = None
token = None
result = None
text_converter = ConsoleCodes256Converter(XmlOutput())
def get_block(self, child):
pass
def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
pass
class EmergeInformationBlock(InfoBlockInterface):
_color_block = "(?:\033\[[^m]+?m)?" _color_block = "(?:\033\[[^m]+?m)?"
_new_line = "(?:\r*\n)" _new_line = "(?:\r*\n)"
token = None
end_token = ["\n"] end_token = ["\n"]
re_block = None re_block = None
action = None
re_match_type = type(re.match("", "")) re_match_type = type(re.match("", ""))
re_type = type(re.compile("")) re_type = type(re.compile(""))
def __init__(self, parent): def __init__(self, parent):
""" """
:type parent: EmergeParser :type parent: InfoBlockInterface
""" """
self.result = None self.result = None
self.text_converter = parent.text_converter self.text_converter = parent.text_converter
@ -224,6 +205,9 @@ class EmergeInformationBlock(object):
self.children = [] self.children = []
def add_element(self, element): def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
self.children.append(element) self.children.append(element)
def __str__(self): def __str__(self):
@ -308,7 +292,7 @@ class UninstallPackagesBlock(EmergeInformationBlock):
_new_line = EmergeInformationBlock._new_line _new_line = EmergeInformationBlock._new_line
_color_block = EmergeInformationBlock._color_block _color_block = EmergeInformationBlock._color_block
token = ["Calculating removal order", token = ["Calculating removal order",
"These are the packages that would be unmerged",] "These are the packages that would be unmerged"]
end_token = re.compile("All selected packages:.*\n") end_token = re.compile("All selected packages:.*\n")
re_block = re.compile( re_block = re.compile(
r"(?:{token}).*?{nl}(.*){nl}All selected packages: (.*?){nl}". r"(?:{token}).*?{nl}(.*){nl}All selected packages: (.*?){nl}".
@ -326,6 +310,7 @@ class UninstallPackagesBlock(EmergeInformationBlock):
list_block = XmlConverter().transform(self.result).split() list_block = XmlConverter().transform(self.result).split()
self.list = PackageList(map(EmergePackage, list_block)) self.list = PackageList(map(EmergePackage, list_block))
class GroupEmergeInformationBlock(EmergeInformationBlock): class GroupEmergeInformationBlock(EmergeInformationBlock):
""" """
Группа блоков Группа блоков
@ -456,7 +441,6 @@ class QuestionGroup(GroupEmergeInformationBlock):
child.expect_exact(self.end_token) child.expect_exact(self.end_token)
match = child.match match = child.match
data = token + child.before + match data = token + child.before + match
#self.get_data(before + data)
child.before = before child.before = before
for block in self.children: for block in self.children:
child.match = re.search(block.token, data) child.match = re.search(block.token, data)
@ -668,13 +652,12 @@ class RevdepPercentBlock(NotifierInformationBlock):
except pexpect.EOF: except pexpect.EOF:
self.result = "" self.result = ""
class EmergeParser(object): class EmergeParser(InfoBlockInterface):
""" """
Парсер вывода emerge Парсер вывода emerge
""" """
def __init__(self, command, run=False): def __init__(self, command, run=False):
self.text_converter = ConsoleCodes256Converter(XmlOutput())
self.command = command self.command = command
self.elements = {} self.elements = {}
@ -710,6 +693,9 @@ class EmergeParser(object):
self.fetching.action = lambda child: None self.fetching.action = lambda child: None
def add_element(self, element): def add_element(self, element):
"""
:type element: InfoBlockInterface
"""
if element.token: if element.token:
if type(element.token) == list: if type(element.token) == list:
for token in element.token: for token in element.token:
@ -765,6 +751,7 @@ class Md5Checkvalue(MtimeCheckvalue):
def value_func(self, fn): def value_func(self, fn):
return hashlib.md5(readFile(fn)).hexdigest() return hashlib.md5(readFile(fn)).hexdigest()
class GitCheckvalue(object): class GitCheckvalue(object):
def __init__(self, rpath): def __init__(self, rpath):
self.rpath = rpath self.rpath = rpath
@ -783,10 +770,10 @@ class EmergeCache(object):
cache_file = '/var/lib/calculate/calculate-update/world.cache' cache_file = '/var/lib/calculate/calculate-update/world.cache'
# список файлов проверяемый по mtime на изменения # список файлов проверяемый по mtime на изменения
check_list = [MtimeCheckvalue('/etc/make.conf', check_list = [MtimeCheckvalue('/etc/make.conf',
'/etc/portage', '/etc/portage',
'/etc/make.profile'), '/etc/make.profile'),
Md5Checkvalue('/var/lib/portage/world', Md5Checkvalue('/var/lib/portage/world',
'/var/lib/portage/world_sets')] '/var/lib/portage/world_sets')]
logger = log("emerge-cache", logger = log("emerge-cache",
filename="/var/log/calculate/emerge-cache.log", filename="/var/log/calculate/emerge-cache.log",
formatter="%(asctime)s - %(levelname)s - %(message)s") formatter="%(asctime)s - %(levelname)s - %(message)s")
@ -804,16 +791,16 @@ class EmergeCache(object):
f.write("{fn}={val}\n".format(fn=fn, val=val)) f.write("{fn}={val}\n".format(fn=fn, val=val))
f.write('\n') f.write('\n')
for pkg in package_list: for pkg in package_list:
f.write("%s\n"% str(pkg)) f.write("%s\n" % str(pkg))
self.logger.info("Setting cache (%d packages)"%len(package_list)) self.logger.info("Setting cache (%d packages)" % len(package_list))
def drop_cache(self, reason=None): def drop_cache(self, reason=None):
if path.exists(self.cache_file): if path.exists(self.cache_file):
with ignore(OSError): with ignore(OSError):
os.unlink(self.cache_file) os.unlink(self.cache_file)
self.logger.info("Droping cache. Reason: %s"%reason) self.logger.info("Droping cache. Reason: %s" % reason)
else: else:
self.logger.info("Droping empty cache. Reason: %s"%reason) self.logger.info("Droping empty cache. Reason: %s" % reason)
def get_cached_package_list(self): def get_cached_package_list(self):
self.read_cache() self.read_cache()
@ -833,10 +820,10 @@ class EmergeCache(object):
return True return True
else: else:
reason = "Unknown" reason = "Unknown"
for k,v in self.get_control_values().items(): for k, v in self.get_control_values().items():
if k in self.files_control_values: if k in self.files_control_values:
if v != self.files_control_values[k]: if v != self.files_control_values[k]:
reason = "%s was modified"%k reason = "%s was modified" % k
else: else:
reason = "Checksum of file %s is not exist" % k reason = "Checksum of file %s is not exist" % k
self.logger.info("Failed to get cache. Reason: %s" % reason) self.logger.info("Failed to get cache. Reason: %s" % reason)
@ -846,7 +833,7 @@ class EmergeCache(object):
self.files_control_values = {} self.files_control_values = {}
cache_file_lines = readLinesFile(self.cache_file) cache_file_lines = readLinesFile(self.cache_file)
for line in cache_file_lines: for line in cache_file_lines:
if not "=" in line: if "=" not in line:
break break
k, v = line.split('=') k, v = line.split('=')
self.files_control_values[k] = v.strip() self.files_control_values[k] = v.strip()
@ -855,6 +842,7 @@ class EmergeCache(object):
def get_control_values(self): def get_control_values(self):
def generate(): def generate():
for obj in self.check_list: for obj in self.check_list:
for checkvalue in obj.checkvalues(): for check_value in obj.checkvalues():
yield checkvalue yield check_value
return dict(generate()) return dict(generate())

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2014-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,12 +13,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sys import sys
from os import path from os import path
import shutil import shutil
import os from calculate.lib.utils.files import (listDirectory, readFile, readLinesFile,
from calculate.lib.utils.files import listDirectory, readFile, readLinesFile, \ makeDirectory, removeDir)
makeDirectory, removeDir
from calculate.lib.utils.git import Git from calculate.lib.utils.git import Git
from update import UpdateError from update import UpdateError
@ -27,8 +27,17 @@ setLocalTranslate('cl_update3', sys.modules[__name__])
DEFAULT_BRANCH = Git.Reference.Master DEFAULT_BRANCH = Git.Reference.Master
class RepositoryStorageInterface(object):
def __iter__(self):
raise StopIteration
def get_profiles(self, url, branch=DEFAULT_BRANCH):
return []
def get_repository(self, url, branch=DEFAULT_BRANCH):
return None
class RepositoryStorage(object): class RepositoryStorage(RepositoryStorageInterface):
directory = '/tmp' directory = '/tmp'
def __init__(self, directory): def __init__(self, directory):
@ -44,6 +53,10 @@ class RepositoryStorage(object):
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
return [] return []
def get_repository(self, url, branch=DEFAULT_BRANCH):
return None
class ProfileStorage(RepositoryStorage): class ProfileStorage(RepositoryStorage):
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
rep = self.get_repository(url, branch) rep = self.get_repository(url, branch)
@ -54,6 +67,7 @@ class ProfileStorage(RepositoryStorage):
def get_repository(self, url, branch=DEFAULT_BRANCH): def get_repository(self, url, branch=DEFAULT_BRANCH):
return None return None
class LocalStorage(ProfileStorage): class LocalStorage(ProfileStorage):
""" """
Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные
@ -64,7 +78,6 @@ class LocalStorage(ProfileStorage):
if rep.is_like(url, branch): if rep.is_like(url, branch):
return rep return rep
class CacheStorage(ProfileStorage): class CacheStorage(ProfileStorage):
""" """
Хранилище репозиториев, при запросе по урлу смотрит, доступные Хранилище репозиториев, при запросе по урлу смотрит, доступные
@ -78,7 +91,7 @@ class CacheStorage(ProfileStorage):
else: else:
return ProfileRepository.clone(url, self, branch) return ProfileRepository.clone(url, self, branch)
class RepositoryStorageSet(RepositoryStorage): class RepositoryStorageSet(RepositoryStorageInterface):
""" """
Набор хранилищ репозиториев Набор хранилищ репозиториев
""" """

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2014-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from functools import wraps, partial from functools import wraps
import random import random
import sys import sys
@ -52,7 +52,7 @@ from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir,
import emerge_parser import emerge_parser
import logging import logging
from emerge_parser import (EmergeParser, EmergeCommand, EmergeError, from emerge_parser import (EmergeParser, EmergeCommand, EmergeError,
EmergeCache, ChrootEmergeCommand) EmergeCache, Chroot)
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
RegexpLocalization, _) RegexpLocalization, _)
@ -141,8 +141,7 @@ class Update(MethodsInterface):
self.update_map = {} self.update_map = {}
self.refresh_binhost = False self.refresh_binhost = False
@staticmethod def get_prog_path(self, program_name):
def get_prog_path(program_name):
return getProgPath(program_name) return getProgPath(program_name)
def _syncRepository(self, name, url, rpath, revision, def _syncRepository(self, name, url, rpath, revision,
@ -850,11 +849,6 @@ class Update(MethodsInterface):
""" """
Выполнить сборку пакета Выполнить сборку пакета
""" """
if self.clVars.Get('cl_chroot_path') != '/':
command_class = partial(ChrootEmergeCommand,
self.clVars.Get('cl_chroot_path'))
else:
command_class = EmergeCommand
deo = self.clVars.Get('cl_emerge_default_opts') deo = self.clVars.Get('cl_emerge_default_opts')
if not packages: if not packages:
packages = [param] packages = [param]
@ -864,9 +858,14 @@ class Update(MethodsInterface):
if not packages: if not packages:
return True return True
extra_params = [param] extra_params = [param]
with EmergeParser(command_class(list(packages), emerge_default_opts=deo,
extra_params=extra_params, command = EmergeCommand(list(packages), emerge_default_opts=deo,
use=use)) as emerge: extra_params=extra_params,
use=use)
if self.clVars.Get('cl_chroot_path') != '/':
command = Chroot(self.clVars.Get('cl_chroot_path'), command)
with EmergeParser(command) as emerge:
try: try:
emerge.question.action = lambda x: False emerge.question.action = lambda x: False
emerge.run() emerge.run()

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -22,7 +22,6 @@ from calculate.core.server.gen_pid import search_worked_process
from calculate.lib.cl_template import SystemIni from calculate.lib.cl_template import SystemIni
from calculate.lib.utils.content import getCfgFiles from calculate.lib.utils.content import getCfgFiles
from calculate.lib.utils.files import getRunCommands, readFile, writeFile from calculate.lib.utils.files import getRunCommands, readFile, writeFile
import time
class UpdateInfo(object): class UpdateInfo(object):

@ -1,4 +1,4 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015 Calculate Ltd. http://www.calculate-linux.org # Copyright 2015 Calculate Ltd. http://www.calculate-linux.org
# #

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,12 +15,13 @@
# limitations under the License. # limitations under the License.
import sys import sys
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError from calculate.update.update import UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.portage import GitError
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -36,12 +37,11 @@ class ClSetupUpdateAction(Action):
failedMessage = __("Failed to configure the updates autocheck procedure!") failedMessage = __("Failed to configure the updates autocheck procedure!")
interruptMessage = __("Configuration manually interrupted") interruptMessage = __("Configuration manually interrupted")
# список задач для действия # список задач для действия
tasks = [ tasks = [
{'name': 'set_variables', {'name': 'set_variables',
'method': 'Update.setAutocheckParams(cl_update_autocheck_set,' 'method': 'Update.setAutocheckParams(cl_update_autocheck_set,'
'cl_update_autocheck_interval,' 'cl_update_autocheck_interval,'
'cl_update_other_set,' 'cl_update_other_set,'
'cl_update_cleanpkg_set)'} 'cl_update_cleanpkg_set)'}
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,37 +18,27 @@ import sys
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.cl_template import TemplatesError from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.colortext import get_color_print, Colors
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError from calculate.update.update import UpdateError
from calculate.update.emerge_parser import EmergeError from calculate.update.emerge_parser import EmergeError
from calculate.lib.utils.portage import GitError, Eix, EmergeLog, \ from calculate.lib.utils.portage import (GitError, EmergeLog,
EmergeLogNamedTask, PackageList EmergeLogNamedTask, PackageList)
from ..update_tasks import EmergeMark from calculate.update.update_tasks import EmergeMark
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClUpdateAction(Action): class UpdateConditions(object):
""" @staticmethod
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError,
TemplatesError,
GitError, EmergeError)
successMessage = None
failedMessage = None
interruptMessage = __("Update manually interrupted")
def was_installed(pkg, task_name): def was_installed(pkg, task_name):
def func(): def func():
task = EmergeLog(EmergeLogNamedTask(task_name)) task = EmergeLog(EmergeLogNamedTask(task_name))
return bool(PackageList(task.list)[pkg]) return bool(PackageList(task.list)[pkg])
return func return func
@staticmethod
def need_depclean(pkg, task_name): def need_depclean(pkg, task_name):
def func(Get): def func(Get):
task = EmergeLog(EmergeLogNamedTask(task_name)) task = EmergeLog(EmergeLogNamedTask(task_name))
@ -56,14 +46,19 @@ class ClUpdateAction(Action):
or Get('cl_update_outdated_kernel_set') == 'on') or Get('cl_update_outdated_kernel_set') == 'on')
return func return func
def need_upgrade(pkg):
# TODO: возможно функция не работает
def func():
return bool(Eix(pkg, Eix.Option.Upgrade).get_packages())
return func
def pkg_color(text): class ClUpdateAction(Action):
return text """
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError,
TemplatesError,
GitError, EmergeError)
successMessage = None
failedMessage = None
interruptMessage = __("Update manually interrupted")
emerge_tasks = [ emerge_tasks = [
{'name': 'premerge_group', {'name': 'premerge_group',
@ -74,24 +69,24 @@ class ClUpdateAction(Action):
'method': 'Update.premerge("-uDN","--with-bdeps=y","@world")', 'method': 'Update.premerge("-uDN","--with-bdeps=y","@world")',
'condition': lambda Get:Get('cl_update_sync_only_set') == 'off' 'condition': lambda Get:Get('cl_update_sync_only_set') == 'off'
}], }],
}, },
{'name': 'premerge:update', {'name': 'premerge:update',
'condition': lambda Get:Get('cl_update_pretend_set') == 'off', 'condition': lambda Get:Get('cl_update_pretend_set') == 'off',
'depend': Tasks.result("premerge", eq='yes') 'depend': Tasks.result("premerge", eq='yes')
}, },
{'name': 'update_other', {'name': 'update_other',
'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and 'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and
Get('cl_update_sync_only_set') == 'off') Get('cl_update_sync_only_set') == 'off')
}, },
{'name': 'update:update_world', {'name': 'update:update_world',
'group': __("Updating packages"), 'group': __("Updating packages"),
'tasks': [ 'tasks': [
{'name': 'update:update_world', {'name': 'update:update_world',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.emerge("","-uDN","--with-bdeps=y","@world")', 'method': 'Update.emerge("","-uDN","--with-bdeps=y","@world")',
} }
] ]
}, },
{'name': 'update:update_python', {'name': 'update:update_python',
'group': __("Updating Python"), 'group': __("Updating Python"),
'tasks': [ 'tasks': [
@ -99,11 +94,11 @@ class ClUpdateAction(Action):
'message': __('Find & rebuild packages broken due ' 'message': __('Find & rebuild packages broken due '
'to a Python upgrade'), 'to a Python upgrade'),
'method': 'Update.emergelike("python-updater")', 'method': 'Update.emergelike("python-updater")',
'condition': was_installed('dev-lang/python$', 'condition': UpdateConditions.was_installed(
EmergeMark.PythonUpdater), 'dev-lang/python$', EmergeMark.PythonUpdater),
'decoration': 'Update.update_task("%s")' % 'decoration': 'Update.update_task("%s")' %
EmergeMark.PythonUpdater EmergeMark.PythonUpdater
}, },
] ]
}, },
{'name': 'update:update_perl', {'name': 'update:update_perl',
@ -113,8 +108,8 @@ class ClUpdateAction(Action):
'message': __('Find & rebuild packages and Perl header files ' 'message': __('Find & rebuild packages and Perl header files '
'broken due to a perl upgrade'), 'broken due to a perl upgrade'),
'method': 'Update.emergelike("perl-cleaner", "all")', 'method': 'Update.emergelike("perl-cleaner", "all")',
'condition': was_installed('dev-lang/perl$', 'condition': UpdateConditions.was_installed(
EmergeMark.PerlCleaner), 'dev-lang/perl$', EmergeMark.PerlCleaner),
'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner
}, },
] ]
@ -125,7 +120,8 @@ class ClUpdateAction(Action):
{'name': 'update_other:update_depclean', {'name': 'update_other:update_depclean',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.depclean()', 'method': 'Update.depclean()',
'condition': need_depclean('.*', EmergeMark.Depclean), 'condition': UpdateConditions.need_depclean(
'.*', EmergeMark.Depclean),
'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean 'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean
}, },
] ]
@ -136,38 +132,40 @@ class ClUpdateAction(Action):
{'name': 'update_other:module_rebuild', {'name': 'update_other:module_rebuild',
'message': __('Updating Kernel modules'), 'message': __('Updating Kernel modules'),
'method': 'Update.emerge("","@module-rebuild")', 'method': 'Update.emerge("","@module-rebuild")',
'condition': was_installed('sys-kernel/.*source', 'condition': UpdateConditions.was_installed(
EmergeMark.KernelModules), 'sys-kernel/.*source', EmergeMark.KernelModules),
'decoration': 'Update.update_task("%s")' % 'decoration': 'Update.update_task("%s")' %
EmergeMark.KernelModules EmergeMark.KernelModules
}, },
{'name': 'update_other:x11_module_rebuild', {'name': 'update_other:x11_module_rebuild',
'message': __('Updating X.Org server modules'), 'message': __('Updating X.Org server modules'),
'method': 'Update.emerge("","@x11-module-rebuild")', 'method': 'Update.emerge("","@x11-module-rebuild")',
'condition': was_installed('x11-base/xorg-server', 'condition': UpdateConditions.was_installed(
EmergeMark.XorgModules), 'x11-base/xorg-server', EmergeMark.XorgModules),
'decoration': 'Update.update_task("%s")' % 'decoration': 'Update.update_task("%s")' %
EmergeMark.XorgModules EmergeMark.XorgModules
}, },
{'name': 'update_other:preserved_rebuild', {'name': 'update_other:preserved_rebuild',
'message': __('Updating preserved libraries'), 'message': __('Updating preserved libraries'),
'method': 'Update.emerge("","@preserved-rebuild")', 'method': 'Update.emerge("","@preserved-rebuild")',
'condition': was_installed('.*', EmergeMark.PreservedLibs), 'condition': UpdateConditions.was_installed(
'.*', EmergeMark.PreservedLibs),
'decoration': 'Update.update_task("%s")' % 'decoration': 'Update.update_task("%s")' %
EmergeMark.PreservedLibs EmergeMark.PreservedLibs
}, },
{'name': 'update_other:revdev_rebuild', {'name': 'update_other:revdev_rebuild',
'message': __('Checking reverse dependencies'), 'message': __('Checking reverse dependencies'),
'method': 'Update.revdep_rebuild("revdep-rebuild")', 'method': 'Update.revdep_rebuild("revdep-rebuild")',
'condition': lambda Get:(Get('cl_update_skip_rb_set') == 'off' 'condition': lambda Get: (Get(
and ClUpdateAction.was_installed('.*', 'cl_update_skip_rb_set') == 'off' and
EmergeMark.RevdepRebuild)()), UpdateConditions.was_installed(
'.*', EmergeMark.RevdepRebuild)()),
'decoration': 'Update.update_task("%s")' % 'decoration': 'Update.update_task("%s")' %
EmergeMark.RevdepRebuild EmergeMark.RevdepRebuild
}, },
{'name': 'update_other:dispatch_conf_end', {'name': 'update_other:dispatch_conf_end',
'message': __("Updating configuration files"), 'message': __("Updating configuration files"),
'method':'Update.dispatchConf()', 'method': 'Update.dispatchConf()',
'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
Get('cl_update_pretend_set') == 'off') Get('cl_update_pretend_set') == 'off')
}, },
@ -305,18 +303,16 @@ class ClUpdateAction(Action):
Tasks.success_all("check_schedule")))}, Tasks.success_all("check_schedule")))},
{'name': 'failed', {'name': 'failed',
'depend': Tasks.failed_all("check_schedule") 'depend': Tasks.failed_all("check_schedule")
}, },
# сообщение удачного завершения при обновлении ревизии # сообщение удачного завершения при обновлении ревизии
{'name': 'success_rev', {'name': 'success_rev',
'message': __("System update finished!"), 'message': __("System update finished!"),
'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and 'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and
Get('cl_update_pretend_set') == 'off') Get('cl_update_pretend_set') == 'off')
}, },
# сообщение удачного завершения при пересоздании world # сообщение удачного завершения при пересоздании world
{'name': 'success_world', {'name': 'success_world',
'message': __("World rebuild finished!"), 'message': __("World rebuild finished!"),
'condition': lambda Get: Get('cl_rebuild_world_set') == 'on' 'condition': lambda Get: Get('cl_rebuild_world_set') == 'on'
}, },
] ]
was_installed = staticmethod(was_installed)

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError from calculate.update.update import UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.portage import GitError
_ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -39,7 +40,6 @@ class ClUpdateProfileAction(Action):
failedMessage = __("Failed to update the profile") failedMessage = __("Failed to update the profile")
interruptMessage = __("Profile update manually interrupted") interruptMessage = __("Profile update manually interrupted")
# список задач для действия # список задач для действия
tasks = [ tasks = [
{'name': 'migrate_repository', {'name': 'migrate_repository',
@ -51,18 +51,18 @@ class ClUpdateProfileAction(Action):
Get('cl_update_profile_storage').is_local( Get('cl_update_profile_storage').is_local(
Get('cl_update_profile_url'), Get('cl_update_profile_url'),
Get('cl_update_profile_branch'))) Get('cl_update_profile_branch')))
}, },
{'name': 'reconfigure_vars1', {'name': 'reconfigure_vars1',
'method': 'Update.invalidateVariables("cl_update_profile_storage")', 'method': 'Update.invalidateVariables("cl_update_profile_storage")',
'depend': Tasks.has('migrate_repository') 'depend': Tasks.has('migrate_repository')
}, },
{'name': 'drop_binhosts', {'name': 'drop_binhosts',
'method': 'Update.drop_binhosts(update.cl_update_profile_datavars)' 'method': 'Update.drop_binhosts(update.cl_update_profile_datavars)'
}, },
{'name': 'reconfigure_vars', {'name': 'reconfigure_vars',
'method': 'Update.reconfigureProfileVars(cl_update_profile_datavars,' 'method': 'Update.reconfigureProfileVars(cl_update_profile_datavars,'
'cl_chroot_path)' 'cl_chroot_path)'
}, },
{'name': 'reps_synchronization', {'name': 'reps_synchronization',
'group': __("Repositories synchronization"), 'group': __("Repositories synchronization"),
'tasks': [ 'tasks': [
@ -70,8 +70,9 @@ class ClUpdateProfileAction(Action):
'foreach': 'cl_update_profile_sync_rep', 'foreach': 'cl_update_profile_sync_rep',
'message': __("Syncing the {eachvar:capitalize} repository"), 'message': __("Syncing the {eachvar:capitalize} repository"),
'method': 'Update.syncRepositories(eachvar)', 'method': 'Update.syncRepositories(eachvar)',
#'condition': lambda Get: Get('cl_update_profile_sync_rep') # TODO: неиспользуемое условие
}, # 'condition': lambda Get: Get('cl_update_profile_sync_rep')
},
{'name': 'sync_reps:regen_cache', {'name': 'sync_reps:regen_cache',
'foreach': 'cl_update_sync_overlay_rep', 'foreach': 'cl_update_sync_overlay_rep',
'message': __("Updating the {eachvar:capitalize} repository cache"), 'message': __("Updating the {eachvar:capitalize} repository cache"),
@ -81,7 +82,7 @@ class ClUpdateProfileAction(Action):
lambda Get: (Get('cl_update_outdate_set') == 'on' and lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force')) Get('cl_update_metadata_force') == 'force'))
}, },
{'name': 'emerge_metadata', {'name': 'emerge_metadata',
'message': __("Metadata transfer"), 'message': __("Metadata transfer"),
'method': 'Update.emergeMetadata()', 'method': 'Update.emergeMetadata()',
@ -89,7 +90,7 @@ class ClUpdateProfileAction(Action):
lambda Get: (Get('cl_update_outdate_set') == 'on' and lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force')) Get('cl_update_metadata_force') == 'force'))
}, },
{'name': 'eix_update', {'name': 'eix_update',
'message': __("Updating the eix cache"), 'message': __("Updating the eix cache"),
'method': 'Update.eixUpdate(cl_repository_name)', 'method': 'Update.eixUpdate(cl_repository_name)',
@ -97,7 +98,7 @@ class ClUpdateProfileAction(Action):
lambda Get: (Get('cl_update_outdate_set') == 'on' and lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or Get('cl_update_eixupdate_force') != 'skip' or
Get('cl_update_eixupdate_force') == 'force')) Get('cl_update_eixupdate_force') == 'force'))
}, },
# сообщение удачного завершения при обновлении репозиториев # сообщение удачного завершения при обновлении репозиториев
{'name': 'success_syncrep', {'name': 'success_syncrep',
'message': __("Synchronization finished"), 'message': __("Synchronization finished"),
@ -107,32 +108,33 @@ class ClUpdateProfileAction(Action):
"eix_update")), "eix_update")),
} }
] ]
}, },
{'name': 'reps_synchronization', {'name': 'reps_synchronization',
'group': __("Setting up the profile"), 'group': __("Setting up the profile"),
'tasks': [ 'tasks': [
{'name': 'set_profile', {'name': 'set_profile',
'message': __("Switching to profile {cl_update_profile_system}"), 'message': __("Switching to profile {cl_update_profile_system}"),
'method': 'Update.setProfile(cl_update_profile_system)' 'method': 'Update.setProfile(cl_update_profile_system)'
}, },
{'name': 'revision', {'name': 'revision',
'message': __("Fixing the settings"), 'message': __("Fixing the settings"),
'method': 'Update.applyProfileTemplates(cl_template_clt_set,' 'method': 'Update.applyProfileTemplates(cl_template_clt_set,'
'True,False,"update_profile")', 'True,False,"update_profile")',
'condition': lambda Get: Get('cl_templates_locate') 'condition': lambda Get: Get('cl_templates_locate')
}, },
{'name': 'reconfigure', {'name': 'reconfigure',
'message': __("The system is being configured"), 'message': __("The system is being configured"),
'method': 'Update.applyProfileTemplates(cl_template_clt_set,' 'method': 'Update.applyProfileTemplates(cl_template_clt_set,'
'True,False,"merge")', 'True,False,"merge")',
'condition': lambda Get: (Get('cl_update_templates_locate') and 'condition': lambda Get: (
Get('cl_update_skip_setup_set') == 'off') Get('cl_update_templates_locate') and
}, Get('cl_update_skip_setup_set') == 'off')
{'name': 'dispatch_conf', },
'message': __("Updating configuration files"), {'name': 'dispatch_conf',
'method':'Update.dispatchConf()', 'message': __("Updating configuration files"),
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip' 'method': 'Update.dispatchConf()',
}, 'condition': lambda Get: Get('cl_dispatch_conf') != 'skip'
},
] ]
} }
] ]

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,10 +14,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from calculate.lib.datavars import ReadonlyVariable
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_update3',sys.modules[__name__]) setLocalTranslate('cl_update3',sys.modules[__name__])

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,18 +19,17 @@ import sys
import re import re
from os import path from os import path
from calculate.lib.datavars import (Variable, VariableError, from calculate.lib.datavars import (Variable, VariableError,
ReadonlyVariable, ReadonlyTableVariable, TableVariable, FieldValue, ReadonlyVariable, ReadonlyTableVariable,
SimpleDataVars, DataVarsError) TableVariable, FieldValue,
from calculate.lib.utils.files import readFile, \ SimpleDataVars, DataVarsError)
listDirectory, process, pathJoin from calculate.lib.utils.files import readFile, listDirectory, process, pathJoin
from calculate.lib.utils.git import Git
from calculate.lib.configparser import ConfigParser from calculate.lib.configparser import ConfigParser
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
from calculate.lib.utils.text import simplify_profiles from calculate.lib.utils.text import simplify_profiles
from calculate.lib.utils.portage import Git, GitError, Layman from calculate.lib.utils.portage import Git, GitError, Layman
from ..profile import RepositoryStorageSet, DEFAULT_BRANCH, \ from ..profile import (RepositoryStorageSet, DEFAULT_BRANCH,
LocalStorage, ProfileRepository, CacheStorage LocalStorage, ProfileRepository, CacheStorage)
from calculate.lib.variables import linux as lib_linux from calculate.lib.variables import linux as lib_linux
from calculate.lib.variables import env from calculate.lib.variables import env
@ -38,7 +37,7 @@ from calculate.update.update_info import UpdateInfo
import urllib2 import urllib2
import time import time
_ = lambda x:x _ = lambda x: x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
@ -552,7 +551,7 @@ class VariableClUpdateOtherRepData(ReadonlyTableVariable):
if rname in layman_overlays and rname not in repNames: if rname in layman_overlays and rname not in repNames:
yield (rname, rpath) yield (rname, rpath)
def get(self): def get(self, hr=False):
return list(self.generator()) return list(self.generator())
class VariableClUpdateOtherRepName(FieldValue,ReadonlyVariable): class VariableClUpdateOtherRepName(FieldValue,ReadonlyVariable):

@ -1,6 +1,6 @@
#-*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2010-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,17 +16,18 @@
import sys import sys
from calculate.lib.datavars import VariableError,DataVarsError,DataVars from calculate.lib.datavars import VariableError,DataVarsError
from calculate.core.server.func import WsdlBase from calculate.core.server.func import WsdlBase
from calculate.install.install import InstallError from calculate.install.install import InstallError
from calculate.update.update import Update,UpdateError from calculate.update.update import Update, UpdateError
from calculate.lib.utils.portage import GitError from calculate.lib.utils.portage import GitError
from utils.cl_update import ClUpdateAction from utils.cl_update import ClUpdateAction
from utils.cl_update_profile import ClUpdateProfileAction from utils.cl_update_profile import ClUpdateProfileAction
from utils.cl_setup_update import ClSetupUpdateAction from utils.cl_setup_update import ClSetupUpdateAction
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_update3',sys.modules[__name__])
setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)

Loading…
Cancel
Save