utils.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # -*- coding: utf-8 -*-
  2. """
  3. Copyright (C) 2017, Rodrigo Garcia.
  4. <strysg@riseup.net>
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU Affero Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU Affero General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. """
  16. # Utilidades en General
  17. import random
  18. import os
  19. import json
  20. def titulo_legible(titulo):
  21. '''
  22. Retorna la cadena `titulo' como una cadena legible, ej:
  23. red-indestructible-12
  24. Red indestructible 12
  25. '''
  26. titulo = titulo.split('posts/')[-1]
  27. titulo = titulo.split('Posts/')[-1]
  28. titulo = titulo.split('.md')[0]
  29. titulo = titulo[0].upper() + titulo[1:]
  30. return titulo.replace('-'," ")
  31. def captcha_pregunta_opciones_random():
  32. '''
  33. Retorna una tupla con la pregunta y opciones del
  34. archivo captchas.txt siguiendo el formato del archivo.
  35. (pregunta,[opciones])
  36. Devuelve None en caso de error
  37. '''
  38. with open("monomotapa/captchas.txt", "r") as fil:
  39. contenido = fil.read()
  40. lista = contenido.split("###")[1:]
  41. total = len(lista)
  42. indice = int(random.random()*(total))
  43. captcha = lista[indice]
  44. pregunta = "Letra con la que empieza hola"
  45. opciones = ['h','f','Z','N']
  46. respuestas = ['h']
  47. try:
  48. pregunta = captcha.split("\n")[1]
  49. opciones = captcha.split("\n")[2].split(",")
  50. return (pregunta, opciones)
  51. except:
  52. print ("Error en:"+captcha+"\n indice:"+str(indice))
  53. return ("Letra con la que empieza hola",['h','e','z'])
  54. return None
  55. def captcha_comprobar_respuesta(pregunta, respuesta):
  56. '''
  57. Comprueba si la respuesta a la pregunta dada es la correcta
  58. buscando en el archivo captchas.txt, devuelve True o False
  59. TODO: En caso de exito marcar el captcha como usado y rehabilitarlo luego
  60. de digamos 1 minuto.
  61. '''
  62. correcto = False
  63. if pregunta is None or respuesta is None:
  64. return False
  65. with open("monomotapa/captchas.txt", "r") as fil:
  66. contenido = fil.read()
  67. indice = contenido.find(pregunta)
  68. if indice != -1:
  69. aux = contenido[indice:]
  70. respuesta_correcta = aux.split("\n")[2]
  71. if respuesta_correcta == respuesta:
  72. correcto = True
  73. if correcto:
  74. return True
  75. return False
  76. def pregunta_captcha_random():
  77. '''
  78. Retorna una tupla con una pregunta al azar del archivo
  79. captchas.txt siguiendo el formato del archivo.
  80. El formato de la tupla es:
  81. (pregunta,[opciones],[respuestas])
  82. Devuelve None en caso de error
  83. '''
  84. with open("monomotapa/captchas.txt", "r") as fil:
  85. contenido = fil.read()
  86. lista = contenido.split("###")[1:]
  87. total = len(lista)
  88. indice = int(random.random()*(total))
  89. captcha = lista[indice]
  90. pregunta = "Letra con la que empieza hola"
  91. opciones = ['h','f','Z']
  92. respuestas = ['h']
  93. try:
  94. pregunta = captcha.split("\n")[1]
  95. opciones = captcha.split("\n")[2].split(",")
  96. respuestas = captcha.split("\n")[3].split(",")
  97. return (pregunta, opciones, respuestas)
  98. except:
  99. print ("Error en:"+captcha+"\n indice:"+str(indice))
  100. return ("Letra con la que empieza hola",['h','e','z'],['h'])
  101. return None
  102. def categorias_de_post(nombre=None):
  103. ''' Devuelve una lista con los nombres de las categorias a las
  104. que pertenece un post con nombre `nombre' '''
  105. categorias = []
  106. with open("monomotapa/src/posts/"+nombre, 'r') as fil:
  107. c = fil.readline() # primera linea con las categorias
  108. lc = c.split("[#")[1:]
  109. for cad in lc:
  110. cat = cad.split("]")[0]
  111. categorias.append(cat)
  112. return categorias
  113. return None
  114. def categoriasDePost(nombre=None):
  115. ''' Retorna la lista con los nombres de las categorias a las que
  116. pertenece un post de nombre `nombre'.
  117. Este metodo lee el archivo pages.json'''
  118. nombre = nombre.split('.md')[0]
  119. with open(os.path.join('monomotapa', 'pages.json'), 'r') as pagefile:
  120. json_pattrs = json.load(pagefile)
  121. if json_pattrs.get('posts/' + nombre, None) is not None:
  122. return json_pattrs['posts/' + nombre]['categorias']
  123. else:
  124. return []
  125. def categoriasList(categoria=None):
  126. ''' Retorna una lista con los nombres de posts y el numero de posts
  127. que pertenecen a la categoria dada o cada categoria
  128. Las categorias se obtienen del archivo pages.json.
  129. Si no se especifica `categoria' cada elemento de la lista devuelta es:
  130. (nombre_categoria, numero_posts, [nombres_posts])
  131. Si se especifica `categoria' cada elemento de la lista devuelta es:
  132. (numero_posts, [nombres_posts]
  133. '''
  134. json_pattrs = {}
  135. dict = {}
  136. with open(os.path.join('monomotapa', 'pages.json'), 'r') as pagefile:
  137. json_pattrs = json.load(pagefile)
  138. for key,value in json_pattrs.items():
  139. nombre = key.split('posts/')[-1]
  140. if value.get('categorias', None) is None:
  141. continue
  142. for cat in value['categorias']:
  143. if dict.get(cat, None) is None:
  144. dict[cat] = {
  145. 'contador': 1,
  146. 'posts': [nombre]
  147. }
  148. else:
  149. dict[cat]['contador'] += 1 # contador de post en categoria
  150. dict[cat]['posts'].append(nombre)
  151. lista = []
  152. for key, value in dict.items():
  153. if categoria is None:
  154. lista.append((key, value['contador'], value['posts']))
  155. elif key == categoria:
  156. lista = [value['contador'], value['posts']]
  157. return lista
  158. def cabezaPost(archivo , max_caracteres=250, categorias=True):
  159. """ Devuelve las primeras lineas de un archivo de post (en formato markdown)
  160. con un maximo numero de caracteres excluyendo titulos en la cabeza devuelta.
  161. Si se especifica `categorias' en True
  162. Se devuelve una lista de la forma:
  163. (cabeza_post, categorias)
  164. donde categorias son cadenas con los nombres de las categorias a la que
  165. pertenece el post
  166. """
  167. cabeza_post = ""
  168. cats = []
  169. with open(os.path.join("monomotapa/src/posts",archivo)) as file:
  170. cats = categoriasDePost(archivo)
  171. # analizando si hay titulos al principio
  172. for linea in file.readlines():
  173. # evitando h1, h2
  174. if linea.startswith("##") or linea.startswith("#"):
  175. cabeza_post += " "
  176. else:
  177. cabeza_post += linea
  178. if len(cabeza_post) >= max_caracteres:
  179. break
  180. cabeza_post = cabeza_post[0:max_caracteres-1]
  181. if categorias:
  182. return (cabeza_post, cats)
  183. return cabeza_post