utils.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. import datetime as dt
  21. def titulo_legible(titulo):
  22. '''
  23. Retorna la cadena `titulo' como una cadena legible, ej:
  24. red-indestructible-12
  25. Red indestructible 12
  26. '''
  27. titulo = titulo.split('posts/')[-1]
  28. titulo = titulo.split('Posts/')[-1]
  29. titulo = titulo.split('.md')[0]
  30. titulo = titulo[0].upper() + titulo[1:]
  31. return titulo.replace('-'," ")
  32. def captcha_pregunta_opciones_random():
  33. '''
  34. Retorna una tupla con la pregunta y opciones del
  35. archivo captchas.txt siguiendo el formato del archivo.
  36. (pregunta,[opciones])
  37. Devuelve None en caso de error
  38. '''
  39. with open("monomotapa/captchas.txt", "r") as fil:
  40. contenido = fil.read()
  41. lista = contenido.split("###")[1:]
  42. total = len(lista)
  43. indice = int(random.random()*(total))
  44. captcha = lista[indice]
  45. pregunta = "Letra con la que empieza hola"
  46. opciones = ['h','f','Z','N']
  47. random.shuffle(opciones)
  48. respuestas = ['h']
  49. try:
  50. pregunta = captcha.split("\n")[1]
  51. opciones = captcha.split("\n")[2].split(",")
  52. random.shuffle(opciones)
  53. return (pregunta, opciones)
  54. except:
  55. print ("Captcha Error en:"+captcha+"\n indice:"+str(indice))
  56. return ("Letra con la que empieza hola",['h','e','z'])
  57. return None
  58. def captcha_comprobar_respuesta(pregunta, respuesta):
  59. '''
  60. Comprueba si la respuesta a la pregunta dada es la correcta
  61. buscando en el archivo captchas.txt, devuelve True o False
  62. TODO: En caso de exito marcar el captcha como usado y rehabilitarlo luego
  63. de digamos 1 minuto.
  64. '''
  65. correcto = False
  66. if pregunta is None or respuesta is None:
  67. return False
  68. with open("monomotapa/captchas.txt", "r") as fil:
  69. contenido = fil.read()
  70. indice = contenido.find(pregunta)
  71. if indice != -1:
  72. aux = contenido[indice:]
  73. respuesta_correcta = aux.split("\n")[2]
  74. if respuesta_correcta == respuesta:
  75. correcto = True
  76. if correcto:
  77. return True
  78. return False
  79. def pregunta_captcha_random():
  80. '''
  81. Retorna una tupla con una pregunta al azar del archivo
  82. captchas.txt siguiendo el formato del archivo.
  83. El formato de la tupla es:
  84. (pregunta,[opciones],[respuestas])
  85. Devuelve None en caso de error
  86. '''
  87. with open("monomotapa/captchas.txt", "r") as fil:
  88. contenido = fil.read()
  89. lista = contenido.split("###")[1:]
  90. total = len(lista)
  91. indice = int(random.random()*(total))
  92. captcha = lista[indice]
  93. pregunta = "Letra con la que empieza hola"
  94. opciones = ['h','f','Z']
  95. respuestas = ['h']
  96. try:
  97. pregunta = captcha.split("\n")[1]
  98. opciones = captcha.split("\n")[2].split(",")
  99. respuestas = captcha.split("\n")[3].split(",")
  100. return (pregunta, opciones, respuestas)
  101. except:
  102. print ("Error en:"+captcha+"\n indice:"+str(indice))
  103. return ("Letra con la que empieza hola",['h','e','z'],['h'])
  104. return None
  105. def categorias_de_post(nombre=None):
  106. ''' Devuelve una lista con los nombres de las categorias a las
  107. que pertenece un post con nombre `nombre' '''
  108. categorias = []
  109. with open("monomotapa/src/posts/"+nombre, 'r') as fil:
  110. c = fil.readline() # primera linea con las categorias
  111. lc = c.split("[#")[1:]
  112. for cad in lc:
  113. cat = cad.split("]")[0]
  114. categorias.append(cat)
  115. return categorias
  116. return None
  117. def categoriasDePost(nombre=None):
  118. ''' Retorna la lista con los nombres de las categorias a las que
  119. pertenece un post de nombre `nombre'.
  120. Este metodo lee el archivo pages.json'''
  121. nombre = nombre.split('.md')[0]
  122. with open(os.path.join('monomotapa', 'pages.json'), 'r') as pagefile:
  123. json_pattrs = json.load(pagefile)
  124. if json_pattrs.get('posts/' + nombre, None) is not None:
  125. return json_pattrs['posts/' + nombre]['categorias']
  126. else:
  127. return []
  128. def categoriasList(categoria=None):
  129. ''' Retorna una lista con los nombres de posts y el numero de posts
  130. que pertenecen a la categoria dada o cada categoria
  131. Las categorias se obtienen del archivo pages.json.
  132. Si no se especifica `categoria' cada elemento de la lista devuelta es:
  133. (nombre_categoria, numero_posts, [nombres_posts])
  134. Si se especifica `categoria' cada elemento de la lista devuelta es:
  135. (numero_posts, [nombres_posts]
  136. '''
  137. json_pattrs = {}
  138. dict = {}
  139. with open(os.path.join('monomotapa', 'pages.json'), 'r') as pagefile:
  140. json_pattrs = json.load(pagefile)
  141. for key,value in json_pattrs.items():
  142. nombre = key.split('posts/')[-1]
  143. if value.get('categorias', None) is None:
  144. continue
  145. for cat in value['categorias']:
  146. if dict.get(cat, None) is None:
  147. dict[cat] = {
  148. 'contador': 1,
  149. 'posts': [nombre]
  150. }
  151. else:
  152. dict[cat]['contador'] += 1 # contador de post en categoria
  153. dict[cat]['posts'].append(nombre)
  154. lista = []
  155. for key, value in dict.items():
  156. if categoria is None:
  157. lista.append((key, value['contador'], value['posts']))
  158. elif key == categoria:
  159. lista = [value['contador'], value['posts']]
  160. return lista
  161. def cabezaPost(archivo , max_caracteres=250, categorias=True):
  162. """ Devuelve las primeras lineas de un archivo de post (en formato markdown)
  163. con un maximo numero de caracteres excluyendo titulos en la cabeza devuelta.
  164. Si se especifica `categorias' en True
  165. Se devuelve una lista de la forma:
  166. (cabeza_post, categorias)
  167. donde categorias son cadenas con los nombres de las categorias a la que
  168. pertenece el post
  169. """
  170. cabeza_post = ""
  171. cats = []
  172. with open(os.path.join("monomotapa/src/posts",archivo)) as file:
  173. cats = categoriasDePost(archivo)
  174. # analizando si hay titulos al principio
  175. for linea in file.readlines():
  176. # evitando h1, h2
  177. if linea.startswith("##") or linea.startswith("#"):
  178. cabeza_post += " "
  179. else:
  180. cabeza_post += linea
  181. if len(cabeza_post) >= max_caracteres:
  182. break
  183. cabeza_post = cabeza_post[0:max_caracteres-1]
  184. if categorias:
  185. return (cabeza_post, cats)
  186. return cabeza_post
  187. def metaTagsAutomaticos(nombreArchivo, atributos):
  188. ''' Extrae información básica de los atributos del post y los agrega en
  189. el atributo `meta'.
  190. -- return lista meta con las propiedades llenadas
  191. '''
  192. meta = []
  193. title = ''
  194. summary = ''
  195. if not isinstance(atributos.get('attributes', ''), dict):
  196. atributos['attributes'] = {}
  197. summary = atributos['attributes'].get('summary', atributos.get('heading', 'otro post de Rodrigo Garcia Saenz'))
  198. title = atributos['attributes'].get('heading', atributos.get('title', 'otro post de Rodrigo Garcia Saenz'))
  199. meta.append({"tag": "name", "name":"description", "content":summary})
  200. meta.append({"tag": "property","name":"og:description", "content":summary})
  201. meta.append({"tag": "property","name":"og:title", "content":title})
  202. meta.append({"tag": "property","name":"og:type", "content":"web"})
  203. meta.append({"tag": "name","name":"twitter:card", "content":"summary"})
  204. meta.append({"tag": "name","name":"twitter:description", "content":summary})
  205. meta.append({"tag": "name","name":"twitter:title", "content":title})
  206. meta.append({"tag": "name","name":"twitter:site", "content": atributos['url_base']})
  207. meta.append({"tag": "name","name":"twitter:autor", "content": "@strymsg"})
  208. # keywords
  209. keywords = atributos.get('keywords', '')
  210. for categoria in atributos.get('categorias', []):
  211. keywords += ', ' + categoria
  212. meta.append({"tag": "name", "name":"keywords", "content":keywords})
  213. for keyword in keywords.split(','):
  214. meta.append({"tag":"property", "name": "article:tag", "content":keyword})
  215. meta.append({"tag":"name","name":"news_keywords", "content":keywords})
  216. # fechas
  217. date = ''
  218. date = atributos['attributes'].get('date', str(dt.datetime.now()))
  219. # imagenes
  220. imgCard = atributos['attributes'].get('image-card', '/static/imgs/cabecera1.png')
  221. meta.append({"tag":"itemprop", "name": "image", "content": imgCard})
  222. meta.append({"tag":"property", "name": "og:image", "content": imgCard})
  223. meta.append({"tag":"name", "name": "twitter:image:src", "content": atributos['url_base'] + imgCard})
  224. return meta