-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
executable file
·162 lines (129 loc) · 4.91 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python3
from sys import argv, stdout
import re
import pycurl
import curl
PATCHES = \
[
{
"name": "aufs",
"meta-url": "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-kernel/aufs-sources/",
"meta-pattern": "aufs-sources-${kseries}.\d+.ebuild",
"url": "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-kernel/aufs-sources/${eval-meta-pattern}",
"pattern": '(?<=AUFS_VERSION=).*'
},
{
"name": "ck", # ck != bfs, ck is a superset of bfs
"url": "http://ck.kolivas.org/patches/3.0/${kseries}",
"pattern": "${kseries}-ck[0-9]"
},
{
"name": "genpatches",
"url": "http://dev.gentoo.org/~mpagano/genpatches/tarballs/",
"pattern": "genpatches-${kseries}-\d+"
},
{
"name": "reiser4",
"url": "http://sourceforge.net/projects/reiser4/files/reiser4-for-linux-3.x/",
"pattern": "reiser4-for-${kseries}(?:.\d+)?.patch.gz"
},
{
"name": "tuxonice",
"url": "http://tuxonice.nigelcunningham.com.au/downloads/all/",
"pattern": "tuxonice-for-linux(?:-head)?-${kseries}\.\d+-\d+-\d+-\d+"
},
{
"name": "uksm",
"meta-meta-url": "http://kerneldedup.org/projects/uksm/download/",
"meta-meta-pattern": "0\.1\.\d+\.(?:\d+)?",
"meta-url": "http://kerneldedup.org/projects/uksm/download/",
"meta-pattern": "(?<=http://kerneldedup.org/projects/uksm/download/uksm/${eval-meta-meta-pattern}/#wpfb-cat-)\d+",
"url": "http://kerneldedup.org/wp-content/plugins/wp-filebase/wpfb-ajax.php?action=tree&type=browser&base=${eval-meta-pattern}",
"pattern": "uksm-0\.1\.\d+\.(?:\d+)?-for-v${kseries}.ge.\d+.patch",
},
]
def http_get(url):
_curl = curl.Curl()
content = _curl.get(url).decode("UTF-8")
response_code = _curl.get_info(pycurl.RESPONSE_CODE)
if response_code == 200:
return content
elif response_code == 404:
return None
else:
raise RuntimeError("HTTP Error: %d" % response_code)
class VersionNumber():
def __init__(self, version_string):
from distutils.version import LooseVersion
self._verstr = version_string
for idx, val in enumerate(version_string):
# the problem is that we can not compare two patches
# differently named but actually just the same thing:
#
# patch-3.1.2 and patch-experimental-4.0.1
#
# So, I assume different branches of a patch never use the same
# version number. So just ignore until the first number,
# but we also need to keep the original version string for output.
if val.isdigit():
self._verobj = LooseVersion(version_string[idx:])
break
def __gt__(self, other):
return self._verobj > other._verobj
def __eq__(self, other):
return self._verobj == other._verobj
def __lt__(self, other):
return self._verobj < other._verobj
def __str__(self):
return self._verstr
def latest_version(versions_list):
versions_list = list(set(versions_list))
versions = []
for version in versions_list:
versions.append(VersionNumber(version))
return str(max(versions))
class ReplaceTable():
def __init__(self):
self._table = {}
def add(self, k, v):
self._table[k] = v
def replace(self, string):
for k, v in self._table.items():
string = string.replace("${%s}" % k, v)
return string
if __name__ == "__main__":
if len(argv) < 2:
print("Usage: %s [LINUX KERNEL SERIES]" % argv[0])
print("Example: %s 3.10" % argv[0])
exit()
for patch in PATCHES:
print("checking %s..." % patch["name"], end="")
stdout.flush()
# init replace table
table = ReplaceTable()
table.add("kseries", argv[1])
# how many levels?
level = 0
for key in patch.keys():
_level = key.count("meta")
if _level > level:
level = _level
# perform each level
while level >= 0:
# replace
for k, v in patch.items():
patch[k] = table.replace(v)
prefix = "%s-" % "meta" * level
content = http_get(patch[prefix + "url"])
if not content:
print("unsupported (404)")
break
matched = re.findall(patch[prefix + "pattern"], content)
if not matched:
print("unsupported (no matched item)")
break
version = latest_version(matched)
table.add("eval-%spattern" % prefix, version)
if level == 0:
print(version)
level -= 1