]>
Commit | Line | Data |
---|---|---|
818a4490 | 1 | #!/usr/bin/python |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2007 Michael Tremer & Christian Schmidt # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
21 | ||
22 | import os | |
23 | import cgi | |
24 | from git import * | |
25 | ||
26 | def give_404(): | |
27 | print "Status: 404 Not found" | |
28 | print "Pragma: no-cache" | |
29 | print "Cache-control: no-cache" | |
30 | print "Connection: close" | |
31 | ||
32 | os._exit(0) | |
33 | ||
34 | def give_302(): | |
35 | print "Status: 302 Moved" | |
36 | print "Location: /" | |
37 | print "Pragma: no-cache" | |
38 | print "Cache-control: no-cache" | |
39 | print "Connection: close" | |
40 | ||
41 | ||
42 | os._exit(0) | |
43 | ||
44 | class NotFoundError(Exception): | |
45 | pass | |
46 | ||
47 | class SourceObject: | |
48 | def __init__(self, path): | |
49 | self.path = path | |
50 | ||
51 | self.object_type = None | |
52 | ||
53 | # Init hashes | |
54 | self.hash_md5 = None | |
55 | self.hash_sha1 = None | |
56 | ||
57 | def hash(self): | |
58 | ## This is for python 2.4. | |
59 | #import md5 | |
60 | #self.hash_md5 = md5.new(self.data()).hexdigest() | |
61 | ||
62 | import sha | |
63 | self.hash_sha1 = sha.new(self.data()).hexdigest() | |
64 | ||
65 | def data(self): | |
66 | return self.filedata | |
67 | ||
68 | def run(self): | |
69 | self.hash() | |
70 | self.showhttpheaders() | |
71 | print self.data() | |
72 | ||
73 | def showhttpheaders(self): | |
74 | print "Pragma: no-cache" | |
75 | print "Cache-control: no-cache" | |
76 | print "Connection: close" | |
77 | print "Content-type:" + self.mimetype() | |
78 | print "Content-length: %s" % len(self.data()) | |
79 | if self.object_type: | |
80 | print "X-Object:" + self.object_type | |
81 | if self.hash_md5: | |
82 | print "X-MD5:" + self.hash_md5 | |
83 | if self.hash_sha1: | |
84 | print "X-SHA1:" + self.hash_sha1 | |
85 | ||
86 | # An empty line ends the header | |
87 | ||
88 | class FileObject(SourceObject): | |
89 | def __init__(self, path, version, url="/srv/www/ipfire.org/source/"): | |
90 | SourceObject.__init__(self, path) | |
91 | self.url= os.path.join(url, "source-%s" % version) | |
92 | self.filepath = os.path.join(self.url, path) | |
93 | self.init_file() | |
94 | ||
95 | self.object_type = "FileObject" | |
96 | ||
97 | def init_file(self): | |
98 | try: | |
99 | f = open(self.filepath, "rb") | |
100 | except: | |
101 | raise NotFoundError | |
102 | ||
103 | self.filedata = f.read() | |
104 | f.close() | |
105 | ||
106 | def mimetype(self): | |
107 | default_mimetype = "text/plain" | |
108 | from mimetypes import guess_type | |
109 | return guess_type(self.filepath)[0] or default_mimetype | |
110 | ||
111 | class PatchObject(SourceObject): | |
112 | def __init__(self, path, url="/srv/git/patches.git"): | |
113 | SourceObject.__init__(self, path) | |
114 | ||
115 | self.object_type = "PatchObject" | |
116 | ||
117 | self.url = url | |
118 | self.init_repo() | |
119 | ||
120 | def init_repo(self): | |
121 | # init the repo | |
122 | self.repo = Repository(self.url) | |
123 | ||
124 | # head, tree & blob | |
125 | #self.head = self.repo.head() | |
126 | self.tree = self.repo.head.tree | |
127 | ||
128 | self.blob = self.set_blob() | |
129 | ||
130 | def set_blob(self): | |
131 | blob = None | |
132 | ||
133 | for directory in self.tree.keys(): | |
134 | if isinstance(self.tree[directory], Blob): | |
135 | continue | |
136 | try: | |
137 | blob = self.tree[directory][path] | |
138 | if blob: | |
139 | break | |
140 | except KeyError: | |
141 | pass | |
142 | ||
143 | if not blob: | |
144 | raise NotFoundError | |
145 | ||
146 | blob._load() | |
147 | self.filedata = blob._contents | |
148 | return blob | |
149 | ||
150 | def mimetype(self): | |
151 | return "text/plain" #self.blob.mime_type | |
152 | ||
153 | # main() | |
154 | path = cgi.FieldStorage().getfirst('path') | |
155 | ver = cgi.FieldStorage().getfirst('ver') | |
156 | ||
157 | if not path: | |
158 | give_302() | |
159 | ||
160 | if not ver: | |
161 | ver = "3.x" | |
162 | ||
163 | ||
164 | # At first, we assume that the requested object is a plain file: | |
165 | try: | |
166 | object = FileObject(path=path, version=ver) | |
167 | except NotFoundError: | |
168 | # Second, we assume that the requestet object is in the patch repo: | |
169 | try: | |
170 | object = PatchObject(path=path) | |
171 | except NotFoundError: | |
172 | give_404() | |
173 | else: | |
174 | object.run() | |
175 | else: | |
176 | object.run() |