mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Make bad links in Markdown not fail
Links such as []{pokemon:mewthree} can come from users, so they should not crash the parser. So, when an object is not found (or more than one is found), call identifier_url() directly, instead of failing to get the object for object_url(). Essentially, treat the link as having an unknown category (like mechanic:, currently). The test that check the pokédex descriptions updated so that only links to known objects and "mechanic:" are allowed.
This commit is contained in:
parent
cdac374eed
commit
928eaca4a4
2 changed files with 49 additions and 32 deletions
|
@ -170,16 +170,22 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern):
|
|||
query = query.join(tables.Pokemon.species)
|
||||
query = query.filter(
|
||||
tables.PokemonSpecies.identifier == pokemon_ident)
|
||||
obj = query.one()
|
||||
else:
|
||||
obj = util.get(self.session, table, target)
|
||||
query = session.query(table)
|
||||
query = query.filter(table.identifier == target)
|
||||
try:
|
||||
obj = query.one()
|
||||
except Exception:
|
||||
obj = name = target
|
||||
url = self.factory.identifier_url(category, obj)
|
||||
else:
|
||||
url = self.factory.object_url(category, obj)
|
||||
url = url or self.factory.identifier_url(category, target)
|
||||
name = None
|
||||
# Translations can be incomplete; in which case we want to use a
|
||||
# fallback.
|
||||
# Translations can be incomplete; in which case we want to use
|
||||
# a fallback.
|
||||
if table in [tables.Type] and self.string_language:
|
||||
# Type wants to be localized to the same language as the text
|
||||
# Type wants to be localized to the text language
|
||||
name = obj.name_map.get(self.string_language)
|
||||
if not name and self.game_language:
|
||||
name = obj.name_map.get(self.game_language)
|
||||
|
@ -222,12 +228,18 @@ class PokedexLinkExtension(markdown.Extension):
|
|||
|
||||
Returns None by default, which causes <span> to be used in place of
|
||||
<a>.
|
||||
|
||||
This method is also called for non-existent objects, e.g.
|
||||
[]{pokemon:bogus}.
|
||||
"""
|
||||
return None
|
||||
|
||||
def object_url(self, category, obj):
|
||||
"""Return the URL for the ORM object `obj`.
|
||||
u"""Return the URL for the ORM object `obj`.
|
||||
|
||||
Returns None by default, which causes identifier_url to be tried.
|
||||
|
||||
Note that obj may be a Pokémon form. Unlike other returned objects,
|
||||
these do not have identifiers. Be sure to test this case.
|
||||
"""
|
||||
return None
|
||||
|
|
|
@ -92,9 +92,9 @@ def test_markdown():
|
|||
|
||||
def test_markdown_string():
|
||||
en = util.get(connection, tables.Language, 'en')
|
||||
md = markdown.MarkdownString('[]{move:thunderbolt} [paralyzes]{mechanic:paralysis} []{form:sky shaymin}', connection, en)
|
||||
assert unicode(md) == 'Thunderbolt paralyzes Sky Shaymin'
|
||||
assert md.as_html() == '<p><span>Thunderbolt</span> <span>paralyzes</span> <span>Sky Shaymin</span></p>'
|
||||
md = markdown.MarkdownString('[]{move:thunderbolt} [paralyzes]{mechanic:paralysis} []{form:sky shaymin}. []{pokemon:mewthree} does not exist.', connection, en)
|
||||
assert unicode(md) == 'Thunderbolt paralyzes Sky Shaymin. mewthree does not exist.'
|
||||
assert md.as_html() == '<p><span>Thunderbolt</span> <span>paralyzes</span> <span>Sky Shaymin</span>. <span>mewthree</span> does not exist.</p>'
|
||||
|
||||
class ObjectTestExtension(markdown.PokedexLinkExtension):
|
||||
def object_url(self, category, obj):
|
||||
|
@ -109,9 +109,9 @@ def test_markdown_string():
|
|||
return "%s/%s" % (category, ident)
|
||||
|
||||
assert md.as_html(extension_cls=ObjectTestExtension) == (
|
||||
'<p><a href="move/thunderbolt">Thunderbolt</a> <span>paralyzes</span> <a href="form/sky shaymin">Sky Shaymin</a></p>')
|
||||
'<p><a href="move/thunderbolt">Thunderbolt</a> <span>paralyzes</span> <a href="form/sky shaymin">Sky Shaymin</a>. <span>mewthree</span> does not exist.</p>')
|
||||
assert md.as_html(extension_cls=IdentifierTestExtension) == (
|
||||
'<p><a href="move/thunderbolt">Thunderbolt</a> <a href="mechanic/paralysis">paralyzes</a> <a href="form/sky shaymin">Sky Shaymin</a></p>')
|
||||
'<p><a href="move/thunderbolt">Thunderbolt</a> <a href="mechanic/paralysis">paralyzes</a> <a href="form/sky shaymin">Sky Shaymin</a>. <a href="pokemon/mewthree">mewthree</a> does not exist.</p>')
|
||||
|
||||
def markdown_column_params():
|
||||
"""Check all markdown values
|
||||
|
@ -136,23 +136,28 @@ def test_markdown_values(parent_class, translation_class, column_name):
|
|||
query = connection.query(parent_class)
|
||||
if translation_class:
|
||||
query = query.join(translation_class)
|
||||
for item in query:
|
||||
for language, markdown in getattr(item, column_name + '_map').items():
|
||||
|
||||
if markdown is None:
|
||||
for item in query:
|
||||
for language, md_text in getattr(item, column_name + '_map').items():
|
||||
|
||||
if md_text is None:
|
||||
continue
|
||||
|
||||
key = u"Markdown in {0} #{1}'s {2} (lang={3})".format(
|
||||
parent_class.__name__, item.id, column_name, language.identifier)
|
||||
|
||||
try:
|
||||
text = markdown.as_text()
|
||||
except NoResultFound:
|
||||
assert False, u"{0} references something that doesn't exist:\n{1}".format(
|
||||
key, markdown.source_text)
|
||||
except AttributeError:
|
||||
print markdown
|
||||
raise
|
||||
class TestExtension(markdown.PokedexLinkExtension):
|
||||
def object_url(self, category, obj):
|
||||
"Swallow good links"
|
||||
return 'ok'
|
||||
|
||||
def identifier_url(self, category, ident):
|
||||
"Only allow mechanic links here (good links handled in object_url)"
|
||||
assert category == 'mechanic', (
|
||||
'%s: unknown link target: {%s:%s}' %
|
||||
(key, category, ident))
|
||||
|
||||
text = md_text.as_html(extension_cls=TestExtension)
|
||||
|
||||
error_message = u"{0} leaves syntax cruft:\n{1}"
|
||||
error_message = error_message.format(key, text)
|
||||
|
|
Loading…
Reference in a new issue