|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2015-2016 Mir Calculate. 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 re
|
|
|
import os
|
|
|
from os import path
|
|
|
from itertools import chain, groupby
|
|
|
import time
|
|
|
|
|
|
from calculate.lib.datavars import DataVars
|
|
|
from calculate.lib.cl_template import templateFunction
|
|
|
from calculate.lib.utils.files import readFile, writeFile
|
|
|
|
|
|
get_pkgname_by_filename = templateFunction.get_pkgname_by_filename
|
|
|
|
|
|
|
|
|
class Cache():
|
|
|
reMerge = re.compile("(merge|mergepkg)\(([-\w/]*)(?:\[[^\]]\])?\)[-!=<>]")
|
|
|
rePatch = re.compile("^#\s*Calculate.*ac_install_patch==on")
|
|
|
|
|
|
PATCH_TYPE = "patch"
|
|
|
MERGE_TYPE = "merge"
|
|
|
DIRECTORY_TEMPLATE = ".calculate_directory"
|
|
|
CLT_SUFFIX = ".clt"
|
|
|
|
|
|
def __init__(self, dv=None):
|
|
|
if dv is None:
|
|
|
dv = DataVars()
|
|
|
dv.importData()
|
|
|
dv.flIniFile()
|
|
|
self.dv = dv
|
|
|
self.base_dn = "/var/lib/calculate/calculate-core/cache"
|
|
|
self.fn_mtime = path.join(self.base_dn, "merge.mtime")
|
|
|
self.fn_patch = path.join(self.base_dn, "merge-patch.list")
|
|
|
self.fn_setup = path.join(self.base_dn, "merge-setup.list")
|
|
|
|
|
|
def search_merge(self, dn):
|
|
|
"""
|
|
|
Сканировать директорию с шаблонами
|
|
|
"""
|
|
|
patch_dirs = []
|
|
|
for root, dirs, files in os.walk(dn):
|
|
|
for fn in (path.join(root, x) for x in files):
|
|
|
data = readFile(fn)
|
|
|
if self.rePatch.search(data):
|
|
|
if path.basename(fn) == self.DIRECTORY_TEMPLATE:
|
|
|
patch_dirs.append(path.dirname(fn))
|
|
|
patch_template = True
|
|
|
else:
|
|
|
if any(fn.startswith(x) for x in patch_dirs):
|
|
|
patch_template = True
|
|
|
else:
|
|
|
patch_template = False
|
|
|
for fname, pkg in self.reMerge.findall(data):
|
|
|
pkg = pkg or get_pkgname_by_filename(fn)
|
|
|
yield (self.PATCH_TYPE if patch_template
|
|
|
else self.MERGE_TYPE, pkg)
|
|
|
|
|
|
def search_merge_clt(self, dn):
|
|
|
"""
|
|
|
Сканировать clt шаблоны
|
|
|
"""
|
|
|
for root, dirs, files in os.walk(dn):
|
|
|
for fn in (path.join(root, x) for x in files
|
|
|
if x.endswith(self.CLT_SUFFIX)):
|
|
|
data = readFile(fn)
|
|
|
for fname, pkg in self.reMerge.findall(data):
|
|
|
pkg = pkg or get_pkgname_by_filename(fn)
|
|
|
yield (self.MERGE_TYPE, pkg)
|
|
|
|
|
|
@staticmethod
|
|
|
def check_new_that(mtime_fn, dirs, fn_filter=None):
|
|
|
"""
|
|
|
Проверить появились ли новые файлы после последней проверки
|
|
|
"""
|
|
|
if not path.exists(mtime_fn):
|
|
|
return True
|
|
|
check_mtime = os.stat(mtime_fn).st_mtime
|
|
|
for dn in dirs:
|
|
|
for root, dirs, files in os.walk(dn):
|
|
|
for fn in (path.join(root, x) for x in files
|
|
|
if fn_filter is None or fn_filter(x)):
|
|
|
if os.stat(fn).st_mtime > check_mtime:
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
def update(self, force=False):
|
|
|
template_path = self.dv.Get('main.cl_template_path')
|
|
|
if (force or
|
|
|
self.check_new_that(
|
|
|
self.fn_mtime, ['/etc'],
|
|
|
fn_filter=lambda x: x.endswith(self.CLT_SUFFIX)) or
|
|
|
self.check_new_that(self.fn_mtime, template_path)):
|
|
|
all_packages = chain(self.search_merge_clt('/etc'),
|
|
|
*[self.search_merge(x) for x in template_path])
|
|
|
for _type, pkgs in groupby(sorted(all_packages), lambda x: x[0]):
|
|
|
list_packages = sorted(set(y for x, y in pkgs))
|
|
|
if _type == self.MERGE_TYPE:
|
|
|
with writeFile(self.fn_setup) as f:
|
|
|
f.write("\n".join(list_packages))
|
|
|
if _type == self.PATCH_TYPE:
|
|
|
with writeFile(self.fn_patch) as f:
|
|
|
f.write("\n".join(list_packages))
|
|
|
with writeFile(self.fn_mtime) as f:
|
|
|
f.write(str(time.time()))
|