Skip to content

Latest commit

 

History

History
618 lines (551 loc) · 24.5 KB

README.md

File metadata and controls

618 lines (551 loc) · 24.5 KB

Wikjote

A python package to convert the Spanish Wiktionary into JSON

The wikjote package is a solution to extract information from the Spanish Wiktionary ( and maybe other wikimedia sites ) into JSON from the rendered HTML.

Wikjote don't work directly with the HTML generated by the Wiktionary, instead it relies on the work of the Kiwix and the OpenZIM project which have created a mature and stable infrastructure capable of generating compressed files (ZIM) from the vast majority of wikimedia instances for offline usage.

The process has two steps:

  1. Wikjote reads de zim file and converts each html page into a simplified json representation.
  2. The resulting json goes trough a configurable pipeline where the data of each page is corrected, modified and structured.

Installation

git clone https://github.com/SrGnis/wikjote.git
cd wikjote
pip install .
# if you want to edit the code use this instead:
pip install -e .

Usage

Wikjote has two usage modes:

  • wikjote convert: To convert the data from a zim file into a json
  • wikjote process: Process the previous converted data

Convert usage

You can run Wikjote simply by:

wikjote convert

It will download the last Spanish Wiktionary ZIM file, process all the pages and dump the result in a json file.

By default the working directory is ./wikjote_dir, you can specify other directory with the -d option.

You can prevent the zim download with the -n option, Wikjote will search the zim in "working_dir"/downloads/wiktionary_es.zim ( planed to be more general ) or specify the path to the zim file with -p

To prevent Wikjote process all the pages of the zim, specify a list of lemas with -l lema1 leam2 or a file with a list of lemas with -lf

The lemas file format could be a json array:

[
    "lema1",
    "lema2"
]

or a file with a lema in each line:

lema1
lema2

Examples:

wikjote convert -d ./working_dir -l gato casa
# if the zim is already downloaded
wikjote convert -n -d ./working_dir -l gato casa

Process usage

The process mode will load the supplied json file containing the data from the convert mode, this data will be supplied to a pipeline that will transform that data. Finally that data is witted to a new json file.

The pipeline is built following the configuration file that specifies a sequence of handlers that will transform the data. The pipeline will use workers for runnig the handlers in different threads, but since Python has GIL this has litte effect.

The process mode only has tree arguments -i input json file, -o output json file, -w number of workers.

Example:

wikjote process -i eswiktionary.json -o process_out.json -w 1

Config file

Wikjote loads a internal config file where all the important configurations are set.

You can specify your own config file using the -c option followed by the config path. And you can get the default config file with the wikjote_print_config command.

Example:

wikjote_print_config > my_config.json
# edit your config file
wikjote -c my_config.json

The command parameters overwrite the fields of the config file, as an example: the -l parameter will overwrite the "lemas" field int the config.

Config Specification

Basic Config

field name value description required
lemas array A list of lemas to process, overwrited by -l --lemas false
default_processor processor The default processor to use, default=DefaultProcessor true
rules array of rules A list of rules to process each section true
pipeline array of handlers A list of handlers that build a pipeline true

Processor Config

field name value description required
module_name string The module name of the processor or the file path if is a file true
class_name string The class of the processor true
is_file bool Specifies if the processor is a module or a file true

Rule Config

field name value description required
name string A descriptive name of the rule true
type string The type of rule to use: NameRule or XPathRule true
args dict Arguments supplied to the rule, name of the section in case of a NameRule and a xpath query in case of XPathRule or regex in RegExRule true
section_type string The type of section that fulfills the rule. The value will be added to the resulting json of the section to identify the section true
processor processor The processor that will convert the section true

Handler Config

Same as a processor with args

Extending Wikjote

You can add/modify the rules and processors of Wikjote to process more sections or change the output of the conversion.

First of all check the inner workings of Wikjote in this document

To add a new processor is as easy as create a new class that extends the Processor class. Just implement the run method and return the data that you want, the return could be anything that can be converted to json.

Example: Processor to extract only the links from a section

from typing import Any

from wikjote.processors.procesor import Processor


class LinksProcessor(Processor):
    def run(self) -> Any:
        links_elements = self.object.find(".//a")
        links = []
        for link_element in links_elements:
            links.append(link_element.root.get("href", None))
        return links

Now we add it to the rules in the config:

{
    "name": "get_links_rule",
    "type": "NameRule",
    "section_type": "refranes",
    "processor": {
        "module_name": "/path/to/linksprocessor.py",
        "class_name": "LinksProcessor",
        "is_file": true
    },
    "arguments":{
        "name":"Refranes"
    }
}

You can also create a package with your processors instead of using single files.

Following the same method you can add new handlers:

Example: A handler that add a new entry with the length of the list

from __future__ import annotations

from wikjote.pipeline.handler import Handler

class AddLengthHandler(Handler):
    _input_type = [list[dict]]
    _output_type = list[dict]
    _concurrent = False

    def process(self, data: list[dict]) -> list[dict]:

        data.append({"length": len(data)})

        return data

Now we add it to the rules in the config:

{
    "handler": {
        "module_name": "/path/to/addlengthhandler.py",
        "class_name": "AddLengthHandler",
        "is_file": true
    },
    "arguments":{}
}

Conversion output

The JSON resulting from the conversion will have the following structure:

{
    "lema1": [
        {
            "name": "section_name",
            "type": "section_type",
            "contents": "section contents (can be a str, array or object)",
            "sub_sections":[
                {
                    "name": "section_name",
                    "type": "section_type",
                    "contents": "section contents (can be a str, array or object)",
                    "sub_sections":[
                        ...
                    ]
                },
                {
                    "name": "section_name",
                    "type": "section_type",
                    "contents": "section contents (can be a str, array or object)",
                    "sub_sections":[
                        ...
                    ]
                },
                ...
            ]
        },
        {
            ...
        },
        ...
    ]
    "lema2": ...
}
A real example
{
  "gato": [
    {
      "name": "Español",
      "type": "languaje",
      "contents": null,
      "sub_sections": [
        {
          "name": "Etimología",
          "type": "etymology",
          "contents": "Del latín vulgar cattus. Compárese el catalán gat, el francés chat, el inglés cat, el italiano gatto o el portugués gato. Las lenguas celtas, eslavas, germánicas, helénicas y romances han adoptado casi sin excepción este término, reemplazando a los patrimoniales; el latín feles sólo sobrevive en los derivados felino, félido",
          "sub_sections": []
        },
        {
          "name": "Sustantivo masculino",
          "type": "senses",
          "contents": {
            "senses": [
              {
                "title": "1 Zoología (mamíferos).",
                "content": "(Felis catus) Animal carnívoro de la familia de los felinos, domesticado como animal de compañía desde al menos el 3500 a. C",
                "attributes": {
                  "Sinónimos": "minino, micho (Ecuador, Panamá)"
                }
              },
              {
                "title": "2 Zoología (mamíferos).",
                "content": "Por extensión, cualquier ejemplar de la familia de los félidos, que comprende 37 especies de mamíferos carnívoros",
                "attributes": {
                  "Sinónimos": "félido, felino",
                  "Hipónimo": "gato montés"
                }
              },
              {
                "title": "3",
                "content": "Prostituta de alto nivel, que solo atiende un número más o menos reducido de clientes regulares",
                "attributes": {
                  "Ámbito": "Río de la Plata",
                  "Uso": "lunfardismo, coloquial, Usado más como sustantivo femenino"
                }
              },
              {
                "title": "4",
                "content": "Por extensión, prostituta en general, especialmente la de cierto nivel",
                "attributes": {
                  "Ámbito": "Río de la Plata",
                  "Uso": "lunfardismo"
                }
              },
              {
                "title": "5",
                "content": "Cliente regular de una prostituta",
                "attributes": {
                  "Ámbito": "Río de la Plata",
                  "Uso": "lunfardismo"
                }
              },
              {
                "title": "6",
                "content": "Bisoñé, peluca que usan algunos hombres para disimular su calvicie",
                "attributes": {
                  "Ámbito": "Río de la Plata",
                  "Uso": "lunfardismo"
                }
              },
              {
                "title": "7",
                "content": "Máquina para levantar grandes pesos a poca altura",
                "attributes": {
                  "Sinónimos": "gato hidraúlico, cric, crique, gata"
                }
              },
              {
                "title": "8",
                "content": "Juego de mesa para dos personas en que gana el primero en poner tres marcas en línea, usualmente círculos y cruces, dentro de una cuadrícula de tres casillas de ancho por tres de alto",
                "attributes": {
                  "Sinónimos": "juego de la vieja, juego del gato, tres en raya, ta te ti, triqui"
                }
              },
              {
                "title": "9",
                "content": "Nombre del símbolo #, por su semejanza con el juego llamado \"gato\", sobre todo hablando de la tecla que lleva ese símbolo en los teléfonos",
                "attributes": {
                  "Ámbito": "Chile, México",
                  "Sinónimos": "almohadilla (España), numeral"
                }
              },
              {
                "title": "10",
                "content": "Baile tradicional de Argentina, de pareja suelta y ritmo alegre.\n\"Yo vengo de aquellos pagos / muy cerca de la frontera / donde se baila la cueca / zamba, gato y chacarera\" (Óscar Palavecino, \"Chacarera pa' mi Tartagal\")",
                "attributes": {
                  "Hipónimos": "gato con relaciones, gato cordobés, gato cuyano, gato patriótico",
                  "Ejemplos": ""
                }
              },
              {
                "title": "11",
                "content": "Persona nacida en la ciudad de Madrid, España",
                "attributes": {}
              },
              {
                "title": "12",
                "content": "Ladrones de poca monta (o rateros), llamados así por su habilidad para moverse y actuar silenciosamente sin ser detectados, al igual que el animal",
                "attributes": {
                  "Ámbito": "Algunas provincias argentinas"
                }
              },
              {
                "title": "13",
                "content": "Sirviente, en especial del servicio doméstico",
                "attributes": {
                  "Ámbito": "México",
                  "Uso": "despectivo"
                }
              },
              {
                "title": "14 Botánica.",
                "content": "(Salix caprea) Árbol dioico de la familia de las salicáceas, nativo de Eurasia, de hojas relativamente anchas y flores agrupadas en amentos",
                "attributes": {
                  "Ámbito": "Chile",
                  "Sinónimos": "sauce cabruno, sauce alemán (Chile), meca de gato (Chiloé)"
                }
              },
              {
                "title": "15",
                "content": "Estafa o robo de poca monta y mucho sigilo, mas comúnmente dicho, de gato, veáse acep. 12",
                "attributes": {
                  "Ámbito": "Uruguay",
                  "Uso": "coloquial"
                }
              }
            ],
            "inflection": {
              "Singular": [
                "gato"
              ],
              "Plural": [
                "gatos"
              ]
            }
          },
          "sub_sections": []
        },
        {
          "name": "Locuciones",
          "type": "idioms",
          "contents": [
            "a gatas: apoyando las rodillas y las manos en el suelo",
            "bolsa de gatos: embrollo",
            "buscarle la quinta pata o los tres pies al gato: insistir exageradamente en los defectos de algo",
            "buscarle las cinco patas al gato: cometer imprudencias que pueden traer consecuencias que lamentar. (Venezuela)",
            "a ver quien pone el cascabel al gato: Quien se atreve a enfrentarse a alguien problemático o agresivo",
            "cuatro gatos: muy poca gente",
            "defenderse como gato boca arriba, de espaldas o panza arriba: defenderse agresiva y desesperadamente (coloquial)",
            "de gato: adquirido por medios de legalidad dudosa (coloquial, Uruguay)",
            "dar o pasar gato por liebre: engañar dando algo de menor valor que lo acordado",
            "darle el palo al gato: acertar, particularmente al lograr un negocio ventajoso (Chile, coloquial)",
            "el gato en la carnicería o el gato cuidando la carnicería",
            "echar el gato a las barbas: insultar a alguno (España)",
            "eso lo sabe hasta el gato: dicho para denotar que un asunto es muy obvio o sabido y que decirlo sería una perogrullada",
            "estar más perdido que un gato en una fábrica de sifones: estar muy perdido, confuso o desorientado",
            "estar meado de gato: estar con mala suerte (Chile, coloquial)",
            "estar para el gato: estar en malas condiciones, o con mala salud (Cono Sur)",
            "gato casero: ratero de poca monta (España)",
            "gato colo: felino sudamericano (Chile)",
            "gato colocolo: felino sudamericano (Chile)",
            "gato de agua: trampa para ratones hecha con agua",
            "gato de campo: con afición por el robo o habilidad para realizarlo (Chile, coloquial)",
            "gato de río o gato huillín: mamífero mustélido sudamericano (Chile)",
            "gato de mar: mamífero mustélido sudamericano (Chile)",
            "gato de nueve colas: instrumento de tortura",
            "gato montés o del monte",
            "gato pajero: felino sudamericano",
            "gato viejo: persona astuta y perspicaz que intenta no parecerlo (España)",
            "gato negro: en la Edad Media se relacionó a los gatos negros con la brujería",
            "gollo de gato",
            "haber gato encerrado: haber algo oculto o sospechoso",
            "jugar al gato y al ratón: oponerse encarnizadamente",
            "llevarse como el perro y el gato: llevarse muy mal",
            "llevarse el gato al agua: vencer en un enfrentamiento (España)",
            "mano o manito de gato",
            "más asustado que gato en bote",
            "más ladrón que gato de campo",
            "más rayado que charango de gato: loco, delirante (Chile, coloquial)",
            "meca de gato",
            "mojón de gato",
            "ojo de gato",
            "pelo de gato",
            "quedar como gato mojado: resultar humillado (Cataluña)",
            "tener siete vidas como los gatos: salir indemne de un accidentes",
            "vivir como perros y gatos: vivir en conflicto constante"
          ],
          "sub_sections": []
        },
        {
          "name": "Refranes",
          "type": null,
          "contents": "Refranes\n    \ncierra la puerta que se escapa el gato: se usa para reprender a quien revela intimidades frente a un tercero (España)\nel gato escaldado, del agua fría huye: quien ha sufrido un percance, trata de huir de lo que le recuerda al mismo.\ngato con guantes no caza ratones: indica que cuando se va a realizar una labor manual hay que llevar la indumentaria adecuada.\nhasta los gatos quieren zapatos: se usa para reprender ambiciones excesivas\nhijo de gato caza ratón: cuando los hijos hacen lo mismo que sus padres o heredan sus habilidades o aun sus mañas.\nla curiosidad mató al gato: se usa para advertir a quien investiga asuntos turbios o peligrosos\nDe gato: igual que acepción 12 (Argentina) y acepción 15 (Uruguay)\nComo gato entre la leña: para referirse a quien sortea las dificultades con gran habilidad y o agilidad (Uruguay)",
          "sub_sections": []
        },
        {
          "name": "Información adicional",
          "type": "additional_info",
          "contents": [
            "Rima:",
            "Anagramas: gota, toga",
            "Pares mínimos: gata, gueto, bato, cato, dato, fato, hato, lato, mato, nato, pato, rato, vato, Gabo, gafo, gajo, galo, gallo, gamo, gano"
          ],
          "sub_sections": []
        },
        {
          "name": "Véase también",
          "type": "see_more",
          "contents": [
            "Wikipedia  tiene un artículo sobre gato",
            "felino",
            "gatear",
            "gatera",
            "minino",
            "perro"
          ],
          "sub_sections": []
        },
        {
          "name": "Traducciones",
          "type": "translations",
          "contents": {
            "Afrikáans": "[1] kat",
            "Aimara": "[1] phisi",
            "Alemán": "[1, 2] Katze, [8] Tic Tac Toe",
            "Armenio": "[1] կատու",
            "Asturiano": "[1] gatu",
            "Azerí": "[1] pişik",
            "Bretón": "[1] kazh",
            "Búlgaro": "котарак, котка",
            "Catalán": "[1] gat, [1] móx",
            "Coreano": "고양이",
            "Danés": "[1] kat, [8] kryds og bolle",
            "Esperanto": "[1] kato",
            "Estonio": "[1] kass",
            "Euskera": "katu",
            "Finés": "[1] kissa, nosturi",
            "Francés": "[1] chat, [7] cric",
            "Galés": "[1] cath",
            "Gallego": "[1] gato, [8] tres en raia",
            "Georgiano": "[1] კატა",
            "Griego": "[1] γάτα",
            "Guaraní": "[1] mbarakaja",
            "Húngaro": "[1] macska",
            "Ido": "[1] kato",
            "Inglés": "[1] cat, [8] tic-tac-toe",
            "Irlandés": "[1] cat",
            "Italiano": "[1] gatto, [7] cricco",
            "Japonés": "[1] 猫, [8] 三目並べ",
            "Kurdo": "kitik",
            "Latín": "[1] feles",
            "Luxemburgués": "[1,2] Kaz",
            "Mandarín": "",
            "Mapuche": "[1] narki, [1] ñayki",
            "Maya yucateco": "[1] miis",
            "Mazahua central": "mixi",
            "Mazahua de Michoacán": "mixi",
            "Mongol": "муур",
            "Náhuatl central": "miztontli",
            "Náhuatl clásico": "mizton",
            "Náhuatl de Guerrero": "miston",
            "Náhuatl de la Huasteca central": "misto",
            "Náhuatl de la Huasteca occidental": "misto",
            "Náhuatl de la Huasteca oriental": "mistoh, micho",
            "Náhuatl de Morelos": "mistle",
            "Neerlandés": "[1] kat, kaas en eieren",
            "Noruego bokmål": "[1] katt",
            "Noruego nynorsk": "[1] katt",
            "Otomí de Temoaya": "mixi",
            "Otomí del Valle del Mezquital": "mixi",
            "Papiamento": "[1] pushi",
            "Polaco": "[1] kot, [8] kółko i krzyżyk",
            "Portugués": "[1] gato, [8] jogo da velha",
            "Quechua boliviano": "[1] michi",
            "Quechua cuzqueño": "[1] michi",
            "Quechua de Huaylas": "mishi",
            "Rapa nui": "kuri",
            "Rumano": "[1, 2] pisică, [1] pisică de casă",
            "Ruso": "[1] кот, [8] крестики-нолики",
            "Serbio": "[1] мачак, [8] икс-окс",
            "Sueco": "[1] katt",
            "Ucraniano": "[1] кіт,, [1] кішка",
            "Tártaro de Crimea": "mışıq",
            "Yoruba": "[1] ológìnní, [1] ológbò"
          },
          "sub_sections": []
        }
      ]
    },
    {
      "name": "Gallego",
      "type": "languaje",
      "contents": null,
      "sub_sections": [
        {
          "name": "Etimología",
          "type": "etymology",
          "contents": "Si puedes, incorpórala: ver cómo",
          "sub_sections": []
        },
        {
          "name": "Sustantivo masculino",
          "type": "senses",
          "contents": {
            "senses": [
              {
                "title": "1 Zoología (mamíferos).",
                "content": "Gato",
                "attributes": {}
              }
            ],
            "inflection": null
          },
          "sub_sections": []
        }
      ]
    },
    {
      "name": "Judeoespañol",
      "type": "languaje",
      "contents": null,
      "sub_sections": [
        {
          "name": "Etimología",
          "type": "etymology",
          "contents": "Si puedes, incorpórala: ver cómo",
          "sub_sections": []
        },
        {
          "name": "Sustantivo masculino",
          "type": "senses",
          "contents": {
            "senses": [
              {
                "title": "1 Zoología (mamíferos).",
                "content": "Gato",
                "attributes": {}
              }
            ],
            "inflection": null
          },
          "sub_sections": []
        },
        {
          "name": "Véase también",
          "type": "see_more",
          "contents": [
            "Wikipedia en judeoespañol tiene un artículo sobre gato"
          ],
          "sub_sections": []
        }
      ]
    }
  ]
}

And here is the TODO list