veekun_pokedex/scripts/markdown-identifiers.py

162 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Encoding: UTF-8
"""Rewrite Markdown strings to use identifiers instead of names
This is an unmaintained one-shot script, only included in the repo for reference.
"""
from functools import partial
import sys
import re
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy.sql.expression import func
from pokedex.db import connect, tables
sanity_re = re.compile(ur"^[-A-Za-z0-9 é\[\]{}.%':;,×/()\"|`—!*♂♀\\]$")
# RE that matches anything that might look like a link
fuzzy_link_re = re.compile(r"""
\[
[^]]+
\]
\{
[^}]+
\}""", re.VERBOSE)
# Very specific RE that matches links that appear in our Markdown strings
strict_link_re = re.compile(r"""
\[
(?P<label>
[-A-Za-z 0-9'.]{,30}
)
\]
\{
(?P<category>
[a-z]{,20}
)
(
:
(?P<target>
[A-Za-z 0-9]{,20}
)
)?
\}
""", re.VERBOSE)
english_id = 9
def is_md_col(column):
return column.info.get('format') == 'markdown'
manual_replacements = {
(
u'Used in battle\n: Attempts to [catch]{mechanic} a wild Pok\xe9mon, using a catch rate of 1.5\xd7.\n\nThis item can only be used in the [Great Marsh]{location} or [Safari Zone]{location}.',
u'[Safari Zone]{location}',
): 'in a Safari Zone',
(
u'Used outside of battle\n: Transports the trainer to the last-entered dungeon entrance. Cannot be used outside, in buildings, or in [Distortion World]{location}, [Hall of Origin]{location}, [Spear Pillar]{location}, or [Turnback Cave]{location}.',
u'[Hall of Origin]{location}',
): '[Hall of Origin]{location:hall-of-origin-1}',
(
u'Give to the [Wingull]{pokemon} on [Route 13]{location}, along with [Gram 2]{item} and [Gram 3]{item}, to receive [TM89]{item}.',
u'[Route 13]{location}',
): u'[Route 13]{location:unova-route-13}',
(
u'Give to the [Wingull]{pokemon} on [Route 13]{location}, along with [Gram 1]{item} and [Gram 3]{item}, to receive [TM89]{item}.',
u'[Route 13]{location}',
): u'[Route 13]{location:unova-route-13}',
(
u'Give to the [Wingull]{pokemon} on [Route 13]{location}, along with [Gram 1]{item} and [Gram 2]{item}, to receive [TM89]{item}.',
u'[Route 13]{location}',
): u'[Route 13]{location:unova-route-13}',
(
u"Forms have different stats and movepools. In Generation III, Deoxys's form depends on the game: Normal Forme in Ruby and Sapphire, Attack Forme in FireRed, Defense Forme in LeafGreen, and Speed Forme in Emerald. In Generation IV, every form exists: form is preserved when transferring via [Pal Park]{location}, and meteorites in the southeast corner of [Veilstone City]{location} or at the west end of [Route 3]{location} can be used to switch between forms.",
u'[Route 3]{location}',
): u'[Route 3]{location:kanto-route-13}',
}
def get_replacement(session, entire_text, matchobj):
print "%-30s" % matchobj.group(0),
label = matchobj.group('label')
category = matchobj.group('category')
target = matchobj.group('target') or label
try:
result = manual_replacements[entire_text, matchobj.group(0)]
except KeyError:
if category == 'mechanic':
target = target.lower()
else:
query = None
if category == 'item':
table = tables.Item
elif category == 'ability':
table = tables.Ability
elif category == 'move':
table = tables.Move
elif category == 'type':
table = tables.Type
elif category == 'pokemon':
table = tables.Pokemon
query = session.query(table).filter(tables.Pokemon.id < 10000)
elif category == 'location':
table = tables.Location
else:
print
print repr(entire_text)
print repr(matchobj.group(0))
raise ValueError('Category %s not implemented' % category)
if not query:
query = session.query(table)
query = query.join(table.names_local)
query = query.filter(func.lower(table.names_table.name) == target.lower())
try:
thingy = query.one()
target = thingy.identifier
except:
print
print repr(entire_text)
print repr(matchobj.group(0))
raise
result = "[%s]{%s:%s}" % (label, category, target)
print result
return result
def main(argv):
session = connect()
for cls in tables.mapped_classes:
for translation_class in cls.translation_classes:
columns = translation_class.__table__.c
md_columns = [c for c in columns if c.info.get('format') == 'markdown']
if not md_columns:
continue
for row in session.query(translation_class):
if row.local_language_id != english_id:
continue
for column in md_columns:
markdown = getattr(row, column.name)
if not markdown:
continue
text = unicode(markdown)
# Make sure everything that remotely looks like a link is one
links = fuzzy_link_re.findall(text)
if not links:
continue
for link in links:
assert strict_link_re.findall(link), [link]
# Do the replacement
replaced = strict_link_re.sub(
partial(get_replacement, session, text),
text,
)
setattr(row, column.name, replaced)
if argv and argv[0] == '--commit':
session.commit()
print 'Committed'
else:
print 'Run with --commit to commit changes'
if __name__ == '__main__':
main(sys.argv[1:])