-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsv2qs.py
150 lines (118 loc) · 4.37 KB
/
csv2qs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# -*- coding: utf-8 -*-
import pandas as pd
import re
import urllib.parse
import requests
'''
- Valor de URL deve começar com http://
- Valor de telefone e email possuem formatação
- Opção de escolher referências para declarações
- Inserir regex para validar valores fornecidos
- indicar problemas e sugestões
'''
def tipo_dado(declaracoes):
""" (lis) -> dict
Recebe uma lista com as declarações que serão usadas e retorna um dicionário com o tipo de valor
aceito para cada declaração
:param list declaracoes: Lista com as declarações que serão usadas
:return dict dicionario: Dicionário com os valores aceitos pelas declarações
"""
dicionario = {}
for statement in declaracoes:
# retorna o tipo de valor da declaração
if re.match(r'P\d+|qal\d+|S\d+|s\d+', statement):
statement = re.sub(r'qal|S|s', 'P', statement)
statement = re.sub(r'\..*', '', statement)
if statement not in dicionario:
print(f'Verificando {statement}')
S = requests.Session()
URL = "https://wikidata.org/w/api.php?"
PARAMS = {
"action": "wbgetentities",
"ids": statement,
"format": "json"
}
R = S.get(url=URL, params=PARAMS)
DATA = R.json()
tipo = DATA["entities"][statement]["datatype"]
dicionario[statement] = tipo
elif statement == 'qid':
dicionario[statement] = 'wikibase-item'
elif re.match(r'L|D|A|S.*', statement):
dicionario[statement] = 'string'
else:
print(f'O valor indicado "{statement}" não é uma declaração válida!')
return dicionario
def create(qid, statement, value, datatype):
"""(str, str, str, dict) -> str
Verifica se o valor fornecido é válido e constroi o QS
:param str qid: QID fornecido
:param str statement: Declaração fornecida
:param str value: Valor fornecido
:param dict datatype: Dicionário com os tipos de valores para as declarações
:return str result: QS
"""
source = False
if re.match(r'S\d+|s\d+', statement):
source = True
qualifier = False
if re.match(r'qal\d+', statement):
qualifier = True
if re.match(r'qal\d+|S\d+|s\d+', statement):
statement = re.sub(r'qal|S|s', 'P', statement)
# tipo de dado
tipo = datatype[statement]
if tipo == 'wikibase-item' or tipo == 'time':
result = value
elif tipo == 'monolingualtext':
result = re.sub(r':(.*)', ':"\\1"', value)
else:
result = f'"{value}"'
if source:
statement = re.sub(r'P', 'S', statement)
return f'|{statement}|{result}'
elif qualifier:
return f'|{statement}|{result}'
else:
return f'{qid}|{statement}|{result}'
def csv2qs_builder(dataframe):
"""(dataframe) -> None
Executa o script
:param object dataframe: dataframe com as informações para o QuicStatements
:return:
"""
# Cria dataframe
df = dataframe
colunas = df.columns
data_type = tipo_dado(colunas)
# Escreve o QS
QS = ''
for linha in range(0, len(df.index)):
# Define se irá criar ou editar um item no Wikidata com base na coluna qid
QID = df.loc[linha, 'qid']
if pd.notna(QID):
if re.match(r'Q\d+', QID):
QID = f'||{QID}'
else:
print(f'QID inválido: {QID}')
else:
QS += '||CREATE'
QID = '||LAST'
# obtém o valor em cada coluna da linha
for i in range(0, len(colunas)):
declaracao = colunas[i]
# Ignora a coluna qid e verifica as outras colunas
if declaracao != 'qid':
declaracao = re.sub(r'\..*', '', declaracao)
valor = df.iloc[linha, i]
# se não é um valor nan o comando é criado
if pd.notna(valor):
valor = str(valor)
payload = create(QID, declaracao, valor, data_type)
QS += payload
# Encode url
toolforge = 'https://quickstatements.toolforge.org/#/v1='
encode = urllib.parse.quote(QS, safe='')
# print(f'{toolforge}{encode}')
# print(QS)
return f'{toolforge}{encode}'