-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtables.py
More file actions
113 lines (85 loc) · 4.11 KB
/
Copy pathtables.py
File metadata and controls
113 lines (85 loc) · 4.11 KB
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
"""
Модуль предназначен для извлечения в простом и удобном виде шаблонов таблиц
склонения и спряжения из русского викисловаря. Имена шаблонов извлекаются
из дампа, их рендер в html запрашивается у сервера и преобразуется в
простейшую псевдографику.
Module is devoted to extraction of conjugation and declension tamplate tables
and their rendering to plain text form.
"""
import re
import os
import sys
import xml.etree.ElementTree as ET
import http.client
import urllib.parse
import rwe.pages
# !!! NOTE Шаблон:прил ru 2a has two templates in one cell
def render(template_name, text, output_directory):
"""
Преобразует и сохраняет html табличку в простом виде.
Converts and saves html table as plain text table.
"""
parser = ET.XMLPullParser(events=("start", "end"))
parser.feed('<fakeroot>')
parser.feed(text)
dump_file = os.path.join(output_directory, template_name.replace('Шаблон:', '').replace('/', '%') + '.table')
of = open(dump_file, 'w')
table = False
try:
for event, elem in parser.read_events():
if event == 'start' and elem.tag == 'table' and 'style' in elem.attrib and re.match('float *: *right;', elem.attrib['style']):
table = True
if table and event == 'end' and elem.tag == 'table':
break
if table and event == 'end' and elem.tag == 'tr':
print('', file=of)
if table and event == 'end' and (elem.tag == 'th' or elem.tag == 'td'):
text = elem.text
if text is None:
a = elem.find('a')
if a is not None: text = a.text
if text is not None:
print(text.strip(), '|', end=' ', file=of)
if not table and event == 'end':
elem.clear()
except ET.ParseError as e:
print(e)
os.remove(dump_file)
exit(1)
of.close()
def extract_and_render(dump_file, output_directory, address, save_html=False):
"""
Находит таблицы склонения и спряжения в дампе русского викисловаря, запрашивает их
рендер у сервера и сохраняет их по файлам в упрощённом виде.
Finds declension and conjugation tables in ruwiktionary dump, requests their render
from server and save in plain text form.
"""
if not os.path.isdir(output_directory):
if os.path.exists(output_directory):
raise Exception('Tables directory "{}" exists but is not directory'.format(output_directory))
os.mkdir(output_directory)
print('Parsing wiktionary dump for templates, be patient')
template_names = rwe.pages.extract('Шаблон:(прич|сущ|гл|мест|прил|числ) ru', dump_file)
print('Templates extracted:', *template_names, sep='\n')
connection = http.client.HTTPConnection(address)
# connection = http.client.HTTPSConnection("proxy", 3128)
# connection.set_tunnel(address)
for template_name in template_names:
params = {
'action': 'render',
'title': template_name
}
print('Rendering html for', template_name)
connection.request('GET', '/w/index.php?{}'.format(urllib.parse.urlencode(params)))
r = connection.getresponse()
if r.status != 200:
print("Can't get", template_name, "template from wiktionary =\\")
continue
text = r.read().decode()
if save_html:
with open(os.path.join(output_directory, template_name.replace('Шаблон:', '').replace('/', '%') + '.html'), 'w') as f:
print(text, file=f)
render(template_name, text, output_directory)
connection.close()
def main(args):
extract_and_render(args.dump_file, args.output_directory, args.address, args.save_html)