diff options
author | AlKorgun@gmail.com <AlKorgun@gmail.com@94c44753-77e5-68b8-8764-2ca2b8acb85e> | 2011-11-22 23:42:10 +0400 |
---|---|---|
committer | AlKorgun@gmail.com <AlKorgun@gmail.com@94c44753-77e5-68b8-8764-2ca2b8acb85e> | 2011-11-22 23:42:10 +0400 |
commit | b27b1d68580d7138c1fa4d44ae5e8c6294689313 (patch) | |
tree | cc55b8fbd0608178a7bce530a2bac96cb6239a08 | |
parent | 11c01eb2311e9e9fafdc18629219802c0e97fa98 (diff) |
cron added
-rw-r--r-- | BlackSmith.py | 12 | ||||
-rw-r--r-- | expansions/cron/code.py | 251 | ||||
-rw-r--r-- | expansions/cron/cron.en | 14 | ||||
-rw-r--r-- | expansions/cron/cron.ru | 14 | ||||
-rw-r--r-- | expansions/cron/insc.py | 26 | ||||
-rw-r--r-- | expansions/extra_control/code.py | 46 |
6 files changed, 334 insertions, 29 deletions
diff --git a/BlackSmith.py b/BlackSmith.py index 4126e49..eba4b71 100644 --- a/BlackSmith.py +++ b/BlackSmith.py @@ -250,7 +250,7 @@ GenConFile = static % ("config.ini") ConDispFile = static % ("clients.ini") ChatsFile = dynamic % ("chats.db") -(BsMark, BsVer, BsRev) = (2, 19, 0) +(BsMark, BsVer, BsRev) = (2, 20, 0) if os.access(SvnCache, os.R_OK): BsRev = open(SvnCache).readlines()[3].strip() @@ -1088,13 +1088,13 @@ def get_text(body, s0, s2, s1 = "(?:.|\s)+"): body = (body.group(1)).strip() return body -def sub_desc(body, ls, sbls = False): +def sub_desc(body, ls, sbls = None): if isinstance(ls, dict): for x, z in ls.items(): body = body.replace(x, z) else: for x in ls: - if isinstance(x, tuple) or isinstance(x, list): + if isinstance(x, (list, tuple)): if len(x) >= 2: body = body.replace(x[0], x[1]) else: @@ -1106,7 +1106,7 @@ def sub_desc(body, ls, sbls = False): strTime = lambda data = "%d.%m.%Y (%H:%M:%S)", local = True: time.strftime(data, time.localtime() if local else time.gmtime()) def Time2Text(Time): - ext, ls = [], [("Year", 0), ("Month", 12), ("Day", 30), ("Hour", 24), ("Minute", 60), ("Second", 60)] + ext, ls = [], [("Year", None), ("Day", 365.25), ("Hour", 24), ("Minute", 60), ("Second", 60)] while ls: lr = ls.pop() if lr[1]: @@ -1119,7 +1119,7 @@ def Time2Text(Time): return str.join(chr(32), ext) def Size2Text(Size): - ext, ls = [], list("TGMK.") + ext, ls = [], list("YZEPTGMK.") while ls: lr = ls.pop() if ls: @@ -1127,7 +1127,7 @@ def Size2Text(Size): else: Rest = Size if Rest: - ext.insert(0, "%d %sB." % (Rest, (lr if lr != "." else ""))) + ext.insert(0, "%d%sB" % (Rest, (lr if lr != "." else ""))) if not (ls and Size): return str.join(chr(32), ext) diff --git a/expansions/cron/code.py b/expansions/cron/code.py new file mode 100644 index 0000000..f460183 --- /dev/null +++ b/expansions/cron/code.py @@ -0,0 +1,251 @@ +# coding: utf-8 + +# BlackSmith mark.2 +exp_name = "cron" # /code.py v.x2 +# Id: 27~1a +# Code © (2010-2011) by WitcherGeralt [WitcherGeralt@rocketmail.com] + +expansion_register(exp_name) + +from calendar import mdays as Mdays + +CronFile = dynamic % ("cdesc.db") + +CronDesc, CronCounter = dict(), itypes.Number() + +def def_cron(): + exp_name = "cron" + + def exe_cron(command, instance, ls, repeat = ()): + inst = get_source(ls[1][1], ls[1][2]) + if inst == instance or (not inst or not instance): + gt = time.mktime(time.gmtime()) + rlen = len(repeat) + if rlen == 1 and (repeat[0] >= 360): + Answer(CronAnsBase[0] % (command), ls[0], ls[1], ls[3]) + Cmds[command].execute(*ls) + if rlen == 2: + seconds, repeats = (repeat) + if repeats.reduce(): + CronDesc[CronCounter.plus()] = ((seconds + gt), (command, instance, ls, repeat)) + + while VarCache["alive"]: + time.sleep(2) + if not expansions.has_key(exp_name): + break + Time = time.mktime(time.gmtime()) + for id, (date, ls) in CronDesc.items(): + if Time > date: + if Cmds.has_key(ls[0]): + sThread("command(cron)", exe_cron, ls) + del CronDesc[id] + +def getDate(ls, sft, sftime = "%H:%M:%S (%d.%m.%Y)"): + ls[5] += sft + while ls[5] >= 60: + ls[5] -= 60 + ls[4] += 1 + while ls[4] >= 60: + ls[4] -= 60 + ls[3] += 1 + while ls[3] >= 24: + ls[3] -= 24 + ls[2] += 1 + dn = Mdays[ls[1]] + while ls[2] > dn: + ls[2] -= dn + ls[1] += 1 + while ls[1] > 12: + ls[1] -= 11 + ls[0] += 1 + return time.strftime(sftime, time.struct_time(ls)) + +def add_cron(disp, ls, body, Te, source, ltype, gt, answer, repeat, **ext): + cmd = (ls.pop(0)).lower() + if Cmds.has_key(cmd): + if enough_access(source[1], source[2], Cmds[cmd].access): + if ls: + body = body[((body.lower()).find(cmd) + (len(cmd) + 1)):].strip() + else: + body = "" + if 1024 >= len(body): + Time = time.mktime(gt) + instance = get_source(source[1], source[2]) + CronDesc[CronCounter.plus()] = ((Te + Time), (cmd, instance, (ltype, source, body, get_disp(disp)), repeat)) + cdesc_save() + else: + answer = AnsBase[5] + else: + answer = AnsBase[10] + else: + answer = AnsBase[6] + return answer + +def command_cron(ltype, source, body, disp): + gt = time.gmtime() + if body: + ls = body.split() + if len(ls) >= 2: + Mode = (ls.pop(0)).lower() + if Mode in ("stop", "стоп".decode("utf-8")): + id = ls.pop(0) + if isNumber(id): + id = int(id) + if CronDesc.has_key(id): + if enough_access(source[1], source[2], 7): + del CronDesc[id] + answer = AnsBase[4] + else: + date, ls = CronDesc.get(id) + if ls[1] == get_source(source[1], source[2]): + del CronDesc[id] + answer = AnsBase[4] + else: + answer = AnsBase[10] + else: + answer = CronAnsBase[1] % (id) + else: + answer = AnsBase[30] + elif Mode in ("cycled", "цикл".decode("utf-8")): + if len(ls) >= 3: + Te = ls.pop(0) + Tr = ls.pop(0) + if isNumber(Te) and isNumber(Tr): + Te, Tr = int(Te), int(Tr) + if Te <= 240 and Tr > 4: + answer = CronAnsBase[2] + elif 59 < Te and Te*Tr <= 4147200 or enough_access(source[1], source[2], 7): + t_ls, repeat = [Te], (Te, itypes.Number(Tr)) + for x in xrange(1, Tr): + t_ls.append(t_ls[-1] + Te) + ltls = len(t_ls) + t_ls = enumerated_list([getDate(list(gt), Tx) for Tx in t_ls[:8]]) + if ltls > 8: + t_ls += CronAnsBase[3] % (ltls - 8) + answer = CronAnsBase[4] % (t_ls) + answer = add_cron(**locals()) + else: + answer = CronAnsBase[5] + else: + answer = AnsBase[30] + else: + answer = AnsBase[2] + elif Mode in ("date", "дата".decode("utf-8")): + if len(ls) >= 2: + date = list(gt) + Te = ls.pop(0) + Te = Te.split("&") + date[6], date[7], date[8] = 0, 0, 0 + Time = Te.pop(0) + Time = Time.split(":") + try: + date[3] = int(Time.pop(0)) + if Time: + date[4] = int(Time.pop(0)) + if Time: + date[5] = int(Time.pop(0)) + else: + date[5] = 0 + else: + date[4], date[5] = 0, 0 + except: + answer = AnsBase[2] + else: + Date = (Te.pop(0) if Te else None) + if Date: + Date = Date.split(".") + try: + date[2] = int(Date.pop(0)) + if Date: + date[1] = int(Date.pop(0)) + if Date: + date[0] = int(Date.pop(0)) + except: + answer = AnsBase[2] + if not locals().has_key(Types[12]): + try: + date = time.struct_time(date) + except: + answer = AnsBase[2] + else: + Time, Te = time.mktime(gt), time.mktime(date) + if Te > Time: + Te = (Te - Time) + if 59 < Te <= 4147200 or enough_access(source[1], source[2], 7): + repeat = (Te,) + answer = CronAnsBase[6] % time.strftime("%H:%M:%S (%d.%m.%Y)", date) + answer = add_cron(**locals()) + else: + answer = CronAnsBase[5] + else: + answer = AnsBase[2] + else: + answer = AnsBase[2] + elif isNumber(Mode): + Te = int(Mode) + if 59 < Te <= 4147200 or enough_access(source[1], source[2], 7): + repeat = (Te,) + answer = CronAnsBase[6] % getDate(list(gt), Te) + answer = add_cron(**locals()) + else: + answer = CronAnsBase[5] + else: + answer = AnsBase[2] + else: + answer = AnsBase[2] + elif not CronDesc: + answer = CronAnsBase[7] + else: + Te = time.mktime(gt) + ls = [] + for id, (date, desc) in CronDesc.items(): + if date > Te: + line = "%d (%s) [%s]" % (id, desc[0], getDate(list(gt), int(date - Te))) + ls.append(line) + answer = CronAnsBase[8] % enumerated_list(sorted(ls)) + Answer(answer, ltype, source, disp) + +def start_cron(): + Name = def_cron.func_name + for Thr in iThr.enumerate(): + if Thr._Thread__name.startswith(Name): + Thr.kill() + if initialize_file(CronFile, "({}, 0)"): + cdesc, ccnt = eval(get_file(CronFile)) + Time = time.mktime(time.gmtime()) + for id, (date, ls) in cdesc.items(): + if Time > date: + del cdesc[id] + elif len(ls[3]) == 2: + command, instance, ls__, repeat = ls + seconds, repeats = repeat + repeat = (seconds, itypes.Number(repeats)) + ls = (command, instance, ls__, repeat) + cdesc[id] = (date, ls) + CronDesc.update(cdesc) + CronCounter.__init__(ccnt) + composeThr(def_cron, Name).start() + +def cdesc_save(conf = None): + if not conf: + cdesc = CronDesc.copy() + for id, (date, ls) in cdesc.items(): + command, instance, ls__, repeat = ls + if len(repeat) == 2: + seconds, repeats = repeat + repeat = (seconds, int(repeats)) + ltype, source, body, disp = ls__ + one, two, three = source + source = (str(one), two, three) + ls__ = (ltype, source, body, disp) + ls = (command, instance, ls__, repeat) + cdesc[id] = (date, ls) + cat_file(CronFile, str((cdesc, int(CronCounter)))) + +expansions[exp_name].funcs_add([def_cron, getDate, add_cron, command_cron, start_cron, cdesc_save]) +expansions[exp_name].ls.extend(["CronAnsBase", "Mdays", "CronDesc", "CronCounter"]) + +command_handler(command_cron, {"RU": "хрон", "EN": "cron"}, 5, exp_name) + +handler_register(start_cron, "02si", exp_name) +handler_register(cdesc_save, "03si", exp_name) diff --git a/expansions/cron/cron.en b/expansions/cron/cron.en new file mode 100644 index 0000000..18ec5da --- /dev/null +++ b/expansions/cron/cron.en @@ -0,0 +1,14 @@ +scheduler (all times are in UTC)
+cron ([timeout] [command] (parameters))/([cycled] [timeout] [cycles] [command] (parameters))/([date] [[hour]:(minute):(second)(&[day].(month).(year))] [command] (parameters))/([stop] [ID_of_task])
+*/cron
+bot would show all scheduled tasks
+*/cron 60 ping Some_User
+bot would ping "Some_User" after 60 seconds
+*/cron cycled 360 4 test
+bot would execute 'test' 4 times with a timeout in 6 minutes
+*/cron date 21&27 clear
+bot would clean the conference on the 27th of current month at 21:00 (UTC)
+*/cron date 18:40:20&02.12 Ping
+bot would ping you on 2nd December at 18:40:20 (UTC)
+*/cron stop 47
+bot would stop the task with ID=47
\ No newline at end of file diff --git a/expansions/cron/cron.ru b/expansions/cron/cron.ru new file mode 100644 index 0000000..69a434f --- /dev/null +++ b/expansions/cron/cron.ru @@ -0,0 +1,14 @@ +планировщик заданий (все даты указаны в UTC)
+хрон ([тайм-аут] [команда] (параметры))/([цикл] [тайм-аут] [кол-во_циклов] [команда] (параметры))/([дата] [[час]:(минута):(секунда)(&[день].(месяц).(год))] [команда] (параметры))/([стоп] [ID_таймера])
+*/хрон
+бот покажет все запланированные задания
+*/хрон 60 пинг Some_User
+бот пропингует "Some_User" через 60 секунд
+*/хрон цикл 360 4 цитата
+бот 4 раза покажет новую цитату с таймаутом в 6 минут
+*/хрон дата 21&27 чисть
+бот почистит конференцию 27го числа текущего месяца в 21:00 (UTC)
+*/хрон дата 18:40:20&02.12 пинг
+бот пропингует вас 2го декабря в 18:40:20 (UTC)
+*/хрон стоп 47
+бот удалит задание под идентификатором 47
\ No newline at end of file diff --git a/expansions/cron/insc.py b/expansions/cron/insc.py new file mode 100644 index 0000000..5be3941 --- /dev/null +++ b/expansions/cron/insc.py @@ -0,0 +1,26 @@ +# coding: utf-8 + +if DefLANG in ("RU", "UA"): + CronAnsBase = tuple([line.decode("utf-8") for line in ( + "Ты просил выполнить «%s».", # 0 + "Нет задания с ID'ом «%d».", # 1 + "Слишком быстро и часто. (при количестве циклов большем 4х - тайм-аут должен превышать 4 минуты)", # 2 + "\n+ ещё %d раз.", # 3 + "Выполню в:\n%s", # 4 + "Тайм-аут не может быть меньше минуты и больше 48 дней.", # 5 + "Выполню в %s", # 6 + "Нет запланированных заданий.", # 7 + "\n[№][ID][Команда][Deadline]\n%s" # 8 + )]) +else: + CronAnsBase = ( + "You asked to execute '%s'.", # 0 + "There is no task with ID '%d'.", # 1 + "Too quickly and often. (when the number of cycles greater than 4 - timeout must exceed 4 minutes)", # 2 + "\n+ %d more times.", # 3 + "It will be executed at:\n%s", # 4 + "The timeout can't be less than 60 seconds and more than 48 days.", # 5 + "It will be executed at %s", # 6 + "There are no tasks.", # 7 + "\n[#][ID][Command][Deadline]\n%s" # 8 + )
\ No newline at end of file diff --git a/expansions/extra_control/code.py b/expansions/extra_control/code.py index 540fc39..aaca546 100644 --- a/expansions/extra_control/code.py +++ b/expansions/extra_control/code.py @@ -1,8 +1,8 @@ # coding: utf-8 # BlackSmith mark.2 -exp_name = "extra_control" # /code.py v.x5 -# Id: 01~3a +exp_name = "extra_control" # /code.py v.x6 +# Id: 01~4a # Code © (2009-2011) by WitcherGeralt [WitcherGeralt@rocketmail.com] expansion_register(exp_name) @@ -10,9 +10,9 @@ expansion_register(exp_name) def command_remote(ltype, source, body, disp): confs = sorted(Chats.keys()) if body: - list = body.split() - if len(list) >= 3: - x = list[0].lower() + ls = body.split() + if len(ls) >= 3: + x = (ls.pop(0)).lower() if x in confs: conf = x elif isNumber(x): @@ -24,29 +24,29 @@ def command_remote(ltype, source, body, disp): else: conf = False if conf: - itype = list[1].lower() - if itype in [Types[14], Types[0]]: + itype = (ls.pop(0)).lower() + if itype in (Types[14], Types[0]): type2 = Types[1] - elif itype in [Types[15], Types[6]]: + elif itype in (Types[15], Types[6]): type2 = Types[0] else: type2 = False if type2: - command = list[2].lower() - if len(list) >= 4: - Parameters = body[((body.lower()).find(command) + (len(command) + 1)):].strip() + cmd = (ls.pop(0)).lower() + if ls: + body = body[((body.lower()).find(cmd) + (len(cmd) + 1)):].strip() else: - Parameters = "" - if len(Parameters) <= 1024: - if Cmds.has_key(command): - self = Cmds[command] + body = "" + if 1024 >= len(body): + if Cmds.has_key(cmd): + self = Cmds[cmd] if self.isAvalable and self.handler: Info["cmd"].plus() if type2 == Types[1]: disp_ = Chats[conf].disp else: disp_ = get_disp(disp) - sThread("command", self.handler, (type2, (source[0], conf, source[2]), Parameters, disp_), self.name) + sThread("command", self.handler, (type2, (source[0], conf, source[2]), body, disp_), self.name) self.numb.plus() source = get_source(source[1], source[2]) if source and source not in self.desc: @@ -71,14 +71,14 @@ def command_remote(ltype, source, body, disp): def command_private(ltype, source, body, disp): if Chats.has_key(source[1]): if body: - list = body.split() - command = (list.pop(0)).lower() - if Cmds.has_key(command): - if list: - Parameters = body[((body.lower()).find(command) + (len(command) + 1)):].strip() + ls = body.split() + cmd = (ls.pop(0)).lower() + if Cmds.has_key(cmd): + if ls: + body = body[((body.lower()).find(cmd) + (len(cmd) + 1)):].strip() else: - Parameters = "" - Cmds[command].execute(Types[0], source, Parameters, disp) + body = "" + Cmds[cmd].execute(Types[0], source, body, disp) else: answer = AnsBase[6] else: |