def test_remover_links_basico(self):
        tweet = Tweet()
        tweet.id = 19821138922184705
        tweet.texto = "FOTO CURIOSA: ¿Será culpa del arquitecto? ¿Tu que opinas?" \
                      + " http://losgraficos.com/fotos-imagenes-graciosas-1381.html #fb"
        tweet.favoritos = 5
        tweet.retweets = 26
        tweet.es_humor = 1
        tweet.cuenta = 174450359

        self.assertEqual(remover_links(tweet.texto),
                         "FOTO CURIOSA: ¿Será culpa del arquitecto? ¿Tu que opinas?  #fb",
                         "El texto sin el link no es el esperado")
    def test_remover_usuarios_con_acento(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "#ThankYou @clauditaa_love @vivirocha17 @jeanm23 @freddycastro19 @eleze12" \
                      + " @josférsp @vicenteanthonio Retuiters destacados de hoy, gracias!"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_usuarios(tweet.texto),
                         "#ThankYou        Retuiters destacados de hoy, gracias!",
                         "El texto sin los usuarios no es el esperado")
示例#3
0
    def test_escapar(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "3 Cosas que he aprendi en la escuela: Enviar WhatsApp's sin mirar. Dormir sin que me vean." \
                      + " El trabajo en equipo durante los exámenes."
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        freeling = Freeling(tweet)
        self.assertNotEqual(freeling.tokens, [], "Error de tokens vacíos")
示例#4
0
    def test_escapar(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "3 Cosas que he aprendi en la escuela: Enviar WhatsApp's sin mirar. Dormir sin que me vean." \
                      + " El trabajo en equipo durante los exámenes."
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        freeling = Freeling(tweet)
        self.assertNotEqual(freeling.tokens, [], "Error de tokens vacíos")
    def test_remover_hashtags_con_acento(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "#DíaMundialDelOrgasmoFemenino Lol Respeten un poco Este TT es igual como" \
                      + " si fuese #ILoveReggaeton Que gracia  siempre #CojenComoObjetoSexual"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_hashtags(tweet.texto),
                         " Lol Respeten un poco Este TT es igual como si fuese  Que gracia  siempre ",
                         "El texto sin los hashtags no es el esperado")
示例#6
0
    def test_remover_espacios_multiples_y_strip(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "RT    @laseptimabutaca: Trailer de \"Rápido y Furioso 6\"  que     se estrenará" \
                      + " en mayo de este año 2013  "
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_espacios_multiples_y_strip(tweet.texto),
                         "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará" \
                         + " en mayo de este año 2013",
                         "El texto sin los espacios múltiples y sin strip no es el esperado")
示例#7
0
    def test_remover_dos_links(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará en mayo de este año" \
                      + " 2013 http://t.co/tklxfuFx http://t.co/c5aS4hw2"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_links(tweet.texto),
                         "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará en mayo de este año" \
                         + " 2013  ",
                         "El texto sin los links no es el esperado")
示例#8
0
    def test_remover_links_basico(self):
        tweet = Tweet()
        tweet.id = 19821138922184705
        tweet.texto = "FOTO CURIOSA: ¿Será culpa del arquitecto? ¿Tu que opinas?" \
                      + " http://losgraficos.com/fotos-imagenes-graciosas-1381.html #fb"
        tweet.favoritos = 5
        tweet.retweets = 26
        tweet.es_humor = 1
        tweet.cuenta = 174450359

        self.assertEqual(
            remover_links(tweet.texto),
            "FOTO CURIOSA: ¿Será culpa del arquitecto? ¿Tu que opinas?  #fb",
            "El texto sin el link no es el esperado")
示例#9
0
    def test_remover_usuarios_con_acento(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "#ThankYou @clauditaa_love @vivirocha17 @jeanm23 @freddycastro19 @eleze12" \
                      + " @josférsp @vicenteanthonio Retuiters destacados de hoy, gracias!"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(
            remover_usuarios(tweet.texto),
            "#ThankYou        Retuiters destacados de hoy, gracias!",
            "El texto sin los usuarios no es el esperado")
示例#10
0
    def test_remover_retweet_con_usuario_con_acentos(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "RT @GustavoMazy: @LosChistes feliz aniversario de un año en twitter!" \
                      + " //Cierto, estamos cumpliendo UN AÑO, GRACIAS a todos!"
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        self.assertEqual(remover_retweet_si_hay(tweet.texto),
                         "@LosChistes feliz aniversario de un año en twitter!"
                         + " //Cierto, estamos cumpliendo UN AÑO, GRACIAS a todos!",
                         "El texto sin el retweet no es el esperado")
示例#11
0
    def test_remover_dos_links(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará en mayo de este año" \
                      + " 2013 http://t.co/tklxfuFx http://t.co/c5aS4hw2"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_links(tweet.texto),
                         "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará en mayo de este año" \
                         + " 2013  ",
                         "El texto sin los links no es el esperado")
示例#12
0
    def test_remover_espacios_multiples_y_strip(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "RT    @laseptimabutaca: Trailer de \"Rápido y Furioso 6\"  que     se estrenará" \
                      + " en mayo de este año 2013  "
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(remover_espacios_multiples_y_strip(tweet.texto),
                         "RT @laseptimabutaca: Trailer de \"Rápido y Furioso 6\" que se estrenará" \
                         + " en mayo de este año 2013",
                         "El texto sin los espacios múltiples y sin strip no es el esperado")
示例#13
0
    def test_remover_hashtags(self):
        tweet = Tweet()
        tweet.id = 301726981937057792
        tweet.texto = "#DiaMundialDelOrgasmoFemenino Lol Respeten un poco Este TT es igual como" \
                      + " si fuese #ILoveReggaeton Que gracia  siempre #CojenComoObjetoSexual"
        tweet.favoritos = 0
        tweet.retweets = 71
        tweet.es_humor = 1
        tweet.cuenta = 142482558

        self.assertEqual(
            remover_hashtags(tweet.texto),
            " Lol Respeten un poco Este TT es igual como si fuese  Que gracia  siempre ",
            "El texto sin los hashtags no es el esperado")
示例#14
0
    def test_hashtags_basico(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "#cuatro Tweet #uno #doña que #tres #asdfAsfsdañaáéáuasdfasd hola"
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        hashtags = clasificador.features.hashtags.Hashtags()

        tweet.features[hashtags.nombre] = hashtags.calcular_feature(tweet)
        self.assertEquals(5, tweet.features[hashtags.nombre],
                          "El tweet debería tener 5 hashtags, no " + unicode(tweet.features[hashtags.nombre]))
示例#15
0
    def test_antonimos_basico(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "Un pequeño paso para el hombre, pero es un gran paso para la humanidad."
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        antonimos = clasificador.features.antonimos.Antonimos()

        tweet.features[antonimos.nombre] = antonimos.calcular_feature(tweet)
        self.assertEquals(0.25, tweet.features[antonimos.nombre],
                          "El tweet debería tener 0.25 en antonimos, no " + unicode(tweet.features[antonimos.nombre]))
示例#16
0
    def test_remover_retweet_con_usuario_con_acentos(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "RT @GustavoMazy: @LosChistes feliz aniversario de un año en twitter!" \
                      + " //Cierto, estamos cumpliendo UN AÑO, GRACIAS a todos!"
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        self.assertEqual(
            remover_retweet_si_hay(tweet.texto),
            "@LosChistes feliz aniversario de un año en twitter!" +
            " //Cierto, estamos cumpliendo UN AÑO, GRACIAS a todos!",
            "El texto sin el retweet no es el esperado")
    def test_preguntasrespuestas_basico(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "¿De qué color era el caballo blanco de Artigas? Blanco."
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        preguntasrespuestas = clasificador.features.preguntasrespuestas.PreguntasRespuestas()

        tweet.features[preguntasrespuestas.nombre] = preguntasrespuestas.calcular_feature(tweet)
        self.assertEquals(1, tweet.features[preguntasrespuestas.nombre],
                          "El tweet debería tener 1 en preguntas-respuestas, no " + unicode(tweet.features[
                              preguntasrespuestas.nombre]))
    def test_preguntasrespuestas_basico3(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = """Te hago una pregunta -¿Qué te duele? -La mano. Es que te amo -¿Por qué?
                      -De tanto pensar en ti -¡Asqueroso! -Perdón, entonces no te vuelvo hacer una carta :( -¿Sabías?"""
        tweet.texto_original = tweet.texto
        tweet.favoritos = 75
        tweet.retweets = 113
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        preguntasrespuestas = clasificador.features.preguntasrespuestas.PreguntasRespuestas()

        tweet.features[preguntasrespuestas.nombre] = preguntasrespuestas.calcular_feature(tweet)
        self.assertEquals(2, tweet.features[preguntasrespuestas.nombre],
                          "El tweet debería tener 2 preguntas-respuestas, no " + unicode(tweet.features[
                              preguntasrespuestas.nombre]))
示例#19
0
    def test_hashtags_basico(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "#cuatro Tweet #uno #doña que #tres #asdfAsfsdañaáéáuasdfasd hola"
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        hashtags = clasificador.features.hashtags.Hashtags()

        tweet.features[hashtags.nombre] = hashtags.calcular_feature(tweet)
        self.assertEquals(
            5,
            tweet.features[hashtags.nombre],
            "El tweet debería tener 5 hashtags, no " + unicode(tweet.features[hashtags.nombre]),
        )
示例#20
0
    def test_preguntasrespuestas_basico(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = "¿De qué color era el caballo blanco de Artigas? Blanco."
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        preguntasrespuestas = clasificador.features.preguntasrespuestas.PreguntasRespuestas(
        )

        tweet.features[preguntasrespuestas.
                       nombre] = preguntasrespuestas.calcular_feature(tweet)
        self.assertEquals(
            1, tweet.features[preguntasrespuestas.nombre],
            "El tweet debería tener 1 en preguntas-respuestas, no " +
            unicode(tweet.features[preguntasrespuestas.nombre]))
示例#21
0
    def test_preguntasrespuestas_basico3(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = """Te hago una pregunta -¿Qué te duele? -La mano. Es que te amo -¿Por qué?
                      -De tanto pensar en ti -¡Asqueroso! -Perdón, entonces no te vuelvo hacer una carta :( -¿Sabías?"""
        tweet.texto_original = tweet.texto
        tweet.favoritos = 75
        tweet.retweets = 113
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        preguntasrespuestas = clasificador.features.preguntasrespuestas.PreguntasRespuestas(
        )

        tweet.features[preguntasrespuestas.
                       nombre] = preguntasrespuestas.calcular_feature(tweet)
        self.assertEquals(
            2, tweet.features[preguntasrespuestas.nombre],
            "El tweet debería tener 2 preguntas-respuestas, no " +
            unicode(tweet.features[preguntasrespuestas.nombre]))
示例#22
0
    def test_palabrasmayusculas_basico_con_acento_y_numeros(self):
        tweet = Tweet()
        tweet.id = 58179039764021248
        tweet.texto = """Típico :
            –¿MAMÁ?
            –¿Qué?
            –Te amo
            –¡YA TE DIJE 2 VECES QUE NO VAS A SALIR!"""
        tweet.texto_original = tweet.texto
        tweet.favoritos = 3
        tweet.retweets = 14
        tweet.es_humor = 1
        tweet.cuenta = 132679073

        palabrasmayusculas = clasificador.features.palabrasmayusculas.PalabrasMayusculas()

        tweet.features[palabrasmayusculas.nombre] = palabrasmayusculas.calcular_feature(tweet)

        valor_esperado = 10 / 15

        self.assertEquals(valor_esperado, tweet.features[palabrasmayusculas.nombre],
                          "El tweet debería tener " + unicode(valor_esperado) + " en PalabrasMayusculas, no "
                          + str(tweet.features[palabrasmayusculas.nombre]))
示例#23
0
def cargar_tweets(limite=None, agregar_sexuales=False, cargar_features=True):
    """Carga todos los tweets, inclusive aquellos para evaluación, aunque no se quiera evaluar,
    y aquellos mal votados, así se calculan las features para todos. Que el filtro se haga luego."""
    conexion = open_db()
    if DB_ENGINE == 'sqlite3':
        cursor = conexion.cursor()
    else:
        cursor = conexion.cursor(buffered=True)  # buffered así sé la cantidad que son antes de iterarlos

    if agregar_sexuales:
        consulta_sexuales_tweets = ""
        consulta_limite_sexuales = ""
    else:
        consulta_sexuales_tweets = "censurado_tweet = 0"
        consulta_limite_sexuales = "AND " + consulta_sexuales_tweets
    consulta_sexuales_features = consulta_sexuales_tweets

    if limite:
        consulta = "SELECT id_tweet FROM tweets WHERE evaluacion = 0 " + consulta_limite_sexuales + " ORDER BY RAND() LIMIT "\
                   + unicode(limite)

        cursor.execute(consulta)

        bar = IncrementalBar("Eligiendo tweets aleatorios\t", max=cursor.rowcount, suffix=SUFIJO_PROGRESS_BAR)
        bar.next(0)

        ids = []

        for (tweet_id,) in cursor:
            ids.append(tweet_id)
            bar.next()

        bar.finish()

        str_ids = '(' + unicode(ids).strip('[]L') + ')'
        consulta_prueba_tweets = "T.id_tweet IN {ids}".format(ids=str_ids)
        consulta_prueba_features = "id_tweet IN {ids}".format(ids=str_ids)

    else:
        consulta_prueba_features = ""
        consulta_prueba_tweets = ""

    if not agregar_sexuales and limite:
        restricciones_tweets = "WHERE " + consulta_sexuales_tweets + " AND " + consulta_prueba_tweets
        restricciones_features = "WHERE " + consulta_sexuales_features + " AND " + consulta_prueba_features
    elif not agregar_sexuales:
        restricciones_tweets = "WHERE " + consulta_sexuales_tweets
        restricciones_features = "WHERE " + consulta_sexuales_features
    elif limite:
        restricciones_tweets = "WHERE " + consulta_prueba_tweets
        restricciones_features = "WHERE " + consulta_prueba_features
    else:
        restricciones_tweets = ""
        restricciones_features = ""

    if DB_ENGINE == 'sqlite3':
            consulta = """
    SELECT id_account,
           T.id_tweet,
           text_tweet,
           favorite_count_tweet,
           retweet_count_tweet,
           eschiste_tweet,
           censurado_tweet,
           name_account,
           followers_count_account,
           evaluacion,
           votos,
           votos_humor,
           promedio_votos,
           categoria_tweet
    FROM   tweets AS T
           NATURAL JOIN twitter_accounts
                        LEFT JOIN (SELECT id_tweet,
                                          Avg(voto) AS promedio_votos,
                                          Count(*) AS votos,
                                          Count(case when voto <> 'x' then 1 else NULL end) AS votos_humor
                                   FROM   votos
                                   WHERE voto <> 'n'
                                   GROUP  BY id_tweet) V
                               ON ( V.id_tweet = T.id_tweet )
    {restricciones}
    """.format(restricciones=restricciones_tweets)
    else:
        consulta = """
    SELECT id_account,
           T.id_tweet,
           text_tweet,
           favorite_count_tweet,
           retweet_count_tweet,
           eschiste_tweet,
           censurado_tweet,
           name_account,
           followers_count_account,
           evaluacion,
           votos,
           votos_humor,
           promedio_votos,
           categoria_tweet
    FROM   tweets AS T
           NATURAL JOIN twitter_accounts
                        LEFT JOIN (SELECT id_tweet,
                                          Avg(voto) AS promedio_votos,
                                          Count(*) AS votos,
                                          Count(If(voto <> 'x', 1, NULL)) AS votos_humor
                                   FROM   votos
                                   WHERE voto <> 'n'
                                   GROUP  BY id_tweet) V
                               ON ( V.id_tweet = T.id_tweet )
    {restricciones}
    """.format(restricciones=restricciones_tweets)

    cursor.execute(consulta)

    bar = IncrementalBar("Cargando tweets\t\t\t", max=(999999 if DB_ENGINE == 'sqlite3' else cursor.rowcount), suffix=SUFIJO_PROGRESS_BAR)
    bar.next(0)

    resultado = {}

    for (id_account, tweet_id, texto, favoritos, retweets, es_humor, censurado, cuenta, seguidores, evaluacion, votos,
         votos_humor, promedio_votos, categoria) in cursor:
        tweet = Tweet()
        tweet.id = tweet_id
        tweet.texto_original = texto
        tweet.texto = texto
        tweet.favoritos = favoritos
        tweet.retweets = retweets
        tweet.es_humor = es_humor
        tweet.es_chiste = es_humor
        tweet.censurado = censurado
        tweet.cuenta = cuenta
        tweet.seguidores = seguidores
        tweet.evaluacion = evaluacion
        tweet.categoria = categoria
        if votos:
            tweet.votos = int(votos)  # Esta y la siguiente al venir de count y sum, son decimal.
        if votos_humor:
            tweet.votos_humor = int(votos_humor)
        if promedio_votos:
            tweet.promedio_de_humor = promedio_votos

        resultado[tweet.id] = tweet
        bar.next()

    bar.finish()

    if cargar_features:
        consulta = """
        SELECT id_tweet,
               nombre_feature,
               valor_feature
        FROM   features
               NATURAL JOIN tweets
        {restricciones}
        """.format(restricciones=restricciones_features)

        cursor.execute(consulta)

        bar = IncrementalBar("Cargando features\t\t", max=(9999999 if DB_ENGINE == 'sqlite3' else cursor.rowcount), suffix=SUFIJO_PROGRESS_BAR)
        bar.next(0)

        for (id_tweet, nombre_feature, valor_feature) in cursor:
            if id_tweet in resultado:
                resultado[id_tweet].features[nombre_feature] = valor_feature
            bar.next()

        bar.finish()

        cursor.close()
        conexion.close()

    return list(resultado.values())
示例#24
0
def cargar_tweets(limite=None, agregar_sexuales=False, cargar_features=True):
    """Carga todos los tweets, inclusive aquellos para evaluación, aunque no se quiera evaluar,
    y aquellos mal votados, así se calculan las features para todos. Que el filtro se haga luego."""
    conexion = mysql.connector.connect(user=DB_USER,
                                       password=DB_PASS,
                                       host=DB_HOST,
                                       database=DB_NAME)
    cursor = conexion.cursor(
        buffered=True
    )  # buffered así sé la cantidad que son antes de iterarlos

    if agregar_sexuales:
        consulta_sexuales_tweets = ""
        consulta_limite_sexuales = ""
    else:
        consulta_sexuales_tweets = "censurado_tweet = 0"
        consulta_limite_sexuales = "AND " + consulta_sexuales_tweets
    consulta_sexuales_features = consulta_sexuales_tweets

    if limite:
        consulta = "SELECT id_tweet FROM tweets WHERE evaluacion = 0 " + consulta_limite_sexuales + " ORDER BY RAND() LIMIT "\
                   + unicode(limite)

        cursor.execute(consulta)

        bar = IncrementalBar("Eligiendo tweets aleatorios\t",
                             max=cursor.rowcount,
                             suffix=SUFIJO_PROGRESS_BAR)
        bar.next(0)

        ids = []

        for (tweet_id, ) in cursor:
            ids.append(tweet_id)
            bar.next()

        bar.finish()

        str_ids = '(' + unicode(ids).strip('[]L') + ')'
        consulta_prueba_tweets = "T.id_tweet IN {ids}".format(ids=str_ids)
        consulta_prueba_features = "id_tweet IN {ids}".format(ids=str_ids)

    else:
        consulta_prueba_features = ""
        consulta_prueba_tweets = ""

    if not agregar_sexuales and limite:
        restricciones_tweets = "WHERE " + consulta_sexuales_tweets + " AND " + consulta_prueba_tweets
        restricciones_features = "WHERE " + consulta_sexuales_features + " AND " + consulta_prueba_features
    elif not agregar_sexuales:
        restricciones_tweets = "WHERE " + consulta_sexuales_tweets
        restricciones_features = "WHERE " + consulta_sexuales_features
    elif limite:
        restricciones_tweets = "WHERE " + consulta_prueba_tweets
        restricciones_features = "WHERE " + consulta_prueba_features
    else:
        restricciones_tweets = ""
        restricciones_features = ""

    consulta = """
    SELECT id_account,
           T.id_tweet,
           text_tweet,
           favorite_count_tweet,
           retweet_count_tweet,
           eschiste_tweet,
           censurado_tweet,
           name_account,
           followers_count_account,
           evaluacion,
           votos,
           votos_humor,
           promedio_votos,
           categoria_tweet
    FROM   tweets AS T
           NATURAL JOIN twitter_accounts
                        LEFT JOIN (SELECT id_tweet,
                                          Avg(voto) AS promedio_votos,
                                          Count(*) AS votos,
                                          Count(If(voto <> 'x', 1, NULL)) AS votos_humor
                                   FROM   votos
                                   WHERE voto <> 'n'
                                   GROUP  BY id_tweet) V
                               ON ( V.id_tweet = T.id_tweet )
    {restricciones}
    """.format(restricciones=restricciones_tweets)

    cursor.execute(consulta)

    bar = IncrementalBar("Cargando tweets\t\t\t",
                         max=cursor.rowcount,
                         suffix=SUFIJO_PROGRESS_BAR)
    bar.next(0)

    resultado = {}

    for (id_account, tweet_id, texto, favoritos, retweets, es_humor, censurado,
         cuenta, seguidores, evaluacion, votos, votos_humor, promedio_votos,
         categoria) in cursor:
        tweet = Tweet()
        tweet.id = tweet_id
        tweet.texto_original = texto
        tweet.texto = texto
        tweet.favoritos = favoritos
        tweet.retweets = retweets
        tweet.es_humor = es_humor
        tweet.es_chiste = es_humor
        tweet.censurado = censurado
        tweet.cuenta = cuenta
        tweet.seguidores = seguidores
        tweet.evaluacion = evaluacion
        tweet.categoria = categoria
        if votos:
            tweet.votos = int(
                votos
            )  # Esta y la siguiente al venir de count y sum, son decimal.
        if votos_humor:
            tweet.votos_humor = int(votos_humor)
        if promedio_votos:
            tweet.promedio_de_humor = promedio_votos

        resultado[tweet.id] = tweet
        bar.next()

    bar.finish()

    if cargar_features:
        consulta = """
        SELECT id_tweet,
               nombre_feature,
               valor_feature
        FROM   features
               NATURAL JOIN tweets
        {restricciones}
        """.format(restricciones=restricciones_features)

        cursor.execute(consulta)

        bar = IncrementalBar("Cargando features\t\t",
                             max=cursor.rowcount,
                             suffix=SUFIJO_PROGRESS_BAR)
        bar.next(0)

        for (id_tweet, nombre_feature, valor_feature) in cursor:
            if id_tweet in resultado:
                resultado[id_tweet].features[nombre_feature] = valor_feature
            bar.next()

        bar.finish()

        cursor.close()
        conexion.close()

    return list(resultado.values())