ilawn-mower.py - gopher-lawn - The gopher lawn gopher directory project. Err bitreich.org 70 hgit clone git://bitreich.org/gopher-lawn/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gopher-lawn/ URL:git://bitreich.org/gopher-lawn/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gopher-lawn/ bitreich.org 70 1Log /scm/gopher-lawn/log.gph bitreich.org 70 1Files /scm/gopher-lawn/files.gph bitreich.org 70 1Refs /scm/gopher-lawn/refs.gph bitreich.org 70 1Tags /scm/gopher-lawn/tag bitreich.org 70 i--- Err bitreich.org 70 ilawn-mower.py (6722B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 #!/usr/bin/env python Err bitreich.org 70 i 2 # coding=utf-8 Err bitreich.org 70 i 3 # Err bitreich.org 70 i 4 # © 2020 Christoph Lohmann <20h@r-36.net> Err bitreich.org 70 i 5 # Err bitreich.org 70 i 6 # This file is published under the terms of the GPLv3. Err bitreich.org 70 i 7 # Err bitreich.org 70 i 8 Err bitreich.org 70 i 9 import os Err bitreich.org 70 i 10 import sys Err bitreich.org 70 i 11 import getopt Err bitreich.org 70 i 12 Err bitreich.org 70 i 13 def usage(app): Err bitreich.org 70 i 14 app = os.path.basename(app) Err bitreich.org 70 i 15 print("usage: %s [-h] [-b basedir] [-c categorydir] " \ Err bitreich.org 70 i 16 "[-s selectorbase]" \ Err bitreich.org 70 i 17 % (app), file=sys.stderr) Err bitreich.org 70 i 18 sys.exit(1) Err bitreich.org 70 i 19 Err bitreich.org 70 i 20 def main(args): Err bitreich.org 70 i 21 try: Err bitreich.org 70 i 22 opts, largs = getopt.getopt(args[1:], "hc:s:") Err bitreich.org 70 i 23 except getopt.GetoptError as err: Err bitreich.org 70 i 24 print(str(err)) Err bitreich.org 70 i 25 usage(args[0]) Err bitreich.org 70 i 26 Err bitreich.org 70 i 27 basedir = "./" Err bitreich.org 70 i 28 categorysubdir = "/c" Err bitreich.org 70 i 29 selectorbase = "/lawn" Err bitreich.org 70 i 30 for o, a in opts: Err bitreich.org 70 i 31 if o == "-h": Err bitreich.org 70 i 32 usage(args[0]) Err bitreich.org 70 i 33 elif o == "-b": Err bitreich.org 70 i 34 basedir = a Err bitreich.org 70 i 35 elif o == "-c": Err bitreich.org 70 i 36 categorysubdir = a Err bitreich.org 70 i 37 elif o == "-s": Err bitreich.org 70 i 38 selectorbase = a Err bitreich.org 70 i 39 else: Err bitreich.org 70 i 40 assert False, "unhandled option" Err bitreich.org 70 i 41 Err bitreich.org 70 i 42 categorydir = "%s%s" % (basedir, categorysubdir) Err bitreich.org 70 i 43 categoryselector = "%s%s" % (selectorbase, categorysubdir) Err bitreich.org 70 i 44 Err bitreich.org 70 i 45 filelist = largs Err bitreich.org 70 i 46 if len(largs) == 0: Err bitreich.org 70 i 47 filelist = ["/dev/stdin"] Err bitreich.org 70 i 48 Err bitreich.org 70 i 49 dbobjs = [] Err bitreich.org 70 i 50 dbobj = {} Err bitreich.org 70 i 51 for f in filelist: Err bitreich.org 70 i 52 dbobj = {} Err bitreich.org 70 i 53 dbkey = None Err bitreich.org 70 i 54 dbval = None Err bitreich.org 70 i 55 with open(f, "r") as fd: Err bitreich.org 70 i 56 while True: Err bitreich.org 70 i 57 line = fd.readline() Err bitreich.org 70 i 58 # EOF Err bitreich.org 70 i 59 if line == "": Err bitreich.org 70 i 60 #print("EOF") Err bitreich.org 70 i 61 if dbobj != {}: Err bitreich.org 70 i 62 dbobjs.append(dbobj) Err bitreich.org 70 i 63 dbobj = {} Err bitreich.org 70 i 64 break Err bitreich.org 70 i 65 Err bitreich.org 70 i 66 if line[0] == "#": Err bitreich.org 70 i 67 continue Err bitreich.org 70 i 68 Err bitreich.org 70 i 69 line = line.rstrip() Err bitreich.org 70 i 70 #print("line = '%s'" % (line)) Err bitreich.org 70 i 71 if line == "": Err bitreich.org 70 i 72 #print("line empty") Err bitreich.org 70 i 73 if dbobj != {}: Err bitreich.org 70 i 74 dbobjs.append(dbobj) Err bitreich.org 70 i 75 dbobj = {} Err bitreich.org 70 i 76 continue Err bitreich.org 70 i 77 Err bitreich.org 70 i 78 # Multi line value. Err bitreich.org 70 i 79 if line[0] in ["\f", "\t", "\v", " "]: Err bitreich.org 70 i 80 #print("multi-line") Err bitreich.org 70 i 81 if dbkey != None: Err bitreich.org 70 i 82 dbobj[dbkey] += " %s" % (line.lstrip()) Err bitreich.org 70 i 83 continue Err bitreich.org 70 i 84 Err bitreich.org 70 i 85 try: Err bitreich.org 70 i 86 (dbkey, dbval) = line.split(":", 1) Err bitreich.org 70 i 87 except ValueError: Err bitreich.org 70 i 88 sys.write(sys.stderr, "'%s' is invalid line at %s.\n" \ Err bitreich.org 70 i 89 % (line, f)) Err bitreich.org 70 i 90 continue Err bitreich.org 70 i 91 Err bitreich.org 70 i 92 #print("dbkey = %s; dbval = %s" % (dbkey, dbval)) Err bitreich.org 70 i 93 Err bitreich.org 70 i 94 dbkey = dbkey.strip().lower() Err bitreich.org 70 i 95 dbval = dbval.lstrip() Err bitreich.org 70 i 96 dbobj[dbkey] = dbval Err bitreich.org 70 i 97 Err bitreich.org 70 i 98 rootcategory = None Err bitreich.org 70 i 99 categories = {} Err bitreich.org 70 i 100 wantedcategories = {} Err bitreich.org 70 i 101 wantedkeywords = {} Err bitreich.org 70 i 102 keywords = {} Err bitreich.org 70 i 103 links = [] Err bitreich.org 70 i 104 noncategories = [] Err bitreich.org 70 i 105 nonkeywords = [] Err bitreich.org 70 i 106 for obj in dbobjs: Err bitreich.org 70 i 107 if "category" in obj: Err bitreich.org 70 i 108 ocats = obj["category"].split(", ") Err bitreich.org 70 i 109 if len(ocats) == 0 or ocats[0] == '': Err bitreich.org 70 i 110 noncategories.append(obj) Err bitreich.org 70 i 111 obj["category"] = ocats Err bitreich.org 70 i 112 for ocat in ocats: Err bitreich.org 70 i 113 if ocat in wantedcategories: Err bitreich.org 70 i 114 wantedcategories[ocat].append(obj) Err bitreich.org 70 i 115 else: Err bitreich.org 70 i 116 wantedcategories[ocat] = [obj] Err bitreich.org 70 i 117 if "keywords" in obj: Err bitreich.org 70 i 118 okeyws = obj["keywords"].split(", ") Err bitreich.org 70 i 119 if len(okeyws) == 0 or okeyws[0] == '': Err bitreich.org 70 i 120 nonkeywords.append(obj) Err bitreich.org 70 i 121 for okeyw in okeyws: Err bitreich.org 70 i 122 if okeyw in wantedkeywords: Err bitreich.org 70 i 123 wantedkeywords[okeyw].append(obj) Err bitreich.org 70 i 124 else: Err bitreich.org 70 i 125 wantedkeywords[okeyw] = [obj] Err bitreich.org 70 i 126 if obj["type"] == "category": Err bitreich.org 70 i 127 if obj["parent"] == "none": Err bitreich.org 70 i 128 rootcategory = obj Err bitreich.org 70 i 129 if obj["name"] in categories: Err bitreich.org 70 i 130 print("Duplication of category '%s'." \ Err bitreich.org 70 i 131 % (obj["name"])) Err bitreich.org 70 i 132 sys.exit(1) Err bitreich.org 70 i 133 obj["links"] = [] Err bitreich.org 70 i 134 obj["children"] = [] Err bitreich.org 70 i 135 categories[obj["name"]] = obj Err bitreich.org 70 i 136 else: Err bitreich.org 70 i 137 links.append(obj) Err bitreich.org 70 i 138 Err bitreich.org 70 i 139 #print(categories.keys()) Err bitreich.org 70 i 140 keywords = wantedkeywords Err bitreich.org 70 i 141 #print(wantedkeywords.keys()) Err bitreich.org 70 i 142 #print(keywords.keys()) Err bitreich.org 70 i 143 #print(wantedcategories.keys()) Err bitreich.org 70 i 144 #print(noncategories) Err bitreich.org 70 i 145 #print(nonkeywords) Err bitreich.org 70 i 146 Err bitreich.org 70 i 147 for link in links: Err bitreich.org 70 i 148 if "category" in link: Err bitreich.org 70 i 149 for cate in link["category"]: Err bitreich.org 70 i 150 categories[cate]["links"].append(link) Err bitreich.org 70 i 151 Err bitreich.org 70 i 152 for key in categories.keys(): Err bitreich.org 70 i 153 parent = categories[key]["parent"] Err bitreich.org 70 i 154 if parent in categories.keys(): Err bitreich.org 70 i 155 categories[parent]["children"].append(key) Err bitreich.org 70 i 156 else: Err bitreich.org 70 i 157 if parent != "none": Err bitreich.org 70 i 158 print("Undefined parent '%s' used in category '%s'." \ Err bitreich.org 70 i 159 % (parent, key)) Err bitreich.org 70 i 160 Err bitreich.org 70 i 161 for obj in noncategories: Err bitreich.org 70 i 162 print("'%s' has no categories defined." \ Err bitreich.org 70 i 163 % (obj["linkname"])) Err bitreich.org 70 i 164 for obj in nonkeywords: Err bitreich.org 70 i 165 print("'%s' has no keywords defined." \ Err bitreich.org 70 i 166 % (obj["linkname"])) Err bitreich.org 70 i 167 Err bitreich.org 70 i 168 def linktype2gopher(link): Err bitreich.org 70 i 169 linktype = link["type"] Err bitreich.org 70 i 170 if linktype == "link": Err bitreich.org 70 i 171 if link["selector"].startswith("URL:"): Err bitreich.org 70 i 172 return "h" Err bitreich.org 70 i 173 return "1" Err bitreich.org 70 i 174 elif linktype == "text": Err bitreich.org 70 i 175 return "0" Err bitreich.org 70 i 176 elif linktype == "cso": Err bitreich.org 70 i 177 return "2" Err bitreich.org 70 i 178 elif linktype == "error": Err bitreich.org 70 i 179 return "3" Err bitreich.org 70 i 180 elif linktype == "uuencoded": Err bitreich.org 70 i 181 return "6" Err bitreich.org 70 i 182 elif linktype == "search": Err bitreich.org 70 i 183 return "7" Err bitreich.org 70 i 184 elif linktype == "telnet": Err bitreich.org 70 i 185 return "8" Err bitreich.org 70 i 186 else: Err bitreich.org 70 i 187 return "9" Err bitreich.org 70 i 188 Err bitreich.org 70 i 189 def printdescription(desc): Err bitreich.org 70 i 190 maxlinelen = 70 Err bitreich.org 70 i 191 if len(desc) <= maxlinelen: Err bitreich.org 70 i 192 return "%s\n" % (desc) Err bitreich.org 70 i 193 Err bitreich.org 70 i 194 rtext = "" Err bitreich.org 70 i 195 adesc = desc Err bitreich.org 70 i 196 while len(adesc) > maxlinelen: Err bitreich.org 70 i 197 pline = "" Err bitreich.org 70 i 198 i = 70 Err bitreich.org 70 i 199 while i > maxlinelen-20: Err bitreich.org 70 i 200 if adesc[i] in [" ", "\t", "\v", "\f", "-"]: Err bitreich.org 70 i 201 rtext += "%s\n" % (adesc[:i]) Err bitreich.org 70 i 202 adesc = adesc[i+1:] Err bitreich.org 70 i 203 break Err bitreich.org 70 i 204 i -= 1 Err bitreich.org 70 i 205 if i <= maxlinelen-20: Err bitreich.org 70 i 206 rtext += "%s\n" % (adesc[:maxlinelen]) Err bitreich.org 70 i 207 adesc = adesc[maxlinelen:] Err bitreich.org 70 i 208 rtext += "%s\n" % (adesc) Err bitreich.org 70 i 209 Err bitreich.org 70 i 210 return rtext Err bitreich.org 70 i 211 Err bitreich.org 70 i 212 def printlink(link): Err bitreich.org 70 i 213 try: Err bitreich.org 70 i 214 rtext = "[%s|%s|%s|%s|%s]\n" \ Err bitreich.org 70 i 215 % (linktype2gopher(link),\ Err bitreich.org 70 i 216 link["linkname"],\ Err bitreich.org 70 i 217 link["selector"],\ Err bitreich.org 70 i 218 link["host"],\ Err bitreich.org 70 i 219 link["port"]) Err bitreich.org 70 i 220 except KeyError: Err bitreich.org 70 i 221 print("Error printing link in: %s" % (link)) Err bitreich.org 70 i 222 return "" Err bitreich.org 70 i 223 Err bitreich.org 70 i 224 if "description" in link: Err bitreich.org 70 i 225 rtext += printdescription(link["description"]) Err bitreich.org 70 i 226 rtext += "\n" Err bitreich.org 70 i 227 Err bitreich.org 70 i 228 return rtext Err bitreich.org 70 i 229 Err bitreich.org 70 i 230 def printcategory(category, basedir): Err bitreich.org 70 i 231 if "description" in category: Err bitreich.org 70 i 232 name = "%s - %s" \ Err bitreich.org 70 i 233 % (category["linkname"], \ Err bitreich.org 70 i 234 category["description"]) Err bitreich.org 70 i 235 else: Err bitreich.org 70 i 236 name = category["linkname"] Err bitreich.org 70 i 237 return "[1|%s|%s|%s|%s]\n" \ Err bitreich.org 70 i 238 % (name,\ Err bitreich.org 70 i 239 "%s/%s.gph" % (basedir, category["name"]),\ Err bitreich.org 70 i 240 "server",\ Err bitreich.org 70 i 241 "port") Err bitreich.org 70 i 242 Err bitreich.org 70 i 243 def mkcategory(category, cdir, csdir, tmplfile="category.gph.tmpl"): Err bitreich.org 70 i 244 outfilename = tmplfile.replace(".tmpl", "") Err bitreich.org 70 i 245 if "category" in tmplfile: Err bitreich.org 70 i 246 outfilename = outfilename.replace("category",\ Err bitreich.org 70 i 247 category["name"]) Err bitreich.org 70 i 248 Err bitreich.org 70 i 249 tmplfd = open(tmplfile, "r") Err bitreich.org 70 i 250 try: Err bitreich.org 70 i 251 outfd = open("%s/%s" % (cdir, outfilename), "x") Err bitreich.org 70 i 252 except FileExistsError: Err bitreich.org 70 i 253 outfd = open("%s/%s" % (cdir, outfilename), "w") Err bitreich.org 70 i 254 Err bitreich.org 70 i 255 line = "a" Err bitreich.org 70 i 256 while len(line) > 0: Err bitreich.org 70 i 257 line = tmplfd.readline() Err bitreich.org 70 i 258 if "C_A_T_E_G_O_R_Y" in line: Err bitreich.org 70 i 259 if len(category["links"]) > 0: Err bitreich.org 70 i 260 line = line.replace("C_A_T_E_G_O_R_Y", \ Err bitreich.org 70 i 261 category["title"]) Err bitreich.org 70 i 262 outfd.write(line) Err bitreich.org 70 i 263 if "description" in category: Err bitreich.org 70 i 264 outfd.write(printdescription(\ Err bitreich.org 70 i 265 category["description"])) Err bitreich.org 70 i 266 outfd.write("\n") Err bitreich.org 70 i 267 for link in category["links"]: Err bitreich.org 70 i 268 outfd.write(printlink(link)) Err bitreich.org 70 i 269 elif "C_A_T_E_G_O_R_I_E_S" in line: Err bitreich.org 70 i 270 if len(category["children"]) > 0: Err bitreich.org 70 i 271 outfd.write(line) Err bitreich.org 70 i 272 for cate in category["children"]: Err bitreich.org 70 i 273 outfd.write(\ Err bitreich.org 70 i 274 printcategory(\ Err bitreich.org 70 i 275 categories[cate],\ Err bitreich.org 70 i 276 csdir)) Err bitreich.org 70 i 277 else: Err bitreich.org 70 i 278 outfd.write(line) Err bitreich.org 70 i 279 Err bitreich.org 70 i 280 tmplfd.close() Err bitreich.org 70 i 281 outfd.close() Err bitreich.org 70 i 282 Err bitreich.org 70 i 283 mkcategory(rootcategory, basedir, categoryselector, "index.gph.tmpl") Err bitreich.org 70 i 284 for c in categories.keys(): Err bitreich.org 70 i 285 mkcategory(categories[c], categorydir, categoryselector,\ Err bitreich.org 70 i 286 "category.gph.tmpl") Err bitreich.org 70 i 287 return 0 Err bitreich.org 70 i 288 Err bitreich.org 70 i 289 if __name__ == "__main__": Err bitreich.org 70 i 290 sys.exit(main(sys.argv)) Err bitreich.org 70 i 291 Err bitreich.org 70 .