Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alkorgun/blacksmith-2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlKorgun@gmail.com <AlKorgun@gmail.com@94c44753-77e5-68b8-8764-2ca2b8acb85e>2011-11-22 23:42:10 +0400
committerAlKorgun@gmail.com <AlKorgun@gmail.com@94c44753-77e5-68b8-8764-2ca2b8acb85e>2011-11-22 23:42:10 +0400
commitb27b1d68580d7138c1fa4d44ae5e8c6294689313 (patch)
treecc55b8fbd0608178a7bce530a2bac96cb6239a08
parent11c01eb2311e9e9fafdc18629219802c0e97fa98 (diff)
cron added
-rw-r--r--BlackSmith.py12
-rw-r--r--expansions/cron/code.py251
-rw-r--r--expansions/cron/cron.en14
-rw-r--r--expansions/cron/cron.ru14
-rw-r--r--expansions/cron/insc.py26
-rw-r--r--expansions/extra_control/code.py46
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: