From 43090914e360f9e6188123982440eb13d141a663 Mon Sep 17 00:00:00 2001 From: Vincent Le Gallic Date: Sun, 7 Apr 2013 18:09:24 +0200 Subject: [PATCH] =?utf8?q?Initialisation=20du=20d=C3=A9p=C3=B4t?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 ++ today.py | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 303 insertions(+) create mode 100644 .gitignore create mode 100755 today.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96e56c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.pyc +lasts +birthdays.txt +timers.txt +.lasttime +.something + diff --git a/today.py b/today.py new file mode 100755 index 0000000..be2c99c --- /dev/null +++ b/today.py @@ -0,0 +1,296 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" Codé par 20-100 + script qui affiche des trucs à penser, des J-n des conneries + or that kind of stuff""" + +import time, datetime +import re +import os +import sys +import urllib +import subprocess +import json +os.chdir('/home/vincent/scripts/today/') + + +class Config(object): + """Configuration (pas de couleurs si on n'output pas dans un terminal""" + def __init__(self, color=True): + if color: + self.endcolor = "" + self.blue = "" + self.red = "" + self.green = "" + else: + self.endcolor=self.blue=self.red=self.green="" + +if "--color" in sys.argv: + sys.argv.remove("--color") + color = True +elif sys.stdout.isatty(): + color = True +else: + color = False + +config = Config(color=color) + +def print_date(timestamp=None,color=True): + """Afficher la date""" + if timestamp == None: + timestamp = time.time() + return time.strftime(" "*30 + config.blue+"%d/%m/%Y %H:%M:%S"+config.endcolor + "\n", + time.localtime(timestamp)) + +def add_title(titre, texte): + """Ajoute un titre à la partie si il y a quelque chose dedans""" + if texte: + texte = " %s%s :%s\n" % (config.green, titre, config.endcolor) + texte + "\n" + return texte + +def get_now(): + """Obtenir la date actuelle sous le bon format""" + timestamp = time.time() + now = datetime.datetime(*time.localtime(timestamp)[:7]) + return now + +def get_lasts(): + """Récupère la liste des derniers trucs vus/lus""" + with open("lasts") as f: + return json.loads(f.read()) + +def update_lasts(what, value): + """Met à jour un des derniers trucs vus/lus""" + lasts = get_lasts() + if not what in lasts.keys(): + print """%r n'est pas un "truc vu/lu" valide""" % (what,) + return + lasts[what] = value + with open("lasts", "w") as f: + f.write(json.dumps(lasts)) + +def get_timers(): + """Obtenir la liste des évènements à venir (J-n)""" + now = get_now() + f=open("timers.txt", "r") + data = [l.strip("\n").decode("utf8") for l in f.readlines()[1:]] + f.close() + timers = [] + for l in data: + date, event = l.split("\t",1) + date = datetime.datetime(*time.strptime(date,"%d/%m/%Y")[:7]) + delta = date - now + datetime.timedelta(1) + if delta > datetime.timedelta(0): + timers.append([event,delta.days]) + eventsize = max([0]+[len(l[0]) for l in timers]) + timers = "\n".join([("%%-%ss J-%%s" % eventsize) % (event, timer) for event,timer in timers]) + timers = add_title("Timers", timers) + return timers + +def exists(l): + """Renvoie True si au moins un élément de l est vrai""" + for i in l: + if i: + return True + return False + +def get_birthdays(*search): + """Obtenir la liste des anniversaires à venir, + ou la liste des anniversaires correspondants à une recherche""" + now = get_now() + text = open("birthdays.txt","r").readlines() + liste = [l.decode("utf8").split() for l in text if not l.startswith("#")] + liste = [[l[0], " ".join(l[1:])] for l in liste if l!=[]] + liste = [ [datetime.datetime(*time.strptime(l[0],"%d/%m/%Y")[:7]), + l[1]] + for l in liste] + birthdays = [] + if len(search) == 0: + # Simple demande d'anniversaires courants + for date, nom in liste: + thisyeardate = datetime.datetime(now.year, date.month, date.day) + delta = thisyeardate - now + datetime.timedelta(1) + if delta > datetime.timedelta(0): + age = now.year - date.year + if abs(delta) < datetime.timedelta(1): + birthdays.append([config.red,"%s a %s ans AUJOURD'HUI !"%(nom,age),0,config.endcolor]) + elif delta < datetime.timedelta(7): + birthdays.append([config.red,"%s va avoir %s ans"%(nom,age),-delta.days,config.endcolor]) + elif delta < datetime.timedelta(14): + birthdays.append(["","%s va avoir %s ans"%(nom,age),-delta.days,""]) + elif datetime.timedelta(30-4) < delta < datetime.timedelta(30+4): + birthdays.append(["","%s va avoir %s ans"%(nom,age),-delta.days,""]) + else: + # Recherche spécifique + search = [i.lower() for i in search] + tous = ("--all" in search) + for date, nom in liste: + if tous or exists([term.lower() in nom.lower() for term in search]): + thisyeardate = datetime.datetime(now.year, date.month, date.day) + delta = thisyeardate - now + datetime.timedelta(1) + age = now.year - date.year + if delta.days<0: + birthdays.append(["", "%s a eu %s ans"%(nom,age), -delta.days, ""]) + else: + birthdays.append(["", "%s va avoir %s ans"%(nom,age), -delta.days, ""]) + birthdays.sort(lambda x,y: -cmp(x[2], y[2])) + eventsize = max([0]+[len(l[1]) for l in birthdays]) + template = ("%%s%%-%ss J%%+d%%s" % eventsize) + birthdays = "\n".join([template % tuple(tup) for tup in birthdays]) + birthdays = add_title("Anniversaires", birthdays) + return birthdays + +def check_birthdays(): + """Compte combien il y a d'anniversaires à afficher""" + birthdays = get_birthdays() + if birthdays: + n = birthdays.count("\n") - 1 + else: + n = 0 + return n + +def get_dtc(*args): + """Récupère les quotes DTC non lues""" + if len(args) == 0: + cmd = "~/bin/dtc last" + elif len(args) == 1: + cmd = "~/bin/dtc %s" % args[0] + elif len(args) == 2: + cmd = "~/bin/dtc %s %s" % (args[0], args[1]) + else: + return None + proc = subprocess.Popen(["ssh", "pimeys", cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = proc.communicate() + out += err + return out.decode("UTF-8") + +def check_dtc(): + """Vérifie si il y a des quotes DTC non lues""" + cmd = "~/bin/dtc check" + proc = subprocess.Popen(["ssh", "pimeys", cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = proc.communicate() + out += err + if err: + return err + n = int(out) + return n + +def check_xkcd(): + last_read = get_lasts()["xkcd"] + try: + p = urllib.urlopen("http://xkcd.com") + except IOError: + return "Impossible de se connecter à xkcd" + t = p.read() + current_id = int(re.findall("Permanent link to this comic: http://xkcd.com/(.*?)/", t)[0]) + return current_id - last_read + +def update_xkcd(newid): + update_lasts("xkcd", int(newid)) + + +def check_all(): + n_birth = check_birthdays() + n_dtc = check_dtc() + n_xkcd = check_xkcd() + l = [["Anniversaires", n_birth], + ["Quotes DTC", n_dtc], + ["XKCD non lus", n_xkcd]] + checks = [] + for (text, n) in l: + if type(n) != int: + print n + elif n > 0: + checks.append("%s : %s" % (text, n)) + checks = "\n".join(checks) + checks = add_title("Checks", checks) + return checks + +def get_everything(): + """Récupère toutes les infos""" + work = [action() for action in AUTOMATED_ACTIONS.values()] + chain = "\n\n".join([result for result in work if result]) + return chain + +def _is_there_something_in_today(): + """Teste si il y a des choses non lue dans le today""" + return open(".something", "r").read() == "True" + +def _there_is_something_in_today(something): + """Met à jour le something""" + f = open(".something", "w") + f.write(str(bool(something))) + f.close() + +def _get_lasttime(): + """Récupère la dernière fois que today a été exécuté""" + lasttime = open(".lasttime", "r").read() + lasttime = datetime.datetime(*time.localtime(float(lasttime))[:7]) + return lasttime + +def _update_lasttime(when): + """Met à jour le timestamp de dernière exécution de today""" + f = open(".lasttime", "w") + f.write(str(time.mktime(when.timetuple()))) + f.close() + +def ping(): + """Dit juste si il y a quelque chose à voir. + La première exécution de la journée peut être lente parce qu'elle va bosser avnt de répondre.""" + now = get_now() + lasttime = _get_lasttime() + if (lasttime.date() < now.date()): + # On a changé de jour + _update_lasttime(now) + something = get_everything() + _there_is_something_in_today(something) + if something: + return "You have something in %stoday%s" % (config.red, config.endcolor) + else: + return "Nothing in today" + else: + if _is_there_something_in_today(): + return "You have something in %stoday%s" % (config.red, config.endcolor) + +def affiche(): + """Action par défaut, affiche toutes les infos""" + out = print_date() + out += get_everything() + _there_is_something_in_today(False) + return out + +#: Les actions effectuées lors d'un appel sans paramètres +AUTOMATED_ACTIONS = { + "timers" : get_timers, + "birth" : get_birthdays, + "check" : check_all, + } + +#: Les actions qu'on peut effectuer en rajoutant des paramètres +OTHER_ACTIONS = { + "xkcd" : update_xkcd, + "dtc" : get_dtc, + "ping" : ping, + "show" : affiche, + } + +#: Toutes les actions +ACTIONS = dict(AUTOMATED_ACTIONS) +ACTIONS.update(OTHER_ACTIONS) + +ACTIONS[None] = affiche # action par défaut + +if __name__ == "__main__": + import sys + if "--no-color" in sys.argv: + config.endcolor, config.red, config.blue = "","","" + if len(sys.argv) == 1: + # Juste un today + output = ACTIONS[None]() + else: + commande = sys.argv[1] + args = sys.argv[2:] + output = ACTIONS[commande](*args) + if output: + print output.encode("utf-8") -- 2.39.2