spaces_matcher = re.compile(u"\s", flags=re.U)
def equivalence_partition(iterable, relation):
- """ Partitionne l'itérable en classes d'équivalences. """
- classes = []
- for o in iterable:
- # find the class it is in
- found = False
- for c in classes:
- if relation( iter(c).next(), o ): # is it equivalent to this class?
- c.add( o )
- found = True
- break
- if not found: # it is in a new class
- classes.append( set( [ o ] ) )
- return classes
+ """ Partitionne l'itérable en classes d'équivalences. """
+ classes = []
+ for o in iterable:
+ # find the class it is in
+ found = False
+ for c in classes:
+ if relation( iter(c).next(), o ): # is it equivalent to this class?
+ c.add( o )
+ found = True
+ break
+ if not found: # it is in a new class
+ classes.append( set( [ o ] ) )
+ return classes
def get_now():
""" Renvoie la date actuelle """
class Quote(object):
""" Une citation """
- def __init__(self, author, content, timestamp=None):
+ def __init__(self, author, content, timestamp=None, place=None, quoter=None):
if timestamp is None:
timestamp = get_now()
elif isinstance(timestamp, basestring):
self.author = sanitize_author(author)
self.content = content
self.timestamp = timestamp
+ self.place = place
+ self.quoter = quoter
def jsonize(self):
d = {"author" : self.author, "content" : self.content,
- "timestamp" : self.timestamp.strftime(u"%F_%T")}
+ "timestamp" : self.timestamp.strftime(u"%F_%T"),
+ "place" : self.proper_place, "quoter" : self.proper_quoter}
return d
+ def __get_proper_place(self):
+ """
+ property function pour récupérer ``self.place``
+ mais en virant None ou des chaînes ne contenant que des whitespace.
+ """
+ return self.place if self.place and self.place.strip() != u"" else u""
+ proper_place = property(__get_proper_place)
+
+ def __get_proper_quoter(self):
+ """
+ property function pour récupérer ``self.place``
+ mais en virant None ou des chaînes ne contenant que des whitespace.
+ """
+ return self.quoter if self.quoter and self.quoter.strip() != u"" else u""
+ proper_quoter = property(__get_proper_quoter)
+
def __unicode__(self):
""" Retourne la quote affichable """
return config.quote_template % self.__dict__
def __str__(self):
return unicode(self).encode("utf-8")
+ def display(self, show_context=False):
+ """
+ Retourne une chaîne contenant toujours la quote et l'auteur,
+ et le contexte ssi ``show_context = True``.
+ """
+ s = config.quote_template % self.__dict__
+ if show_context:
+ s = u"%s | %s" % (s, self.proper_place)
+ return s.encode("utf-8")
+
+ def full_str(self):
+ """ Retourne une chaîne représentant la totalité des infos de la quote,
+ tout en étant parsable et human-readable. """
+ s = u"%s %s | %s | %s" % (
+ self.timestamp.strftime("%F_%T"),
+ config.quote_template % self.__dict__,
+ self.proper_place,
+ self.proper_quoter)
+ return s.encode("utf-8")
+
def __eq__(self, otherquote):
""" Vérifie si cette phrase n'a pas déjà été dite par la même personne.
Indépendamment de la date et de la casse. """
return author
def get_clash_authors(self):
- """ Renvoie une liste de liste d'auteurs qui sont enresgitrés avec des casses différentes. """
+ """ Renvoie une liste de liste d'auteurs qui sont enregistrés avec des casses différentes. """
authors = list(set([q.author for q in self.quotelist]))
authors = equivalence_partition(authors, lambda x,y: x.lower() == y.lower())
authors = [list(c) for c in authors if len(c) > 1]
return authors
- def store(self, author, content, timestamp=None):
+ def store(self, timestamp=None, **kwargs):
""" Enregistre une nouvelle quote, sauf si elle existe déjà.
Force l'auteur à utiliser la même casse si un auteur de casse différente existait déjà.
Renvoie ``True`` si elle a été ajoutée, ``False`` si elle existait. """
- newquote = Quote(self._collapse_author(author), content, timestamp)
+ kwargs["author"] = self._collapse_author(kwargs["author"])
+ kwargs["timestamp"] = timestamp
+ newquote = Quote(**kwargs)
if not newquote in self.quotelist:
- self.search
self.quotelist.append(newquote)
return True
return False
def random(self):
""" Sort une quote aléatoire """
return random.choice(self.quotelist)
+
def quotesfrom(self, author):
""" Sort toutes les quotes de ``author`` """
return [q for q in self.quotelist if q.author == author]
return random.choice(self.quotesfrom(author))
def search(self, inquote=None, author=None, regexp=False):
- """Fait une recherche dans les quotes."""
- if regexp:
- if inquote is None:
- inquote = ".*"
- if author is None:
- author = ".*"
- qreg = re.compile(inquote, flags=re.UNICODE)
- areg = re.compile(author, flags=re.UNICODE)
- l = [q for q in self.quotelist if qreg.match(q.content) and areg.match(q.author)]
- else:
- if inquote is None:
- inquote = ""
- if author is None:
- author = ""
- l = [q for q in self.quotelist if inquote in q.content and author in q.author]
+ """
+ Fait une recherche dans les quotes.
+ C'est une conjonction de cas : on garde la quote si
+ ``inquote`` matche dans le contenu
+ *et* si ``author`` matche l'auteur
+
+ Si ``regexp=True``, utilise directement les termes comme des regexp.
+ """
+ params = [inquote, author]
+ regexps = []
+ for param in params:
+ if param is None:
+ param = u".*"
+ elif not regexp:
+ param = u".*%s.*" % param
+ regexps.append(re.compile(param, flags=re.UNICODE + re.IGNORECASE))
+ l = [q for q in self.quotelist if all([reg.match(truc) for (reg, truc) in zip(regexps, [q.content, q.author])])]
return l
def search_authors(self, author=None, regexp=False):
"""Renvoie la liste des auteurs contenant ``author`` ou qui matchent la regexp."""
- if regexp:
- if author is None:
- author = ".*"
- areg = re.compile(author, flags=re.UNICODE)
- l = list(set([q.author for q in self.quotelist if areg.match(q.author)]))
- else:
- if author is None:
- author = ""
- l = list(set([q.author for q in self.quotelist if author in q.author]))
+ if author is None:
+ author = u".*"
+ elif not regexp:
+ author = u".*%s.*" % author
+ areg = re.compile(author, flags=re.UNICODE + re.IGNORECASE)
+ l = list(set([q.author for q in self.quotelist if areg.match(q.author)]))
return l
def dump(quotedb, dump_file=None):
"""Pour exporter les quotes dans un format readable vers un fichier."""
if dump_file is None:
dump_file = config.quote_dump_file
- t = "\n".join(["%s %s" % (q.timestamp.strftime("%F_%T"), q) for q in quotedb.quotelist]) + "\n"
+ t = "\n".join([q.full_str() for q in quotedb.quotelist]) + "\n"
with open(dump_file, "w") as f:
f.write(t)