예제 #1
0
파일: apkinfo.py 프로젝트: workos/winterpy
def apkinfo(apk):
    with tempfile.TemporaryDirectory('apk') as tempdir:
        try:
            run(["apktool", "d", "-f", "-s", apk, "-o", tempdir])
        except CalledProcessError:
            raise ApktoolFailed

        with at_dir(tempdir):
            manifest = ET.parse('AndroidManifest.xml').getroot()
            package_id = manifest.get('package')
            package_ver = manifest.get(VER_ATTR)

            app = manifest.find('application')
            icon = app.get(ICON_ATTR)
            name = app.get(NAME_ATTR)

            if os.path.isdir('res'):
                with at_dir('res'):
                    name = read_string(name)
                    package_ver = read_string(package_ver)

                    if icon and icon.startswith('@'):
                        dirname, iconname = icon[1:].split('/', 1)
                        iconfile = firstExistentPath(
                            '%s/%s.png' % (d, iconname)
                            for d in (dirname + x
                                      for x in ('-xxhdpi', '-xhdpi', '-hdpi',
                                                '', '-nodpi', '-xxhdpi-v4',
                                                '-xhdpi-v4', '-hdpi-v4', '-v4',
                                                '-nodpi-v4')))
                        with open(iconfile, 'rb') as f:
                            icon = f.read()

        return ApkInfo(package_id, package_ver, name, icon)
예제 #2
0
파일: api.py 프로젝트: a-wing/lilac
def _update_aur_repo_real(pkgname: str) -> None:
    aurpath = const.AUR_REPO_DIR / pkgname
    if not os.path.isdir(aurpath):
        logger.info('cloning AUR repo: %s', aurpath)
        with at_dir(const.AUR_REPO_DIR):
            run_cmd(['git', 'clone', '[email protected]:%s.git' % pkgname])
    else:
        with at_dir(aurpath):
            git_reset_hard()
            git_pull()

    logger.info('copying files to AUR repo: %s', aurpath)
    files = run_cmd(['git', 'ls-files']).splitlines()
    for f in files:
        if f in const.SPECIAL_FILES:
            continue
        logger.debug('copying file %s', f)
        shutil.copy(f, aurpath)

    with at_dir(aurpath):
        with open('.SRCINFO', 'wb') as srcinfo:
            subprocess.run(
                ['makepkg', '--printsrcinfo'],
                stdout=srcinfo,
                check=True,
            )
        run_cmd(['git', 'add', '.'])
        run_cmd([
            'bash', '-c',
            'git diff-index --quiet HEAD || git commit -m "update by lilac"'
        ])
        run_cmd(['git', 'push'])
예제 #3
0
def _update_aur_repo_real(pkgname):
    aurpath = os.path.join(AUR_REPO_DIR, pkgname)
    if not os.path.isdir(aurpath):
        logger.info('cloning AUR repo: %s', aurpath)
        with at_dir(AUR_REPO_DIR):
            run_cmd(['git', 'clone', '[email protected]:%s.git' % pkgname])
    else:
        with at_dir(aurpath):
            git_reset_hard()
            git_pull()

    logger.info('copying files to AUR repo: %s', aurpath)
    files = run_cmd(['git', 'ls-files']).splitlines()
    for f in files:
        if f in SPECIAL_FILES:
            continue
        logger.debug('copying file %s', f)
        shutil.copy(f, aurpath)

    with at_dir(aurpath):
        with open('.SRCINFO', 'wb') as srcinfo:
            subprocess.run(
                ['makepkg', '--printsrcinfo'],
                stdout=srcinfo,
                check=True,
            )
        run_cmd(['git', 'add', '.'])
        run_cmd(['git', 'commit', '-m', 'update by lilac'])
        run_cmd(['git', 'push'])
예제 #4
0
파일: apkinfo.py 프로젝트: SevenHe/winterpy
def apkinfo(apk):
  with tempfile.TemporaryDirectory('apk') as tempdir:
    try:
      run(["apktool", "d", "-f", "-s", apk, tempdir])
    except CalledProcessError:
      raise ApktoolFailed

    with at_dir(tempdir):
      manifest = ET.parse('AndroidManifest.xml').getroot()
      package_id = manifest.get('package')
      package_ver = manifest.get(VER_ATTR)

      app = manifest.find('application')
      icon = app.get(ICON_ATTR)
      name = app.get(NAME_ATTR)

      if os.path.isdir('res'):
        with at_dir('res'):
          name = read_string(name)
          package_ver = read_string(package_ver)

          if icon and icon.startswith('@'):
            dirname, iconname = icon[1:].split('/', 1)
            iconfile = firstExistentPath(
              '%s/%s.png' % (d, iconname) for d in
              (dirname + x for x in
               ('-xxhdpi', '-xhdpi', '-hdpi', '', '-nodpi'))
            )
            with open(iconfile, 'rb') as f:
              icon = f.read()

    return ApkInfo(package_id, package_ver, name, icon)
예제 #5
0
파일: api.py 프로젝트: farseerfc/lilac
def _update_aur_repo_real(pkgname: str) -> None:
  aurpath = const.AUR_REPO_DIR / pkgname
  if not os.path.isdir(aurpath):
    logger.info('cloning AUR repo: %s', aurpath)
    with at_dir(const.AUR_REPO_DIR):
      run_cmd(['git', 'clone', '[email protected]:%s.git' % pkgname])
  else:
    with at_dir(aurpath):
      git_reset_hard()
      git_pull()

  logger.info('copying files to AUR repo: %s', aurpath)
  files = run_cmd(['git', 'ls-files']).splitlines()
  for f in files:
    if f in const.SPECIAL_FILES:
      continue
    logger.debug('copying file %s', f)
    shutil.copy(f, aurpath)

  with at_dir(aurpath):
    with open('.SRCINFO', 'wb') as srcinfo:
      subprocess.run(
        ['makepkg', '--printsrcinfo'],
        stdout = srcinfo,
        check = True,
      )
    run_cmd(['git', 'add', '.'])
    run_cmd(['bash', '-c', 'git diff-index --quiet HEAD || git commit -m "update by lilac"'])
    run_cmd(['git', 'push'])
예제 #6
0
파일: api.py 프로젝트: DDoSolitary/lilac
def _update_aur_repo_real(pkgname: str) -> None:
    aurpath = const.AUR_REPO_DIR / pkgname
    if not aurpath.is_dir():
        logger.info('cloning AUR repo: %s', aurpath)
        with at_dir(const.AUR_REPO_DIR):
            run_cmd(['git', 'clone', f'[email protected]:{pkgname}.git'])
    else:
        with at_dir(aurpath):
            # reset everything, dropping local commits
            run_cmd(['git', 'reset', '--hard', 'origin/master'])
            git_pull()

    with at_dir(aurpath):
        oldfiles = set(run_cmd(['git', 'ls-files']).splitlines())

    newfiles = set()
    logger.info('copying files to AUR repo: %s', aurpath)
    files = run_cmd(['git', 'ls-files']).splitlines()
    for f in files:
        if f in SPECIAL_FILES:
            continue
        logger.debug('copying file %s', f)
        shutil.copy(f, aurpath)
        newfiles.add(f)

    with at_dir(aurpath):
        for f in oldfiles - newfiles:
            if f in ['.SRCINFO', '.gitignore']:
                continue
            logger.debug('removing file %s', f)
            try:
                os.unlink(f)
            except OSError as e:
                logger.warning('failed to remove file %s: %s', f, e)

        if not _allow_update_aur_repo(pkgname, run_cmd(['git', 'diff'])):
            return

        with open('.SRCINFO', 'wb') as srcinfo:
            subprocess.run(
                ['makepkg', '--printsrcinfo'],
                stdout=srcinfo,
                check=True,
            )
        run_cmd(['git', 'add', '.'])
        p = subprocess.run(['git', 'diff-index', '--quiet', 'HEAD'])
        if p.returncode != 0:
            built_version = _format_package_version(_G.epoch, _G.pkgver,
                                                    _G.pkgrel)
            msg = f'[lilac] updated to {built_version}'
            run_cmd(['git', 'commit', '-m', msg])
            run_cmd(['git', 'push'])
예제 #7
0
def test_update_pkgrel(tmpdir, pkgbuild, expected_pkgbuild, kwargs):
  with at_dir(tmpdir):
    with open('PKGBUILD', 'w') as f:
      f.write(pkgbuild)
    update_pkgrel(**kwargs)
    with open('PKGBUILD', 'r') as f:
      new_pkgbuild = f.read()
    assert new_pkgbuild == expected_pkgbuild
예제 #8
0
def test_update_pkgrel(tmpdir, pkgbuild, expected_pkgbuild, kwargs):
    with at_dir(tmpdir):
        with open('PKGBUILD', 'w') as f:
            f.write(pkgbuild)
        update_pkgrel(**kwargs)
        with open('PKGBUILD', 'r') as f:
            new_pkgbuild = f.read()
        assert new_pkgbuild == expected_pkgbuild
예제 #9
0
def apkinfo(apk):
    with tempfile.TemporaryDirectory("apk") as tempdir:
        try:
            run(["apktool", "d", "-f", "-s", apk, "-o", tempdir])
        except CalledProcessError:
            raise ApktoolFailed

        with at_dir(tempdir):
            manifest = ET.parse("AndroidManifest.xml").getroot()
            package_id = manifest.get("package")
            package_ver = manifest.get(VER_ATTR)

            app = manifest.find("application")
            icon = app.get(ICON_ATTR)
            name = app.get(NAME_ATTR)

            if os.path.isdir("res"):
                with at_dir("res"):
                    name = read_string(name)
                    package_ver = read_string(package_ver)

                    if icon and icon.startswith("@"):
                        dirname, iconname = icon[1:].split("/", 1)
                        iconfile = firstExistentPath(
                            "%s/%s.png" % (d, iconname)
                            for d in (
                                dirname + x
                                for x in (
                                    "-xxhdpi",
                                    "-xhdpi",
                                    "-hdpi",
                                    "",
                                    "-nodpi",
                                    "-xxhdpi-v4",
                                    "-xhdpi-v4",
                                    "-hdpi-v4",
                                    "-v4",
                                    "-nodpi-v4",
                                )
                            )
                        )
                        with open(iconfile, "rb") as f:
                            icon = f.read()

        return ApkInfo(package_id, package_ver, name, icon)
예제 #10
0
    def find_maintainer_or_admin(self, package=None):
        if package is not None:
            path = os.path.join(self.repodir, package)
        else:
            path = '.'

        with at_dir(path):
            try:
                who = self.find_maintainer()
                more = ''
            except:
                who = self.mymaster
                more = traceback.format_exc()

        return who, more
예제 #11
0
  def _find_local_package(self):
    with at_dir(self.directory):
      fnames = [x for x in os.listdir() if x.endswith('.pkg.tar.xz')]
      pkgs = []
      for x in fnames:
        info = archpkg.PkgNameInfo.parseFilename(x)
        if info.name == self.pkgname:
          pkgs.append(x)

      if len(pkgs) == 1:
        return os.path.abspath(pkgs[0])
      elif not pkgs:
        raise FileNotFoundError
      else:
        ret = sorted(
          pkgs, reverse=True, key=lambda n: os.stat(n).st_mtime)[0]
        return os.path.abspath(ret)
예제 #12
0
파일: lilaclib.py 프로젝트: cuihaoleo/lilac
  def _find_local_package(self):
    with at_dir(self.directory):
      fnames = [x for x in os.listdir() if x.endswith('.pkg.tar.xz')]
      pkgs = []
      for x in fnames:
        info = archpkg.PkgNameInfo.parseFilename(x)
        if info.name == self.pkgname:
          pkgs.append(x)

      if len(pkgs) == 1:
        return os.path.abspath(pkgs[0])
      elif not pkgs:
        raise FileNotFoundError
      else:
        ret = sorted(
          pkgs, reverse=True, key=lambda n: os.stat(n).st_mtime)[0]
        return os.path.abspath(ret)
예제 #13
0
def load_all(repodir):
    repodir = pathlib.Path(repodir)
    mods = {}
    errors = {}

    for x in repodir.iterdir():
        if not x.is_dir():
            continue

        if x.name[0] == '.':
            continue

        with at_dir(x):
            try:
                with load_lilac() as mod:
                    mods[x.name] = mod
            except FileNotFoundError:
                pass
            except Exception:
                errors[x.name] = sys.exc_info()

    return mods, errors
예제 #14
0
def load_all(repodir):
    mods = {}
    errors = {}

    for x in repodir.iterdir():
        if not x.is_dir():
            continue

        if x.name[0] == '.':
            continue

        with at_dir(x):
            try:
                with load_lilac() as mod:
                    mods[x.name] = mod
                if hasattr(mod,
                           'time_limit_hours') and mod.time_limit_hours < 0:
                    raise ValueError('time_limit_hours should be positive.')
            except FileNotFoundError:
                pass
            except Exception:
                errors[x.name] = sys.exc_info()

    return mods, errors
예제 #15
0
def packages_need_update(repo, U):
    full = configparser.ConfigParser(dict_type=dict, allow_no_value=True)
    nvchecker_full = repo.repodir / 'nvchecker.ini'
    try:
        full.read([nvchecker_full])
    except Exception:
        tb = traceback.format_exc()
        try:
            who = repo.find_maintainer(file='nvchecker.ini')
            more = ''
        except Exception:
            who = repo.mymaster
            more = traceback.format_exc()

        subject = 'nvchecker 配置文件错误'
        msg = '调用栈如下:\n\n' + tb
        if more:
            msg += '\n获取维护者信息也失败了!调用栈如下:\n\n' + more
        repo.sendmail(who, subject, msg)
        raise

    all_known = set(full.sections())
    unknown = U - all_known
    if unknown:
        logger.warn('unknown packages: %r', unknown)

    if not OLDVER_FILE.exists():
        open(OLDVER_FILE, 'a').close()

    newconfig = {k: full[k] for k in U & all_known}
    newconfig['__config__'] = {
        'oldver': OLDVER_FILE,
        'newver': NEWVER_FILE,
    }
    new = configparser.ConfigParser(dict_type=dict, allow_no_value=True)
    new.read_dict(newconfig)
    with open(NVCHECKER_FILE, 'w') as f:
        new.write(f)

    # vcs source needs to be run in the repo, so cwd=...
    rfd, wfd = os.pipe()
    cmd = [
        'nvchecker', '--logger', 'both', '--json-log-fd',
        str(wfd), NVCHECKER_FILE
    ]
    process = subprocess.Popen(cmd, cwd=repo.repodir, pass_fds=(wfd, ))
    os.close(wfd)

    output = os.fdopen(rfd)
    nvdata = {}
    errors = defaultdict(list)
    for l in output:
        j = json.loads(l)
        pkg = j.get('name')
        event = j['event']
        if event == 'updated':
            nvdata[pkg] = NvResult(j['old_version'], j['version'])
        elif event == 'up-to-date':
            nvdata[pkg] = NvResult(j['version'], j['version'])
        elif j['level'] in ['warn', 'error', 'exception', 'critical']:
            errors[pkg].append(j)

    ret = process.wait()
    if ret != 0:
        raise subprocess.CalledProcessError(ret, cmd)

    missing = []
    error_owners = defaultdict(list)
    for pkg, pkgerrs in errors.items():
        if pkg is None:
            continue

        dir = repo.repodir / pkg
        if not dir.is_dir():
            missing.append(pkg)
            continue

        with at_dir(dir):
            who = repo.find_maintainer()
        error_owners[who].extend(pkgerrs)

    for who, errors in error_owners.items():
        logger.info('send nvchecker report for %r packages to %s',
                    {x['name']
                     for x in errors}, who)
        repo.sendmail(who, '[lilac] nvchecker 错误报告',
                      '\n'.join(_format_error(e) for e in errors))

    if unknown or None in errors or missing:
        subject = 'nvchecker 问题'
        msg = ''
        if unknown:
            msg += '以下软件包没有相应的更新配置信息:\n\n' + ''.join(
                x + '\n' for x in sorted(unknown)) + '\n'
        if None in errors:
            msg += '在更新检查时出现了一些错误:\n\n' + '\n'.join(
                _format_error(e) for e in errors[None]) + '\n'
        if missing:
            msg += '以下软件包没有所对应的目录:\n\n' + \
                '\n'.join( missing) + '\n'
        repo.send_repo_mail(subject, msg)

    for name in U:
        if name not in nvdata:
            # we know nothing about these versions
            # maybe nvchecker has failed
            nvdata[name] = NvResult(None, None)

    return nvdata, unknown