pybot-commits Mailing List for pybot
Brought to you by:
niemeyer
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(6) |
Dec
(7) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
|
Feb
|
Mar
(1) |
Apr
(7) |
May
(1) |
Jun
(14) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(56) |
Jun
(4) |
Jul
|
Aug
(85) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
From: Gustavo N. <nie...@us...> - 2003-09-12 02:24:14
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv30330/pybot/modules Modified Files: eval.py Log Message: * modules/eval.py: Added random functions to eval. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** eval.py 29 Aug 2003 17:14:30 -0000 1.11 --- eval.py 12 Sep 2003 02:24:03 -0000 1.12 *************** *** 22,25 **** --- 22,26 ---- import time import math + import random import os from types import StringType *************** *** 60,63 **** --- 61,65 ---- self.dict["abs"] = abs self.dict["bool"] = bool + self.dict["choice"] = random.choice self.dict["chr"] = chr self.dict["cmp"] = cmp *************** *** 81,88 **** --- 83,94 ---- self.dict["ord"] = ord self.dict["pow"] = pow + self.dict["randint"] = random.randint + self.dict["random"] = random.random + self.dict["randrange"] = random.randrange self.dict["range"] = range self.dict["reduce"] = reduce self.dict["repr"] = repr self.dict["round"] = round + self.dict["shuffle"] = random.shuffle self.dict["str"] = str self.dict["tuple"] = tuple |
From: Gustavo N. <nie...@us...> - 2003-09-12 02:24:14
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv30330 Modified Files: ChangeLog Log Message: * modules/eval.py: Added random functions to eval. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** ChangeLog 29 Aug 2003 00:38:56 -0000 1.36 --- ChangeLog 12 Sep 2003 02:24:03 -0000 1.37 *************** *** 1,2 **** --- 1,5 ---- + 2003-09-11 Gustavo Niemeyer <nie...@co...> + * modules/eval.py: Added random functions to eval. + 2003-08-28 Gustavo Niemeyer <nie...@co...> * modules/eval.py: Implemented a forking/timeout scheme to |
From: Gustavo N. <nie...@us...> - 2003-08-29 17:14:43
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv24478/pybot/modules Modified Files: eval.py Log Message: Remove __builtins__ from keywords list. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** eval.py 29 Aug 2003 16:35:31 -0000 1.10 --- eval.py 29 Aug 2003 17:14:30 -0000 1.11 *************** *** 192,195 **** --- 192,196 ---- if mm.hasperm(msg, "eval"): keywords = self.dict.keys() + keywords.remove("__builtins__") keywords.sort() msg.answer("%:", "The following keywords are available:", |
From: Gustavo N. <nie...@us...> - 2003-08-29 16:36:13
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv14294/pybot/modules Modified Files: eval.py Log Message: Fixed dict["str"] = round. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** eval.py 29 Aug 2003 15:10:01 -0000 1.9 --- eval.py 29 Aug 2003 16:35:31 -0000 1.10 *************** *** 85,93 **** self.dict["repr"] = repr self.dict["round"] = round ! self.dict["str"] = round self.dict["tuple"] = tuple self.dict["unichr"] = unichr self.dict["unicode"] = unicode ! self.dict["xrange"] = range self.dict["zip"] = zip --- 85,93 ---- self.dict["repr"] = repr self.dict["round"] = round ! self.dict["str"] = str self.dict["tuple"] = tuple self.dict["unichr"] = unichr self.dict["unicode"] = unicode ! self.dict["xrange"] = xrange self.dict["zip"] = zip |
From: Gustavo N. <nie...@us...> - 2003-08-29 15:10:27
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv29561 Modified Files: eval.py Log Message: Fixed answering with lists. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** eval.py 29 Aug 2003 01:46:43 -0000 1.8 --- eval.py 29 Aug 2003 15:10:01 -0000 1.9 *************** *** 23,26 **** --- 23,27 ---- import math import os + from types import StringType HELP = """ *************** *** 166,171 **** elif len(answer) > MAXCHARS: msg.answer("%:", "Your answer is too long", [".", "!"]) ! else: msg.answer("%:", answer.translate(TRANSTABLE)) def message(self, msg): --- 167,174 ---- elif len(answer) > MAXCHARS: msg.answer("%:", "Your answer is too long", [".", "!"]) ! elif type(answer) is StringType: msg.answer("%:", answer.translate(TRANSTABLE)) + else: + msg.answer("%:", answer) def message(self, msg): |
From: Gustavo N. <nie...@us...> - 2003-08-29 01:46:56
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv6183/pybot/modules Modified Files: eval.py Log Message: Do not allow special chars to be sent. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** eval.py 29 Aug 2003 01:00:55 -0000 1.7 --- eval.py 29 Aug 2003 01:46:43 -0000 1.8 *************** *** 42,45 **** --- 42,49 ---- TIMEOUT = 3 + MAXCHARS = 300 + + TRANSTABLE = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' + class Eval: def __init__(self): *************** *** 160,167 **** "There's something wrong with this " "expression"], [".", "!"]) ! elif len(answer) > 255: msg.answer("%:", "Your answer is too long", [".", "!"]) else: ! msg.answer("%:", answer) def message(self, msg): --- 164,171 ---- "There's something wrong with this " "expression"], [".", "!"]) ! elif len(answer) > MAXCHARS: msg.answer("%:", "Your answer is too long", [".", "!"]) else: ! msg.answer("%:", answer.translate(TRANSTABLE)) def message(self, msg): |
From: Gustavo N. <nie...@us...> - 2003-08-29 01:01:13
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv395/pybot/modules Modified Files: eval.py Log Message: Implemented "show eval keywords" command. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** eval.py 29 Aug 2003 00:38:56 -0000 1.6 --- eval.py 29 Aug 2003 01:00:55 -0000 1.7 *************** *** 26,38 **** HELP = """ The "eval <expr>" command allows you to evaluate expressions ! using the python evaluation mechanism. The following functions are ! currently available: map, zip, len, min, max, chr, ord, abs, hex, int, ! oct, list, long, float, round, tuple, reduce, filter, coerce, plus all ! methods in the 'math' method. For more information on these functions, ! consult the Python manual. """,""" ! This command depends on the "eval" permission. Notice that a malicious ! user is able to hang me using this command, so no untrusted users should ! have this permission. """ --- 26,36 ---- HELP = """ The "eval <expr>" command allows you to evaluate expressions ! using the python evaluation mechanism. Use the command "show ! eval keywords" to check which 'keywords' are available in ! the evaluation context. """,""" ! This command depends on the "eval" permission. Notice that a ! malicious user is able to hang me using this command, so no ! untrusted users should have this permission. """ *************** *** 89,95 **** self.dict["zip"] = zip ! # Match 'eval <expr>' self.re1 = regexp(r"eval (?P<expr>.*?)") # eval[uate|uation] mm.register_help("eval(?:uate|uation)?", HELP, "eval") --- 87,96 ---- self.dict["zip"] = zip ! # eval <expr> self.re1 = regexp(r"eval (?P<expr>.*?)") + # show eval keywords + self.re2 = regexp(r"show eval keywords?") + # eval[uate|uation] mm.register_help("eval(?:uate|uation)?", HELP, "eval") *************** *** 173,178 **** thread.start_new_thread(self.eval, (msg, m.group("expr"))) else: ! msg.answer("%:", ["Sorry...", "Oops!"], ! "You don't have this power", [".", "!"]) return 0 --- 174,197 ---- thread.start_new_thread(self.eval, (msg, m.group("expr"))) else: ! msg.answer("%:", ["Nope", "Oops"], [".", "!"], ! ["You don't have this power", ! "You can't do this", ! "You're not allowed to do this"], ! [".", "!"]) ! return 0 ! ! m = self.re2.match(msg.line) ! if m: ! if mm.hasperm(msg, "eval"): ! keywords = self.dict.keys() ! keywords.sort() ! msg.answer("%:", "The following keywords are available:", ! ", ".join(keywords)) ! else: ! msg.answer("%:", ["Nope", "Oops"], [".", "!"], ! ["You don't have this power", ! "You can't do this", ! "You're not allowed to do this"], ! [".", "!"]) return 0 |
From: Gustavo N. <nie...@us...> - 2003-08-29 00:39:03
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv29720/pybot/modules Modified Files: eval.py Log Message: * modules/eval.py: Implemented a forking/timeout scheme to protect against DoS evaluations. Now it should be possible to give wider access to the module. Index: eval.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/eval.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** eval.py 24 Aug 2003 19:30:53 -0000 1.5 --- eval.py 29 Aug 2003 00:38:56 -0000 1.6 *************** *** 18,22 **** --- 18,26 ---- from pybot.locals import * + import thread + import signal + import time import math + import os HELP = """ *************** *** 38,41 **** --- 42,47 ---- """ + TIMEOUT = 3 + class Eval: def __init__(self): *************** *** 47,69 **** del self.dict["__file__"] del self.dict["__name__"] ! self.dict["map"] = map ! self.dict["zip"] = zip ! self.dict["len"] = len ! self.dict["min"] = min ! self.dict["max"] = max ! self.dict["chr"] = chr ! self.dict["ord"] = ord self.dict["abs"] = abs self.dict["hex"] = hex self.dict["int"] = int ! self.dict["oct"] = oct self.dict["list"] = list self.dict["long"] = long ! self.dict["float"] = float self.dict["round"] = round self.dict["tuple"] = tuple ! self.dict["reduce"] = reduce ! self.dict["filter"] = filter ! self.dict["coerce"] = coerce # Match 'eval <expr>' --- 53,91 ---- del self.dict["__file__"] del self.dict["__name__"] ! self.dict["False"] = False ! self.dict["True"] = True self.dict["abs"] = abs + self.dict["bool"] = bool + self.dict["chr"] = chr + self.dict["cmp"] = cmp + self.dict["coerce"] = coerce + self.dict["complex"] = complex + self.dict["dict"] = dict + self.dict["divmod"] = divmod + self.dict["filter"] = filter + self.dict["float"] = float + self.dict["hash"] = hash self.dict["hex"] = hex + self.dict["id"] = id self.dict["int"] = int ! self.dict["len"] = len self.dict["list"] = list self.dict["long"] = long ! self.dict["map"] = map ! self.dict["max"] = max ! self.dict["min"] = min ! self.dict["oct"] = oct ! self.dict["ord"] = ord ! self.dict["pow"] = pow ! self.dict["range"] = range ! self.dict["reduce"] = reduce ! self.dict["repr"] = repr self.dict["round"] = round + self.dict["str"] = round self.dict["tuple"] = tuple ! self.dict["unichr"] = unichr ! self.dict["unicode"] = unicode ! self.dict["xrange"] = range ! self.dict["zip"] = zip # Match 'eval <expr>' *************** *** 79,83 **** mm.unregister_help(HELP) mm.unregister_perm("eval") ! def message(self, msg): if not msg.forme: --- 101,167 ---- mm.unregister_help(HELP) mm.unregister_perm("eval") ! ! def fork_eval(self, expr): ! try: ! code = compile(expr, "<string>", "eval") ! except: ! return None ! r, w = os.pipe() ! pid = os.fork() ! if pid == 0: ! os.close(r) ! fw = os.fdopen(w, "w") ! try: ! fw.write(str(eval(code, self.dict))) ! except: ! pass ! fw.close() ! os._exit(1) ! os.close(w) ! fr = os.fdopen(r, "r") ! answer = None ! timeout = TIMEOUT ! while 1: ! try: ! _pid, status = os.waitpid(pid, os.WNOHANG) ! except os.error: ! os.kill(pid, signal.SIGKILL) ! time.sleep(0.5) ! try: ! os.waitpid(pid, os.WNOHANG) ! except os.error: ! pass ! break ! if pid == _pid: ! answer = fr.read() ! break ! else: ! timeout -= 1 ! if not timeout: ! answer = ["Couldn't wait for your answer.", ! "Processing your answer took too long.", ! "I'm in a hurry and can't wait for " ! "your answer."] ! os.kill(pid, signal.SIGKILL) ! time.sleep(0.5) ! try: ! os.waitpid(pid, os.WNOHANG) ! except os.error: ! pass ! break ! time.sleep(1) ! return answer ! ! def eval(self, msg, expr): ! answer = self.fork_eval(expr) ! if not answer: ! msg.answer("%:", ["Can't evaluate this", ! "There's something wrong with this " ! "expression"], [".", "!"]) ! elif len(answer) > 255: ! msg.answer("%:", "Your answer is too long", [".", "!"]) ! else: ! msg.answer("%:", answer) ! def message(self, msg): if not msg.forme: *************** *** 87,101 **** if m: if mm.hasperm(msg, "eval"): ! try: ! answer = str(eval(m.group("expr"), self.dict)) ! except: ! msg.answer("%:", ["Can't evaluate this", ! "There's something wrong with this " ! "expression"], [".", "!"]) ! else: ! if len(answer) > 255: ! msg.answer("%:", "Sorry, your answer is too long...") ! else: ! msg.answer("%:", str(answer)) else: msg.answer("%:", ["Sorry...", "Oops!"], --- 171,175 ---- if m: if mm.hasperm(msg, "eval"): ! thread.start_new_thread(self.eval, (msg, m.group("expr"))) else: msg.answer("%:", ["Sorry...", "Oops!"], |
From: Gustavo N. <nie...@us...> - 2003-08-29 00:39:03
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv29720 Modified Files: ChangeLog README Log Message: * modules/eval.py: Implemented a forking/timeout scheme to protect against DoS evaluations. Now it should be possible to give wider access to the module. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** ChangeLog 28 Aug 2003 01:21:49 -0000 1.35 --- ChangeLog 29 Aug 2003 00:38:56 -0000 1.36 *************** *** 1,2 **** --- 1,7 ---- + 2003-08-28 Gustavo Niemeyer <nie...@co...> + * modules/eval.py: Implemented a forking/timeout scheme to + protect against DoS evaluations. Now it should be possible + to give wider access to the module. + 2003-08-27 Gustavo Niemeyer <nie...@co...> * modules/permissions.py: Implemented permission parameters. *************** *** 8,12 **** * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. ! * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. --- 13,17 ---- * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. ! * modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. Index: README =================================================================== RCS file: /cvsroot/pybot/pybot/README,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** README 25 Aug 2003 18:54:54 -0000 1.5 --- README 29 Aug 2003 00:38:56 -0000 1.6 *************** *** 154,156 **** --- 154,160 ---- flexible way. + - weather + Module which retrieves weather information from any station available + at the NOAA. + vim:st=4:sw=4:et |
From: Gustavo N. <nie...@us...> - 2003-08-28 21:03:16
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv22797/pybot/modules Modified Files: infopack.py Log Message: When searching, use pattern.search() and not pattern.match(). Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** infopack.py 28 Aug 2003 20:44:01 -0000 1.14 --- infopack.py 28 Aug 2003 21:01:34 -0000 1.15 *************** *** 212,216 **** def _search(self, pattern, key, values, results): found = 0 ! if pattern.match(key): found = 1 value = random.choice(values) --- 212,216 ---- def _search(self, pattern, key, values, results): found = 0 ! if pattern.search(key): found = 1 value = random.choice(values) *************** *** 219,223 **** random.shuffle(values) for value in values: ! if pattern.match(value[1]): found = 1 break --- 219,223 ---- random.shuffle(values) for value in values: ! if pattern.search(value[1]): found = 1 break |
From: Gustavo N. <nie...@us...> - 2003-08-28 20:44:18
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv18686 Modified Files: infopack.py Log Message: Included "search" command in help. Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** infopack.py 27 Aug 2003 18:03:42 -0000 1.13 --- infopack.py 28 Aug 2003 20:44:01 -0000 1.14 *************** *** 32,38 **** users/channels and servers will be able to obtain information from it. To do that give the permission "infopack(<name>)" for these you ! want to allow. To show which infopacks are loaded, send me ! "show infopacks". You can also ask for help about some specific ! infopack with "help infopack <name>". """ --- 32,41 ---- users/channels and servers will be able to obtain information from it. To do that give the permission "infopack(<name>)" for these you ! want to allow. ! """,""" ! To show which infopacks are loaded send me "show infopacks"; to ! search for information inside an infopack send me "search infopack ! <name> for /<regexp>/", and to ask for help about some specific ! infopack use "help infopack <name>". """ |
From: Gustavo N. <nie...@us...> - 2003-08-28 12:37:42
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv21239 Modified Files: weather.py Log Message: Fixing minor bug introduced when fixing cloud information. Index: weather.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/weather.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** weather.py 28 Aug 2003 12:34:55 -0000 1.4 --- weather.py 28 Aug 2003 12:37:36 -0000 1.5 *************** *** 70,74 **** r.getISOTime())) if r.getSkyConditions(): ! l.append("%s," % r.getSkyConditions()[0].lower()) l.append("temperature of %.2fC (%.2fF)," % (r.getTemperatureCelsius(), --- 70,74 ---- r.getISOTime())) if r.getSkyConditions(): ! l.append("%s," % r.getSkyConditions().lower()) l.append("temperature of %.2fC (%.2fF)," % (r.getTemperatureCelsius(), |
From: Gustavo N. <nie...@us...> - 2003-08-28 12:35:02
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv20746 Modified Files: weather.py Log Message: Cloud information is not always available. Index: weather.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/weather.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** weather.py 28 Aug 2003 12:23:33 -0000 1.3 --- weather.py 28 Aug 2003 12:34:55 -0000 1.4 *************** *** 69,73 **** r.getStationCountry(), station.upper(), r.getISOTime())) ! l.append("%s," % r.extractCloudInformation()[0].lower()) l.append("temperature of %.2fC (%.2fF)," % (r.getTemperatureCelsius(), --- 69,74 ---- r.getStationCountry(), station.upper(), r.getISOTime())) ! if r.getSkyConditions(): ! l.append("%s," % r.getSkyConditions()[0].lower()) l.append("temperature of %.2fC (%.2fF)," % (r.getTemperatureCelsius(), |
From: Gustavo N. <nie...@us...> - 2003-08-28 12:23:48
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv19159 Modified Files: weather.py Log Message: And another minor typo. :-/ Index: weather.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/weather.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** weather.py 28 Aug 2003 12:19:38 -0000 1.2 --- weather.py 28 Aug 2003 12:23:33 -0000 1.3 *************** *** 76,80 **** (r.getWindSpeed(), r.getWindCompass())) l.append("visibility of %.2fkm." % (r.getWindSpeed())) ! msg.answer("%", " ".join(l)) else: msg.answer("%:", ["You have no permission for that", --- 76,80 ---- (r.getWindSpeed(), r.getWindCompass())) l.append("visibility of %.2fkm." % (r.getWindSpeed())) ! msg.answer("%:", " ".join(l)) else: msg.answer("%:", ["You have no permission for that", |
From: Gustavo N. <nie...@us...> - 2003-08-28 12:19:45
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv18546/modules Modified Files: weather.py Log Message: Fixed small typo. Index: weather.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/weather.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** weather.py 28 Aug 2003 01:21:50 -0000 1.1 --- weather.py 28 Aug 2003 12:19:38 -0000 1.2 *************** *** 80,84 **** msg.answer("%:", ["You have no permission for that", "You are not allowed to do this", ! "You can show weather"], [".", "!"]) return 0 --- 80,84 ---- msg.answer("%:", ["You have no permission for that", "You are not allowed to do this", ! "You can't show weather"], [".", "!"]) return 0 |
From: Gustavo N. <nie...@us...> - 2003-08-28 01:21:57
|
Update of /cvsroot/pybot/pybot/pybot/util In directory sc8-pr-cvs1:/tmp/cvs-serv23210/pybot/util Added Files: pymetar.py Log Message: * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. --- NEW FILE: pymetar.py --- # Copyright (C) 2002 Tobias Klausmann # Modified by Jerome Alet # Code contributed by Jerome Alet and Davide Di Blasi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # By reading this code you agree not to ridicule the author =) import string import re import urllib2 import types import math, fpformat __author__ = "kla...@tu..." __version__ = "0.5" __doc__ = """Pymetar v%s (c) 2002 Tobias Klausman Pymetar is a python module and command line tool designed to fetch Metar reports from the NOAA (http://www.noaa.gov) and allow access to the included weather information. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Please e-mail bugs to: %s""" % (__version__, __author__) # # What a boring list to type ! # # It seems the NOAA doesn't want to return plain text, but considering the # format of their response, this is not to save bandwidth :-) # _WeatherConditions = { "DZ" : ("Drizzle", "rain", { "" : "Moderate drizzle", "-" : "Light drizzle", "+" : "Heavy drizzle", "VC" : "Drizzle in the vicinity", "MI" : "Shallow drizzle", "BC" : "Patches of drizzle", "PR" : "Partial drizzle", "TS" : ("Thunderstorm", "storm"), "BL" : "Windy drizzle", "SH" : "Showers", "DR" : "Drifting drizzle", "FZ" : "Freezing drizzle", }), "RA" : ("Rain", "rain", { "" : "Moderate rain", "-" : "Light rain", "+" : "Heavy rain", "VC" : "Rain in the vicinity", "MI" : "Shallow rain", "BC" : "Patches of rain", "PR" : "Partial rainfall", "TS" : ("Thunderstorm", "storm"), "BL" : "Blowing rainfall", "SH" : "Rain showers", "DR" : "Drifting rain", "FZ" : "Freezing rain", }), "SN" : ("Snow", "snow", { "" : "Moderate snow", "-" : "Light snow", "+" : "Heavy snow", "VC" : "Snow in the vicinity", "MI" : "Shallow snow", "BC" : "Patches of snow", "PR" : "Partial snowfall", "TS" : ("Snowstorm", "storm"), "BL" : "Blowing snowfall", "SH" : "Snowfall showers", "DR" : "Drifting snow", "FZ" : "Freezing snow", }), "SG" : ("Snow grains", "snow", { "" : "Moderate snow grains", "-" : "Light snow grains", "+" : "Heavy snow grains", "VC" : "Snow grains in the vicinity", "MI" : "Shallow snow grains", "BC" : "Patches of snow grains", "PR" : "Partial snow grains", "TS" : ("Snowstorm", "storm"), "BL" : "Blowing snow grains", "SH" : "Snow grain showers", "DR" : "Drifting snow grains", "FZ" : "Freezing snow grains", }), "IC" : ("Ice crystals", "snow", { "" : "Moderate ice crystals", "-" : "Few ice crystals", "+" : "Heavy ice crystals", "VC" : "Ice crystals in the vicinity", "BC" : "Patches of ice crystals", "PR" : "Partial ice crystals", "TS" : ("Ice crystal storm", "storm"), "BL" : "Blowing ice crystals", "SH" : "Showers of ice crystals", "DR" : "Drifting ice crystals", "FZ" : "Freezing ice crystals", }), "PE" : ("Ice pellets", "snow", { "" : "Moderate ice pellets", "-" : "Few ice pellets", "+" : "Heavy ice pellets", "VC" : "Ice pellets in the vicinity", "MI" : "Shallow ice pellets", "BC" : "Patches of ice pellets", "PR" : "Partial ice pellets", "TS" : ("Ice pellets storm", "storm"), "BL" : "Blowing ice pellets", "SH" : "Showers of ice pellets", "DR" : "Drifting ice pellets", "FZ" : "Freezing ice pellets", }), "GR" : ("Hail", "rain", { "" : "Moderate hail", "-" : "Light hail", "+" : "Heavy hail", "VC" : "Hail in the vicinity", "MI" : "Shallow hail", "BC" : "Patches of hail", "PR" : "Partial hail", "TS" : ("Hailstorm", "storm"), "BL" : "Blowing hail", "SH" : "Hail showers", "DR" : "Drifting hail", "FZ" : "Freezing hail", }), "GS" : ("Small hail", "rain", { "" : "Moderate small hail", "-" : "Light small hail", "+" : "Heavy small hail", "VC" : "Small hail in the vicinity", "MI" : "Shallow small hail", "BC" : "Patches of small hail", "PR" : "Partial small hail", "TS" : ("Small hailstorm", "storm"), "BL" : "Blowing small hail", "SH" : "Showers of small hail", "DR" : "Drifting small hail", "FZ" : "Freezing small hail", }), "UP" : ("Precipitation", "rain", { "" : "Moderate precipitation", "-" : "Light precipitation", "+" : "Heavy precipitation", "VC" : "Precipitation in the vicinity", "MI" : "Shallow precipitation", "BC" : "Patches of precipitation", "PR" : "Partial precipitation", "TS" : ("Unknown thunderstorm", "storm"), "BL" : "Blowing precipitation", "SH" : "Showers, type unknown", "DR" : "Drifting precipitation", "FZ" : "Freezing precipitation", }), "BR" : ("Mist", "fog", { "" : "Moderate mist", "-" : "Light mist", "+" : "Thick mist", "VC" : "Mist in the vicinity", "MI" : "Shallow mist", "BC" : "Patches of mist", "PR" : "Partial mist", "BL" : "Mist with wind", "DR" : "Drifting mist", "FZ" : "Freezing mist", }), "FG" : ("Fog", "fog", { "" : "Moderate fog", "-" : "Light fog", "+" : "Thick fog", "VC" : "Fog in the vicinity", "MI" : "Shallow fog", "BC" : "Patches of fog", "PR" : "Partial fog", "BL" : "Fog with wind", "DR" : "Drifting fog", "FZ" : "Freezing fog", }), "FU" : ("Smoke", "fog", { "" : "Moderate smoke", "-" : "Thin smoke", "+" : "Thick smoke", "VC" : "Smoke in the vicinity", "MI" : "Shallow smoke", "BC" : "Patches of smoke", "PR" : "Partial smoke", "TS" : ("Smoke w/ thunders", "storm"), "BL" : "Smoke with wind", "DR" : "Drifting smoke", }), "VA" : ("Volcanic ash", "fog", { "" : "Moderate volcanic ash", "+" : "Thick volcanic ash", "VC" : "Volcanic ash in the vicinity", "MI" : "Shallow volcanic ash", "BC" : "Patches of volcanic ash", "PR" : "Partial volcanic ash", "TS" : ("Volcanic ash w/ thunders", "storm"), "BL" : "Blowing volcanic ash", "SH" : "Showers of volcanic ash", "DR" : "Drifting volcanic ash", "FZ" : "Freezing volcanic ash", }), "SA" : ("Sand", "fog", { "" : "Moderate sand", "-" : "Light sand", "+" : "Heavy sand", "VC" : "Sand in the vicinity", "BC" : "Patches of sand", "PR" : "Partial sand", "BL" : "Blowing sand", "DR" : "Drifting sand", }), "HZ" : ("Haze", "fog", { "" : "Moderate haze", "-" : "Light haze", "+" : "Thick haze", "VC" : "Haze in the vicinity", "MI" : "Shallow haze", "BC" : "Patches of haze", "PR" : "Partial haze", "BL" : "Haze with wind", "DR" : "Drifting haze", "FZ" : "Freezing haze", }), "PY" : ("Sprays", "fog", { "" : "Moderate sprays", "-" : "Light sprays", "+" : "Heavy sprays", "VC" : "Sprays in the vicinity", "MI" : "Shallow sprays", "BC" : "Patches of sprays", "PR" : "Partial sprays", "BL" : "Blowing sprays", "DR" : "Drifting sprays", "FZ" : "Freezing sprays", }), "DU" : ("Dust", "fog", { "" : "Moderate dust", "-" : "Light dust", "+" : "Heavy dust", "VC" : "Dust in the vicinity", "BC" : "Patches of dust", "PR" : "Partial dust", "BL" : "Blowing dust", "DR" : "Drifting dust", }), "SQ" : ("Squall", "storm", { "" : "Moderate squall", "-" : "Light squall", "+" : "Heavy squall", "VC" : "Squall in the vicinity", "PR" : "Partial squall", "TS" : "Thunderous squall", "BL" : "Blowing squall", "DR" : "Drifting squall", "FZ" : "Freezing squall", }), "SS" : ("Sandstorm", "fog", { "" : "Moderate sandstorm", "-" : "Light sandstorm", "+" : "Heavy sandstorm", "VC" : "Sandstorm in the vicinity", "MI" : "Shallow sandstorm", "PR" : "Partial sandstorm", "TS" : ("Thunderous sandstorm", "storm"), "BL" : "Blowing sandstorm", "DR" : "Drifting sandstorm", "FZ" : "Freezing sandstorm", }), "DS" : ("Duststorm", "fog", { "" : "Moderate duststorm", "-" : "Light duststorm", "+" : "Heavy duststorm", "VC" : "Duststorm in the vicinity", "MI" : "Shallow duststorm", "PR" : "Partial duststorm", "TS" : ("Thunderous duststorm", "storm"), "BL" : "Blowing duststorm", "DR" : "Drifting duststorm", "FZ" : "Freezing duststorm", }), "PO" : ("Dustwhirls", "fog", { "" : "Moderate dustwhirls", "-" : "Light dustwhirls", "+" : "Heavy dustwhirls", "VC" : "Dustwhirls in the vicinity", "MI" : "Shallow dustwhirls", "BC" : "Patches of dustwhirls", "PR" : "Partial dustwhirls", "BL" : "Blowing dustwhirls", "DR" : "Drifting dustwhirls", }), "+FC" : ("Tornado", "storm", { "" : "Moderate tornado", "+" : "Raging tornado", "VC" : "Tornado in the vicinity", "PR" : "Partial tornado", "TS" : "Thunderous tornado", "BL" : "Tornado", "DR" : "Drifting tornado", "FZ" : "Freezing tornado", }), "FC" : ("Funnel cloud", "fog", { "" : "Moderate funnel cloud", "-" : "Light funnel cloud", "+" : "Thick funnel cloud", "VC" : "Funnel cloud in the vicinity", "MI" : "Shallow funnel cloud", "BC" : "Patches of funnel cloud", "PR" : "Partial funnel cloud", "BL" : "Funnel cloud w/ wind", "DR" : "Drifting funnel cloud", }), } # # RegExps to extract the different parts from the Metar encoded report TIME_RE_STR = r"^([0-9]{6})Z$" WIND_RE_STR = r"^(([0-9]{3})|VRB)([0-9]?[0-9]{2})(G[0-9]?[0-9]{2})?KT$" VIS_RE_STR = r"^(([0-9]?[0-9])|(M?1/[0-9]?[0-9]))SM$" CLOUD_RE_STR= r"^(CLR|SKC|BKN|SCT|FEW|OVC)([0-9]{3})?$" TEMP_RE_STR = r"^(M?[0-9][0-9])/(M?[0-9][0-9])$" PRES_RE_STR = r"^(A|Q)([0-9]{4})$" COND_RE_STR = r"^(-|\\+)?(VC|MI|BC|PR|TS|BL|SH|DR|FZ)?(DZ|RA|SN|SG|IC|PE|GR|GS|UP|BR|FG|FU|VA|SA|HZ|PY|DU|SQ|SS|DS|PO|\\+?FC)$" class DownloadError(RuntimeError): pass class MetarReport: """ This class provides a means to download and parse the decoded METAR reports from http://weather.noaa.gov/ In order to find the report relevant for you, find the closest station at http://www.nws.noaa.gov/oso/siteloc.shtml and feed its 4-letter station code to fetchMetarReport(), case does not matter. All methods return metric values, no matter what the station provides. The conversion factors were taken from the excellent "units" program. If None is returned that means the information wasn't available or could not be parsed. If you have the suspicion that failure to parse an information was this libs fault, please save the report generating the error send it to me with a few lines detailing the problem. Thanks! """ def match_WeatherPart(self, regexp) : """ Returns the matching part of the encoded Metar report. regexp: the regexp needed to extract this part. Returns the first matching string or None. WARNING: Some Metar reports may contain several matching strings, only the first one is taken into account, e.g. FEW020 SCT075 BKN053 """ if self.code is not None : rg = re.compile(regexp) for wpart in self.getRawMetarCode().split() : match = rg.match(wpart) if match : return match.string[match.start(0) : match.end(0)] def extractSkyConditions(self) : """ Extracts sky condition information from the encoded report. Returns a tuple containing the description of the sky conditions as a string and a suggested pixmap name for an icon representing said sky condition. """ wcond = self.match_WeatherPart(COND_RE_STR) if wcond is not None : if (len(wcond) > 3) and (wcond.startswith('+') or wcond.startswith('-')) : wcond = wcond[1:] if wcond.startswith('+') or wcond.startswith('-') : pphen = 1 elif len(wcond) < 4 : pphen = 0 else : pphen = 2 squal = wcond[:pphen] sphen = wcond[pphen : pphen + 4] phenomenon = _WeatherConditions.get(sphen, None) if phenomenon is not None : (name, pixmap, phenomenon) = phenomenon pheninfo = phenomenon.get(squal, name) if type(pheninfo) != types.TupleType : return (pheninfo, pixmap) else : # contains pixmap info return pheninfo def parseLatLong(self, latlong): """ Parse Lat or Long in METAR notation into float values. N and E are +, S and W are -. Expects one positional string and returns one float value. """ # I know, I could invert this if and put # the rest of the function into its block, # but I find this to be more readable if latlong is None: return None s = string.strip(string.upper(latlong)) elms = string.split(s,'-') ud = elms[-1][-1] elms[-1] = elms[-1][:-1] elms = map(string.atoi, elms) coords = 0.0 elen = len(elms) if elen > 2: coords = coords + float(elms[2])/3600.0 if elen > 1: coords = coords + float(elms[1])/60.0 coords=coords + float(elms[0]) if ud in ('W','S'): coords=-1.0*coords f,i=math.modf(coords) if elen > 2: f=float(fpformat.sci(f,4)) elif elen > 1: f=float(fpformat.sci(f,2)) else: f=0.0 return f+i def extractCloudInformation(self) : """ Extracts cloud information. returns None or a tuple (sky type as a string of text and suggested pixmap name) """ wcloud = self.match_WeatherPart(CLOUD_RE_STR) if wcloud is not None : stype = wcloud[:3] if (stype == "CLR") or (stype == "SKC") : return ("Clear sky", "sun") elif stype == "BKN" : return ("Broken clouds", "suncloud") elif stype == "SCT" : return ("Scattered clouds", "suncloud") elif stype == "FEW" : return ("Few clouds", "suncloud") elif stype == "OVC" : return ("Overcast", "cloud") def getFullReport(self): """ Return the complete weather report. """ return self.fullreport def getTemperatureCelsius(self): """ Return the temperature in degrees Celsius. """ return self.temp def getTemperatureFahrenheit(self): """ Return the temperature in degrees Fahrenheit. """ return (self.temp * (9.0/5.0)) + 32.0 def getDewPointCelsius(self): """ Return dewpoint in degrees Celsius. """ return self.dewp def getDewPointFahrenheit(self): """ Return dewpoint in degrees Fahrenheit. """ return (self.dewp * (9.0/5.0)) + 32.0 def getWindSpeed(self): """ Return the wind speed in meters per second. """ return self.windspeed def getWindDirection(self): """ Return wind direction in degrees. """ return self.winddir def getWindCompass(self): """ Return wind direction as compass direction (e.g. NE or SSE) """ return self.windcomp def getVisibilityKilometers(self): """ Return visibility in km. """ return self.vis def getVisibilityMiles(self): """ Return visibility in miles. """ return self.vis / 1.609344 def getHumidity(self): """ Return relative humidity in percent. """ return self.humid def getPressure(self): """ Return pressure in hPa. """ return self.press def getRawMetarCode(self): """ Return the encoded weather report. """ return self.code def getWeather(self): """ Return short weather conditions """ return self.weather def getSkyConditions(self): """ Return sky conditions """ return self.sky def getStationName(self): """ Return full station name """ return self.fulln def getStationCity(self): """ Return city-part of station name """ return self.stat_city def getStationCountry(self): """ Return country-part of station name """ return self.stat_country def getCycle(self): """ Return cycle value. The cycle value is not the frequency or delay between observations but the "time slot" in which the observation was made. There are 24 cycle slots every day which usually last from N:45 to N+1:45. The cycle from 23:45 to 0:45 is cycle 0. """ return self.cycle def getStationPosition(self): """ Return latitude, longitude and altitude above sea level of station as a tuple. Some stations don't deliver altitude, for those, None is returned as altitude. The lat/longs are expressed as follows: xx-yyd where xx is degrees, yy minutes and d the direction. Thus 51-14N means 51 degrees, 14 minutes north. d may take the values N, S for latitues and W, E for longitudes. Latitude and Longitude may include seconds. Altitude is always given as meters above sea level, including a trailing M. Schipohl Int. Airport Amsterdam has, for example: ('52-18N', '004-46E', '-2M') Moenchengladbach (where I live): ('51-14N', '063-03E', None) If you need lat and long as float values, look at getStationPositionFloat() instead """ return (self.latitude, self.longitude, self.altitude) def getStationPositionFloat(self): """ Return latitude and longitude as float values in a tuple (lat,long,alt) """ return (self.latf,self.longf,self.altitude) def getStationLatitude(self) : """ Return the station's latitude in dd-mm[-ss]D format : dd : degrees mm : minutes ss : seconds D : direction (N, S, E, W) """ return self.latitude def getStationLatitudeFloat(self): """ Return latitude as a float """ return self.latf def getStationLongitude(self) : """ Return the station's longitude in dd-mm[-ss]D format : dd : degrees mm : minutes ss : seconds D : direction (N, S, E, W) """ return self.longitude def getStationLongitudeFloat(self): """ Return Longitude as a float """ return (self.longf) def getStationAltitude(self) : """ Return the station's altitude above the sea in meters. """ return self.altitude def getReportURL(self): """ Return the URL from which the report was fetched. """ return self.reporturl def getTime(self): """ Return the time when the observation was made. Note that this is *not* the time when the report was fetched by us Format: YYYY.MM.DD HHMM UTC Example: 2002.04.01 1020 UTC """ return self.rtime def getISOTime(self): """ Return the time when the observation was made in ISO 8601 format (e.g. 2002-07-25 15:12:00Z) """ return(self.metar_to_iso8601(self.rtime)) def getPixmap(self): """ Return a suggested pixmap name, without extension, depending on current weather. """ return self.pixmap def metar_to_iso8601(self, metardate) : """ Converts a metar date to an ISO8601 date. """ if metardate is not None: (date, hour, tz) = metardate.split() (year, month, day) = date.split('.') # assuming tz is always 'UTC', aka 'Z' return "%s-%s-%s %s:%s:00Z" % (year, month, day, hour[:2], hour[2:4]) def strreverse(self, str): """ Reverses a string """ listr=list(str) listr.reverse() return (string.join(listr,"")) def __init__(self, MetarStationCode = None): """ Get initial report if a station code is passed as a parameter, otherwise initialize fields. """ if MetarStationCode is not None : self.fetchMetarReport(MetarStationCode) else : self._ClearAllFields() def _ClearAllFields(self): """ Clears all fields values. """ # until finished, report is invalid self.valid = 0 # Clear all self.fullreport=None self.temp=None self.windspeed=None self.winddir=None self.vis=None self.dewp=None self.humid=None self.press=None self.code=None self.weather=None self.sky=None self.fulln=None self.cycle=None self.windcomp=None self.rtime=None self.pixmap=None self.latitude=None self.longitude=None self.altitude=None self.stat_city=None self.stat_country=None self.reportutl=None self.latf=None self.longf=None def downloadReport(self, url): # Honor HTTP_PROXY environment var # Thanks to Davide Di Blasi for suggesting this urllib2.install_opener( urllib2.build_opener(urllib2.ProxyHandler, urllib2.HTTPHandler)) fn = urllib2.urlopen(url) # Dump entire report in a variable report = fn.read() if fn.info().status: raise DownloadError(url) fn.close() return report def fetchMetarReport(self, station, baseurl="http://weather.noaa.gov/pub/data/observations/metar/decoded/"): """ Retrieve the decoded METAR report from the given base URL and parse it. Fill the data properties in the class instance with the values found in the report, converting them to metric values where necessary. """ self._ClearAllFields() station=string.upper(station) self.reporturl="%s%s.TXT" % (baseurl, station) self.fullreport = self.downloadReport(self.reporturl) self.processReport(station, self.fullreport) def processReport(self, station, report): lines=string.split(report,"\n") for line in lines: # Most lines start with a Header and a colon try: header,data=string.split(line,":",1) except ValueError: header=data=line header=string.strip(header) data=string.strip(data) # The station identifier and location if (string.find(header,"("+station+")")!=-1): try: loc,p=string.split(data,"(",1) loc=string.strip(loc) rloc=self.strreverse(loc) rcoun,rcity=string.split(rloc,",",1) except ValueError: city="" coun="" p=data try: id,lat,long,ht=string.split(p," ") ht = int(ht[:-1]) # skip the 'M' for meters except ValueError: id,lat,long=string.split(p," ") ht=None self.stat_city=string.strip(self.strreverse(rcity)) self.stat_country=string.strip(self.strreverse(rcoun)) self.fulln=loc self.latitude = lat self.longitude = long self.latf=self.parseLatLong(lat) self.longf=self.parseLatLong(long) self.altitude = ht # The line containing the date/time of the report elif (string.find(data,"UTC")!=-1): local,rt=string.split(data,"/") self.rtime=string.strip(rt) # temperature elif (header=="Temperature"): t,i=string.split(data," ",1) self.temp=(float(t)-32)*(5.0/9.0) # wind direction and speed elif (header == "Wind"): if (string.find(data,"Calm")!=-1): self.windspeed=0.0 self.winddir=None self.windcomp=None elif (string.find(data,"Variable")!=-1): v,a,speed,r=string.split(data," ",3) self.windspeed=(float(speed)*0.44704) self.winddir=None self.windcomp=None else: f,t,comp,deg,r,d,speed,r=string.split(data," ",7) self.winddir=int(deg[1:]) self.windcomp=string.strip(comp) self.windspeed=(float(speed)*0.44704) # visibility elif (header=="Visibility"): for d in data.split() : try : self.vis = float(d)*1.609344 break except ValueError : pass # dew point elif (header=="Dew Point"): dp,i=string.split(data," ",1) self.dewp=(float(dp)-32)*(5.0/9.0) # humidity elif (header=="Relative Humidity"): h,i=string.split(data,"%",1) self.humid=int(h) # pressure elif (header=="Pressure (altimeter)"): p,r=string.split(data," ",1) self.press=(float(p)*33.863886) # short weather description ("rain", "mist", ...) elif (header=="Weather"): self.weather=data # short description of sky cond. elif (header=="Sky conditions"): self.sky=data # the encoded weather report elif (header=="ob"): self.code=string.strip(data) # the cycle value describes the cycle in # which the observations were made elif (header=="cycle"): self.cycle=int(data) # decode cloud and sky conditions informations from # the raw report, this will suggest us a pixmap to use # to graphically represent the weather. cloudinfo = self.extractCloudInformation() if cloudinfo is not None : (cloudinfo, cloudpixmap) = cloudinfo else : (cloudinfo, cloudpixmap) = (None, None) conditions = self.extractSkyConditions() if conditions is not None : (conditions, condpixmap) = conditions else : (conditions, condpixmap) = (None, None) # fill the weather information self.weather = self.weather or conditions or cloudinfo # Pixmap guessed from general conditions has priority # over pixmap guessed from clouds self.pixmap = condpixmap or cloudpixmap # report is complete self.valid = 1 |
From: Gustavo N. <nie...@us...> - 2003-08-28 01:21:57
|
Update of /cvsroot/pybot/pybot/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv23210/contrib Added Files: icao2info.py Log Message: * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. --- NEW FILE: icao2info.py --- #!/usr/bin/python # # Script to convert an ASCII file providing station codes # to a pybot infopack. # # The data file may be obtained from # # http://weather.noaa.gov/tg/site.shtml # def main(): for line in open("nsd_cccc.txt"): tokens = [x.strip() for x in line.split(";")] print "K:%s" % tokens[0] l = [] l.append(tokens[3]) # Location if tokens[4]: # State, for US only l.append(tokens[4]) if tokens[5]: # Country l.append(tokens[5]) if tokens[1] != "--": l.append("WMO block %s" % tokens[1]) if tokens[2] != "---": l.append("WMO station %s" % tokens[2]) l.append("WMO region %s" % tokens[6]) l.append("latitude %s" % tokens[7]) l.append("longitude %s" % tokens[8]) if tokens[9]: l.append("upper air latitude %s" % tokens[9]) if tokens[10]: l.append("upper air longitude %s" % tokens[10]) if tokens[11]: l.append("elevation of %sm" % tokens[11]) try: if tokens[12]: l.append("upper air elevation of %sm" % tokens[12]) if tokens[13] == "P": l.append("RBSN") except IndexError: pass print "V:tm:"+", ".join(l) if __name__ == "__main__": main() |
From: Gustavo N. <nie...@us...> - 2003-08-28 01:21:55
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv23210/data/infopacks Added Files: weather.info Log Message: * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. --- NEW FILE: weather.info --- # Infopack providing ICAO assigned weather station codes for pybot. # # This file has been generated using the file # # http://weather.noaa.gov/data/nsd_cccc.txt # # as documented in # # http://weather.noaa.gov/tg/site.shtml # h:weather stations:weather stations? H:The weather infopack provides a complete list of ICAO-assigned weather station codes. You can ask for some station information using "[show] weather station <code>". T:(?:show\s+)?weather\s+station\s+(\S+)\s*$ M:Station %(key)s is in %(value)s. M:Station %(key)s is located in %(value)s. D:t:I don't know any stations with that code. D:t:Sorry, I don't know anything about this station. K:AGGH V:tm:Honiara / Henderson, Solomon Islands, WMO block 91, WMO station 520, WMO region 5, latitude 09-25S, longitude 160-03E, elevation of 8m, upper air elevation of 9m, RBSN [...12684 lines suppressed...] K:ZWHM V:tm:Hami, China, WMO block 52, WMO station 203, WMO region 2, latitude 42-49N, longitude 093-31E, upper air latitude 42-49N, upper air longitude 093-31E, elevation of 739m, upper air elevation of 739m K:ZWSH V:tm:Kashi, China, WMO block 51, WMO station 709, WMO region 2, latitude 39-28N, longitude 075-59E, upper air latitude 39-28N, upper air longitude 075-59E, elevation of 1291m, upper air elevation of 1291m K:ZWTN V:tm:Hotan, China, WMO block 51, WMO station 828, WMO region 2, latitude 37-08N, longitude 079-56E, upper air latitude 37-08N, upper air longitude 079-56E, elevation of 1375m, upper air elevation of 1375m K:ZWWW V:tm:Urum-Qi / Diwopu, China, WMO region 2, latitude 43-54N, longitude 087-28E, elevation of 654m K:ZWYN V:tm:Yining, China, WMO block 51, WMO station 431, WMO region 2, latitude 43-57N, longitude 081-20E, upper air latitude 43-57N, upper air longitude 081-20E, elevation of 663m, upper air elevation of 663m K:ZYCC V:tm:Changchun, China, WMO block 54, WMO station 161, WMO region 2, latitude 43-54N, longitude 125-13E, upper air latitude 43-54N, upper air longitude 125-13E, elevation of 238m, upper air elevation of 238m K:ZYHB V:tm:Harbin, China, WMO region 2, latitude 46-01-12N, longitude 126-34-48E K:ZYQQ V:tm:Qiqihar, China, WMO block 50, WMO station 745, WMO region 2, latitude 47-23N, longitude 123-55E, upper air latitude 47-23N, upper air longitude 123-55E, elevation of 148m, upper air elevation of 148m K:ZYTL V:tm:Dalian, China, WMO block 54, WMO station 662, WMO region 2, latitude 38-54N, longitude 121-38E, upper air latitude 38-59N, upper air longitude 121-38E, elevation of 97m, upper air elevation of 97m K:ZYTX V:tm:Shenyang / Taokian, China, WMO region 2, latitude 41-48N, longitude 123-24E, elevation of 35m |
From: Gustavo N. <nie...@us...> - 2003-08-28 01:21:55
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv23210 Modified Files: ChangeLog Log Message: * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** ChangeLog 27 Aug 2003 21:05:34 -0000 1.34 --- ChangeLog 28 Aug 2003 01:21:49 -0000 1.35 *************** *** 1,10 **** 2003-08-27 Gustavo Niemeyer <nie...@co...> ! * modules/permissions.py: Implemented permission ! parameters. ! * modules/{remoteinfo.py,infopack.py}: Adapted to ! work with premission parameters. * modules/infopack.py: Implemented infopack searching. ! * data/infopacks/rfc.info,contrib/rfcindex2info.py: ! Created infopack with an RFC index. 2003-08-26 Gustavo Niemeyer <nie...@co...> --- 1,14 ---- 2003-08-27 Gustavo Niemeyer <nie...@co...> ! * modules/permissions.py: Implemented permission parameters. ! * modules/{remoteinfo.py,infopack.py}: Adapted to work with ! premission parameters. * modules/infopack.py: Implemented infopack searching. ! * data/infopacks/rfc.info,contrib/rfcindex2info.py: Created ! infopack with an RFC index. ! * data/infopacks/weather.info,contrib/icao2info.py: Created ! infopack with weather station codes. ! * pybot/modules/weather.py: Implemented module using the ! pymetar.py module for consulting NOAA weather information ! from any station available there. 2003-08-26 Gustavo Niemeyer <nie...@co...> |
From: Gustavo N. <nie...@us...> - 2003-08-28 01:21:55
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv23210/pybot/modules Added Files: weather.py Log Message: * data/infopacks/weather.info,contrib/icao2info.py: Created infopack with weather station codes. * pybot/modules/weather.py: Implemented module using the pymetar.py module for consulting NOAA weather information from any station available there. --- NEW FILE: weather.py --- # Copyright (c) 2000-2003 Gustavo Niemeyer <nie...@co...> # # This file is part of pybot. # # pybot is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # pybot is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with pybot; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pybot.locals import * from pybot.util import pymetar HELP = """ You can check the weather condition at any station registered at the National Oceanic and Atmospheric Administration (NOAA). To do that, use the command "[show] weather [for|from|on|at|in] <code>", providing the four-letters code assigned by The ICAO to the station. You need the "weather" permission for that. """ PERM_WEATHER = """ The "weather" permission allows users check for weather conditions on serveral stations. For more information, check "help weather". """ class Weather: def __init__(self): hooks.register("Message", self.message) # [show] weather [for|from|on|at|in] <station> self.re1 = regexp(r"(?:show )?weather (?:for |from |on |at |in )?(?P<station>\S+?)") mm.register_help(r"weather", HELP, "weather") mm.register_perm("weather", PERM_WEATHER) def unload(self): hooks.unregister("Message", self.message) mm.unregister_help(HELP) mm.unregister_perm(PERM_WEATHER) def message(self, msg): if not msg.forme: return None m = self.re1.match(msg.line) if m: if mm.hasperm(msg, "weather"): station = m.group("station") try: r = pymetar.MetarReport(station) except: msg.answer("%:", "There was an error fetching " "weather information", [".", "!"]) else: l = [] l.append("Weather in %s, %s (%s), at %s:" % (r.getStationCity(), r.getStationCountry(), station.upper(), r.getISOTime())) l.append("%s," % r.extractCloudInformation()[0].lower()) l.append("temperature of %.2fC (%.2fF)," % (r.getTemperatureCelsius(), r.getTemperatureFahrenheit())) l.append("windspeed of %.2fkm/h (%s)," % (r.getWindSpeed(), r.getWindCompass())) l.append("visibility of %.2fkm." % (r.getWindSpeed())) msg.answer("%", " ".join(l)) else: msg.answer("%:", ["You have no permission for that", "You are not allowed to do this", "You can show weather"], [".", "!"]) return 0 def __loadmodule__(): global mod mod = Weather() def __unloadmodule__(): global mod mod.unload() del mod # vim:ts=4:sw=4:et |
From: Gustavo N. <nie...@us...> - 2003-08-27 21:05:55
|
Update of /cvsroot/pybot/pybot/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv3373/contrib Added Files: rfcindex2info.py Log Message: * data/infopacks/rfc.info,contrib/rfcindex2info.py: Created infopack with an RFC index. --- NEW FILE: rfcindex2info.py --- #!/usr/bin/python import re KEY = re.compile("(?P<key>\d+)\s+(?P<content>.+)$") MORE = re.compile("\s+(?P<content>.+)$") def main(): foundfirst = 0 for line in open("1rfc_index.txt"): m = KEY.match(line) if m: foundfirst = 1 print "K:"+m.group("key") print "V:tm:"+m.group("content"), continue if not foundfirst: continue m = MORE.match(line) if m: print m.group("content"), continue print if __name__ == "__main__": main() |
From: Gustavo N. <nie...@us...> - 2003-08-27 21:05:55
|
Update of /cvsroot/pybot/pybot In directory sc8-pr-cvs1:/tmp/cvs-serv3373 Modified Files: ChangeLog Log Message: * data/infopacks/rfc.info,contrib/rfcindex2info.py: Created infopack with an RFC index. Index: ChangeLog =================================================================== RCS file: /cvsroot/pybot/pybot/ChangeLog,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** ChangeLog 27 Aug 2003 17:08:13 -0000 1.33 --- ChangeLog 27 Aug 2003 21:05:34 -0000 1.34 *************** *** 5,8 **** --- 5,10 ---- work with premission parameters. * modules/infopack.py: Implemented infopack searching. + * data/infopacks/rfc.info,contrib/rfcindex2info.py: + Created infopack with an RFC index. 2003-08-26 Gustavo Niemeyer <nie...@co...> |
From: Gustavo N. <nie...@us...> - 2003-08-27 21:05:52
|
Update of /cvsroot/pybot/pybot/data/infopacks In directory sc8-pr-cvs1:/tmp/cvs-serv3373/data/infopacks Added Files: rfc.info Log Message: * data/infopacks/rfc.info,contrib/rfcindex2info.py: Created infopack with an RFC index. --- NEW FILE: rfc.info --- # Infopack providing index of RFCs for pybot. # # This file has been generated using the file 1rfc_index.txt. # h:rfcs:rfcs? H:The rfc infopack provides an index of RFCs. You can ask for an RFC using "rfc <number>". T:rfc\s*(\d+)\s*\?*\s*$ M:RFC%(key)s: %(value)s. D:t:I don't know any RFCs with this number. D:t:Sorry, I don't know anything about this RFC. K:0001 V:tm:Host Software. S. Crocker. Apr-07-1969. (Format: TXT=21088 bytes) (Status: UNKNOWN) K:0002 V:tm:Host software. B. Duvall. Apr-09-1969. (Format: TXT=17145 bytes) (Status: UNKNOWN) K:0003 V:tm:Documentation conventions. S.D. Crocker. Apr-09-1969. (Format: TXT=2323 bytes) (Obsoleted by RFC0010) (Status: UNKNOWN) K:0004 V:tm:Network timetable. E.B. Shapiro. Mar-24-1969. (Format: TXT=5933 bytes) (Status: UNKNOWN) K:0005 [...7119 lines suppressed...] K:3575 V:tm:IANA Considerations for RADIUS (Remote Authentication Dial In User Service). B. Aboba. July 2003. (Format: TXT=15539 bytes) (Updates RFC2865) (Status: PROPOSED STANDARD) K:3576 V:tm:Dynamic Authorization Extensions to Remote Authentication Dial In User Service (RADIUS). M. Chiba, G. Dommety, M. Eklund, D. Mitton, B. Aboba. July 2003. (Format: TXT=70027 bytes) (Status: INFORMATIONAL) K:3577 V:tm:Introduction to the Remote Monitoring (RMON) Family of MIB Modul. S. Waldbusser, R. Cole, C. Kalbfleisch, D. Romascanu. August 2003. (Format: TXT=68551 bytes) (Status: INFORMATIONAL) K:3578 V:tm:Mapping of Integrated Services Digital Network (ISDN) User Part (ISUP) Overlap Signalling to the Session Initiation Protocol (SIP). G. Camarillo, A. B. Roach, J. Peterson, L. Ong. August 2003. (Format: TXT=26667 bytes) (Status: PROPOSED STANDARD) K:3581 V:tm:An Extension to the Session Initiation Protocol (SIP) for Symmetric Response Routing. J. Rosenberg, H. Schulzrinne. August 2003. (Format: TXT=66133 bytes) (Status: PROPOSED STANDARD) K:3582 V:tm:Goals for IPv6 Site-Multihoming Architectures. J. Abley, B. Black, V. Gill. August 2003. (Format: TXT=17045 bytes) (Status: INFORMATIONAL) K:3584 V:tm:Coexistence between Version 1, Version 2, and Version 3 of the Internet-standard Network Management Framework. R. Frye, D. Levi, S. Routhier, B. Wijnen. August 2003. (Format: TXT=115222 bytes) (Obsoletes RFC2576) (Also BCP0074) (Status: BEST CURRENT PRACTICE) K:3585 V:tm:IPsec Configuration Policy Information Model. J. Jason, L. Rafalow, E. Vyncke. August 2003. (Format: TXT=187308 bytes) (Status: PROPOSED STANDARD) K:3586 V:tm:IP Security Policy (IPSP) Requirements. M. Blaze, A. Keromytis, M. Richardson, L. Sanchez. August 2003. (Format: TXT=22068 bytes) (Status: PROPOSED STANDARD) K:3587 V:tm:IPv6 Global Unicast Address Format. R. Hinden, S. Deering, E. Nordmark. August 2003. (Format: TXT=8783 bytes) (Obsoletes RFC2374) (Status: INFORMATIONAL) |
From: Gustavo N. <nie...@us...> - 2003-08-27 18:03:58
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv778/pybot/modules Modified Files: infopack.py Log Message: Protect infopack help with permissions. Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** infopack.py 27 Aug 2003 17:57:28 -0000 1.12 --- infopack.py 27 Aug 2003 18:03:42 -0000 1.13 *************** *** 303,314 **** msg.answer("%:", "There's no infopack with that name.") else: ! for line in help: ! msg.answer("%:", line) return 1 def help_match(self, msg, match): something = match.group("something") found = 0 ! for pack in self.packs.values(): if pack.help_match(something): found = 1 --- 303,323 ---- msg.answer("%:", "There's no infopack with that name.") else: ! if mm.hasperm(msg, "infopack", name): ! for line in help: ! msg.answer("%:", line) ! else: ! msg.answer("%:", ["You have no permission to use that" ! "infopack", ! "You can't use that infopack"], ! [".", "!"]) return 1 def help_match(self, msg, match): something = match.group("something") + allowed = mm.permparams(msg, "infopack") found = 0 ! for name, pack in self.packs.items(): ! if name not in allowed: ! continue if pack.help_match(something): found = 1 *************** *** 458,462 **** allowed = mm.permparams(msg, "infopack") - found = 0 for name, pack in self.packs.items(): --- 467,470 ---- |
From: Gustavo N. <nie...@us...> - 2003-08-27 17:57:34
|
Update of /cvsroot/pybot/pybot/pybot/modules In directory sc8-pr-cvs1:/tmp/cvs-serv32384/pybot/modules Modified Files: infopack.py Log Message: Fixed infopack module unloading. Index: infopack.py =================================================================== RCS file: /cvsroot/pybot/pybot/pybot/modules/infopack.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** infopack.py 27 Aug 2003 17:23:56 -0000 1.11 --- infopack.py 27 Aug 2003 17:57:28 -0000 1.12 *************** *** 292,296 **** hooks.unregister("Message", self.message) mm.unregister_help(HELP) ! mm.unregister_help(self.help) mm.unregister_perm("infopackadmin") --- 292,297 ---- hooks.unregister("Message", self.message) mm.unregister_help(HELP) ! mm.unregister_help(self.help_infopack) ! mm.unregister_help(self.help_match) mm.unregister_perm("infopackadmin") |