umnlisting.dcgi - geomyidae - A small C-based gopherd. | |
git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfri… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
umnlisting.dcgi (5552B) | |
--- | |
1 #!/usr/bin/env python | |
2 # coding=utf-8 | |
3 # | |
4 # Dir listing like in UMN gopher. | |
5 # | |
6 # Files: .abstract, .names, .cap/$file, .Links | |
7 # Entries: Name=, Type=, Path=, Host=, Port=, Abstract=, Admin=, URL=, | |
8 # TTL= | |
9 # | |
10 | |
11 import os | |
12 import sys | |
13 | |
14 def dcgifilterprint(lines): | |
15 for line in lines: | |
16 line = line.strip() | |
17 if line[0] == 't': | |
18 print("t%s" % (line)) | |
19 else: | |
20 print("%s" % (line)) | |
21 | |
22 def parselinksfile(filepath, link={}): | |
23 fd = open(filepath, "r") | |
24 links = {} | |
25 while 1: | |
26 line = fd.readline() | |
27 if not line: | |
28 if "path" in link: | |
29 links[link["path"]] = link | |
30 link = {} | |
31 break | |
32 line = line.strip() | |
33 if len(line) == 0 or line.startswith("#"): | |
34 if "path" in link: | |
35 links[link["path"]] = link | |
36 link = {} | |
37 continue | |
38 elif line.startswith("Type="): | |
39 link["type"] = line.split("=", 1)[1] | |
40 elif line.startswith("Name="): | |
41 link["name"] = line.split("=", 1)[1] | |
42 elif line.startswith("Path="): | |
43 link["path"] = line.split("=", 1)[1] | |
44 elif line.startswith("Host="): | |
45 link["host"] = line.split("=", 1)[1] | |
46 elif line.startswith("Port="): | |
47 link["port"] = line.split("=", 1)[1] | |
48 elif line.startswith("Numb="): | |
49 try: | |
50 link["number"] = int(line.split("=", 1)[… | |
51 except ValueError: | |
52 pass | |
53 elif line.startswith("Abstract="): | |
54 link["abstract"] = line.split("=", 1)[1] | |
55 while link["abstract"][-1] == "\\": | |
56 link["abstract"] = link["abstract"][:-1] | |
57 link["abstract"] += "\n" | |
58 link["abstract"] += fd.readline().strip() | |
59 | |
60 # Undefined case in UMN. Handle it nicely. | |
61 if link["abstract"][-1] == "\\": | |
62 link["abstract"][-1] = "\n" | |
63 elif line.startswith("Admin="): | |
64 link["admin"] = line.split("=", 1)[1] | |
65 elif line.startswith("URL="): | |
66 link["url"] = line.split("=", 1)[1] | |
67 elif line.startswith("TTL="): | |
68 link["ttl"] = line.split("=", 1)[1] | |
69 fd.close() | |
70 | |
71 return links | |
72 | |
73 def usage(app): | |
74 print("usage: %s search arguments host port" % (app), | |
75 file=sys.stderr) | |
76 sys.exit(1) | |
77 | |
78 def main(args): | |
79 scriptname = os.path.basename(args[0]) | |
80 if len(args) < 5: | |
81 usage(scriptname) | |
82 search = args[1] | |
83 arguments = args[2] | |
84 host = args[3] | |
85 port = args[4] | |
86 | |
87 basedir = "." | |
88 if len(arguments) > 0 and arguments[0] == "/": | |
89 basedir = arguments[0].split("?")[0] | |
90 | |
91 # First print every .abstract file content. | |
92 abstractpath = "%s/.abstract" % (basedir) | |
93 if os.path.exists(abstractpath): | |
94 fd = open(abstractpath, "r") | |
95 dcgifilterprint(fd.readlines()) | |
96 fd.close() | |
97 | |
98 outputlinks = {} | |
99 numblinks = {} | |
100 | |
101 linkspath = "%s/.Links" % (basedir) | |
102 if os.path.exists(linkspath): | |
103 linkslinks = parselinksfile(linkspath) | |
104 for linkkey in linkslinks.keys(): | |
105 outputlinks[linkkey] = linkslinks[linkkey] | |
106 if "number" in linkslinks[linkkey]: | |
107 numblinks[linkkey] = linkslinks[linkkey] | |
108 | |
109 entries = os.listdir(basedir) | |
110 for entry in entries: | |
111 entrylink = {} | |
112 entrylink["type"] = "9" | |
113 if os.path.isdir(entry): | |
114 entrylink["type"] = "1" | |
115 | |
116 entrylink["path"] = "./%s" % (entry) | |
117 entrylink["name"] = entry | |
118 capspath = "%s/.cap/%s" % (basedir, entry) | |
119 if os.path.exists(capspath): | |
120 caplink = parselinksfile(capspath, entrylink) | |
121 outputlinks[entrylink["path"]] = entrylink | |
122 if "number" in entrylink: | |
123 numblinks[entrylink["path"]] = entrylink | |
124 | |
125 namespath = "%s/.names" % (basedir) | |
126 if os.path.exists(namespath): | |
127 nameslinks = parselinksfile(namespath) | |
128 for namekey in nameslinks.keys(): | |
129 namelink = nameslinks[namekey] | |
130 if namekey in outputlinks.keys(): | |
131 for key in namelink: | |
132 outputlinks[namekey][key] = \ | |
133 namelink[key] | |
134 else: | |
135 outputlinks[namekey] = nameslinks[nameke… | |
136 if "number" in outputlinks[namekey]: | |
137 numblinks[namekey] = outputlinks[namekey] | |
138 | |
139 displaylinks = {} | |
140 for link in outputlinks.keys(): | |
141 if "name" in outputlinks[link]: | |
142 displaylinks[outputlinks[link]["name"]] = link | |
143 elif "path" in outputlinks[link]: | |
144 if outputlinks[link]["path"].startswith("./"): | |
145 displaylinks[outputlinks[link]["path"][2… | |
146 link | |
147 else: | |
148 displaylinks[outputlinks[link]["path"]] … | |
149 link | |
150 else: | |
151 displaylinks[link] = link | |
152 | |
153 displaykeys = sorted(displaylinks) | |
154 for dotfile in [".Links", ".names", ".cap", ".abstract"]: | |
155 try: | |
156 displaykeys.remove(dotfile) | |
157 except ValueError: | |
158 pass | |
159 | |
160 # This is why the UMN format really sucks. | |
161 numbers = {} | |
162 for numb in numblinks.keys(): | |
163 link = outputlinks[numb] | |
164 numbers[link["number"]] = outputlinks[numb] | |
165 if "name" in link: | |
166 displaykeys.remove(link["name"]) | |
167 elif "path" in link: | |
168 if link["path"].startswith("./"): | |
169 displaykeys.remove(link["path"][2:]) | |
170 else: | |
171 displaykeys.remove(link["path"]) | |
172 | |
173 curnumber = 1 | |
174 while 1: | |
175 if curnumber in numbers.keys(): | |
176 path = numbers[curnumber]["path"] | |
177 numbers.pop(curnumber) | |
178 else: | |
179 key = displaykeys.pop() | |
180 path = displaylinks[key] | |
181 | |
182 # Work on the rest of the numbered links, when no display | |
183 # entries are left. | |
184 if len(displaykeys) == 0: | |
185 if len(numbers) == 0: | |
186 break | |
187 randnumb = numbers.pop() | |
188 path = randnumb["path"] | |
189 | |
190 link = outputlinks[path] | |
191 if "port" not in link: | |
192 link["port"] = "port" | |
193 if "host" not in link: | |
194 link["host"] = "server" | |
195 if "name" not in link: | |
196 if link["path"].startswith("./"): | |
197 link["name"] = link["path"][2:] | |
198 else: | |
199 link["name"] = link["path"] | |
200 if "type" not in link: | |
201 link["type"] = "9" | |
202 | |
203 # dcgi escaping. | |
204 link["name"].replace("|", "\\|") | |
205 | |
206 print("[%s|%s|%s|%s|%s]" % (link["type"][0],\ | |
207 link["name"], link["path"], link["host"],\ | |
208 link["port"])) | |
209 | |
210 if "abstract" in link: | |
211 dcgifilterprint(link["abstract"].split("\n")) | |
212 | |
213 curnumber += 1 | |
214 | |
215 return 0 | |
216 | |
217 if __name__ == "__main__": | |
218 sys.exit(main(sys.argv)) | |
219 |