前回、
スクリプトの基本アイデア
前回も触れたように、
Pythonの
Plamo Linuxの各パッケージは"bash-4.
これらのデータを管理するために、
pkgname = []
...
pkgname.append('bash')
version['bash'] = '4.2.53'
build['bash'] = 'P1'
...
しかし、
「タプル」
package['bash'] = ('4.2.53, 'P1')
package['bc'] = ('1.06.95', 'P2')
...
加えてPythonには、
辞書や連想配列と呼ばれるデータ構造では、
たとえば、
import pickle
...
with open('data.pickle', 'wb') as f:
pickle.dump(ftp_package, f)
こうして作ったdata.
import pickle
...
with open('data.pickle', 'rb') as f:
ftp_package = pickle.load(f)
タプルにまとめたパッケージの情報を辞書に整理し、
スクリプトの解説
前節で紹介したように今回のスクリプトでは、
そのため、
1 #! /usr/bin/python
2 # -*- coding: euc-jp -*-
3
4 import os
5 import pickle
6
7 basedir = '/home/ftp/pub/Plamo-5.x/'
8 archdir = ('x86', 'x86_64')
9
10 for arch in archdir:
11 pkg_path = basedir + arch + "/plamo/"
12 for root, dirs, files in os.walk(pkg_path):
13 if 'old' in dirs:
14 dirs.remove('old')
15
16 for j in files:
17 if j.find(".txz") > 0 or j.find(".tgz") > 0:
18 (base, vers, p_arch, tmp) = j.split("-")
19 (build, ext) = tmp.split(".")
20 r_path = root.replace(basedir, "")
21 data_t = (vers, p_arch, build, ext, r_path)
22 allpkgs[base] = data_t
23
24 pickle_name = "allpkgs_" + arch + ".pickle"
25 with open(pickle_name, 'wb') as f:
26 pickle.dump(allpkgs, f)
9行目までは文字コードやモジュール読み込み、
10行目からのループでは、
何度か例にあげた"bash-4.
allpkgs['bash'] = ('4.2.53', 'x86_64', 'P1', 'txz', 'x86_64/plamo/00_base/')
と記録されるわけです。
24行目からはこうして整理したデータをpickleで保存する処理で、
このファイルを用いてローカルにインストール済みのパッケージと比較するスクリプトはこんな風にしてみました。こちらは少し長いので適宜省略しつつ紹介します。
1 #! /usr/bin/python2
2 # -*- coding: euc-jp -*-
3
4 import sys, os, subprocess, urllib2, pickle
5 PKG_PATH = '/var/log/packages/'
6
7 def get_arch():
8 res = subprocess.check_output(['uname', '-m'])
...
14
15 def get_localpkgs():
16 files = os.listdir(PKG_PATH)
...
28
29 def get_ftp_pkgs(arch):
30 url = "ftp://plamo.linet.gr.jp/pub/Plamo-5.x/allpkgs_" + arch + ".pickle"
31 response = urllib2.urlopen(url)
32 newpkgs = pickle.load(response)
33 return(newpkgs)
34
35 def main():
36 local_pkgs = get_localpkgs()
37 my_arch = get_arch()
38 ftp_pkgs = get_ftp_pkgs(my_arch)
39
40 for i in local_pkgs.keys():
41 try:
42 (ver, p_arch, build, path) = ftp_pkgs[i]
43 chk = (ver, p_arch, build)
44 if local_pkgs[i] != chk:
45 (local_ver, local_arch, local_build) = local_pkgs[i]
46 print("local package:{}-{}-{}-{}".format(i, local_ver, local_arch, local_build))
47 print("new package:{}-{}-{}-{}, path:{}".format(i, ver, p_arch, build, path))
...
51 except KeyError:
52 print("package: {} doesn't exit in FTP tree.".format(i))
53 print("")
54
55 if __name__ == "__main__":
56 main()
リスト中で省略しているget_
36行目のget_
get_
違いがあった場合、
51行目からは例外処理で、
このようなごくシンプルなコードなものの、
$ python get_pkginfo.py local package: lzo-2.09-x86_64-P1 new package: lzo-2.08-x86_64-P2 URL: ftp://plamo.linet.gr.jp/pub/Plamo-5.x/x86_64/plamo/00_base/lzo-2.08-x86_64-P2.txz local package: bind-9.9.6_P1-x86_64-P1 new package: bind-9.9.6_P2-x86_64-P1 URL: ftp://plamo.linet.gr.jp/pub/Plamo-5.x/x86_64/plamo/01_minimum/network.txz/bind-9.9.6_P2-x86_64-P1.txz local package: pidgin-2.10.9-x86_64-P1 new package: pidgin-2.10.11-x86_64-P1 URL: ftp://plamo.linet.gr.jp/pub/Plamo-5.x/x86_64/plamo/05_ext/gnome_parts.txz/pidgin-2.10.11-x86_64-P1.txz ...
前回も触れたように、
なかなか解決できなかった問題が、
実のところ、
Plamo Linuxのメンテナ用MLにこのコードを投げたところ、
- 「表示されるパッケージをダウンロードできれば便利」、
- 「ダウンロードできるならupdatepkgで更新してしまってもいいのでは」、
- 「でも、
いくつかのパッケージは単純にupdatepkgじゃ更新できないよね」、 - 「ダウンロード中の状態表示が欲しい」、
- 「ローカルに更新しているパッケージはチェック対象にして欲しくない」、
等々、
そこで、
$ python ./get_pkginfo.py -h usage: get_pkginfo.py [-h] [-v] [-u URL] [-d | -s] [-o DOWNTODIR] [-c CATEGORY] [-b] [-l LOCALBLOCK] [-a | -i] [-r] Plamo Linux update packages check and download optional arguments: -h, --help show this help message and exit -v, --verbose verbose messages (not implemented yet) -u URL, --url URL set URL to download -d, --download download package(s) -s, --dlsubdir download package(s) with subdir(s) -o DOWNTODIR, --downtodir DOWNTODIR directory to save package(s) -c CATEGORY, --category CATEGORY set category(ies) to check -b, --blocklist ignore block list -l LOCALBLOCK, --localblock LOCALBLOCK set pkgname(s) to block -a, --autoinstall install downloaded package(s) automatically -i, --interactive install downloaded package(s) interactively -r, --reverse find un-selected package(s)
現在では、
簡単なアイデアやコードが触媒となって興味ある人々の間でどんどん発展していき、