Implemented an ugly (but complete!) GTS listing. veekun-promotions/2010070701 veekun-promotions/2010080801 veekun-promotions/2010080802
authorEevee <git@veekun.com>
Thu, 8 Jul 2010 05:32:32 +0000 (22:32 -0700)
committerEevee <git@veekun.com>
Thu, 8 Jul 2010 05:32:32 +0000 (22:32 -0700)
splinext/gts/__init__.py
splinext/gts/controllers/gts.py
splinext/gts/controllers/gts_browse.py [new file with mode: 0644]
splinext/gts/templates/css/gts.mako
splinext/gts/templates/gts/list.mako [new file with mode: 0644]

index 370be29..174e8db 100644 (file)
@@ -5,6 +5,7 @@ from pylons import c, session
 from spline.lib.plugin import PluginBase
 from spline.lib.plugin import PluginBase, PluginLink, Priority
 import splinext.gts.controllers.gts
 from spline.lib.plugin import PluginBase
 from spline.lib.plugin import PluginBase, PluginLink, Priority
 import splinext.gts.controllers.gts
+import splinext.gts.controllers.gts_browse
 
 def add_routes_hook(map, *args, **kwargs):
     """Hook to inject some of our behavior into the routes configuration."""
 
 def add_routes_hook(map, *args, **kwargs):
     """Hook to inject some of our behavior into the routes configuration."""
@@ -12,11 +13,15 @@ def add_routes_hook(map, *args, **kwargs):
     map.connect('/pokemondpds/worldexchange/{page}.asp', controller='gts', action='dispatch')
     map.connect('/pokemondpds/common/{page}.asp', controller='gts', action='dispatch')
 
     map.connect('/pokemondpds/worldexchange/{page}.asp', controller='gts', action='dispatch')
     map.connect('/pokemondpds/common/{page}.asp', controller='gts', action='dispatch')
 
+    # Web-side stuff
+    map.connect('/gts', controller='gts_browse', action='list')
+
 
 class GTSPlugin(PluginBase):
     def controllers(self):
         return dict(
             gts = splinext.gts.controllers.gts.GTSController,
 
 class GTSPlugin(PluginBase):
     def controllers(self):
         return dict(
             gts = splinext.gts.controllers.gts.GTSController,
+            gts_browse = splinext.gts.controllers.gts_browse.GTSBrowseController,
         )
 
     def hooks(self):
         )
 
     def hooks(self):
index 5f7bfaf..15b3457 100644 (file)
@@ -12,7 +12,7 @@ import struct
 import pokedex.db
 import pokedex.db.tables as tables
 import pokedex.formulae
 import pokedex.db
 import pokedex.db.tables as tables
 import pokedex.formulae
-from pokedex.savefile import PokemonSave
+from pokedex.struct import SaveFilePokemon
 from pylons import config, request, response, session, tmpl_context as c, url
 from pylons.controllers.util import abort, redirect_to
 from sqlalchemy import and_, or_, not_
 from pylons import config, request, response, session, tmpl_context as c, url
 from pylons.controllers.util import abort, redirect_to
 from sqlalchemy import and_, or_, not_
@@ -156,7 +156,7 @@ class GTSController(BaseController):
                 .one()
             # We've got one!  Cool, send it back.  The game will ask us to
             # delete it after receiving successfully
                 .one()
             # We've got one!  Cool, send it back.  The game will ask us to
             # delete it after receiving successfully
-            pokemon_save = PokemonSave(stored_pokemon.pokemon_blob)
+            pokemon_save = SaveFilePokemon(stored_pokemon.pokemon_blob)
             return pokemon_save.as_encrypted
 
         except:
             return pokemon_save.as_encrypted
 
         except:
@@ -186,7 +186,7 @@ class GTSController(BaseController):
 
         try:
             # The uploaded Pokémon is encrypted, which is not very useful
 
         try:
             # The uploaded Pokémon is encrypted, which is not very useful
-            pokemon_save = PokemonSave(data, encrypted=True)
+            pokemon_save = SaveFilePokemon(data, encrypted=True)
 
             # Create a record...
             stored_pokemon = gts_model.GTSPokemon(
 
             # Create a record...
             stored_pokemon = gts_model.GTSPokemon(
diff --git a/splinext/gts/controllers/gts_browse.py b/splinext/gts/controllers/gts_browse.py
new file mode 100644 (file)
index 0000000..09a398b
--- /dev/null
@@ -0,0 +1,32 @@
+# encoding: utf8
+from __future__ import absolute_import, division
+
+import logging
+
+import pokedex.db
+import pokedex.db.tables as tables
+from pokedex.struct import SaveFilePokemon
+from pylons import config, request, response, session, tmpl_context as c, url
+from pylons.controllers.util import abort, redirect_to
+from sqlalchemy.orm.exc import NoResultFound
+
+from spline.model import meta
+from spline.lib.base import BaseController, render
+from spline.lib import helpers as h
+from splinext.gts import model as gts_model
+
+log = logging.getLogger(__name__)
+
+class GTSBrowseController(BaseController):
+
+    def list(self):
+        u"""Show a list of all Pokémon currently uploaded to the GTS."""
+
+        gts_pokemons = meta.Session.query(gts_model.GTSPokemon).all()
+
+        c.savefiles = []
+        for gts_pokemon in gts_pokemons:
+            savefile = SaveFilePokemon(gts_pokemon.pokemon_blob)
+            c.savefiles.append(savefile)
+
+        return render('/gts/list.mako')
index e69de29..9a21ba1 100644 (file)
@@ -0,0 +1,12 @@
+.gts-pokemon { margin: 1em 0; }
+.gts-pokemon .icon { display: block; float: right; margin: 0 0 16px 16px; }
+.gts-pokemon .header { height: 32px; line-height: 32px; margin-right: 96px; border: 1px solid #b4c7e6; background: url(${h.static_uri('local', 'images/layout/th-background.png')}) left bottom repeat-x; vertical-align: middle; }
+.gts-pokemon .header .name { float: left; font-size: 1.5em; padding: 0 1em; line-height: 32px; }
+.gts-pokemon .header .name .gender { font-size: 0.67em; vertical-align: top; }
+.gts-pokemon .header .personality { float: right; font-size: 0.83em; padding: 0 0.5em; line-height: 16px; font-family: monospace; text-align: right; }
+.gts-pokemon p { margin: 0.5em 0.75em; }
+.gts-pokemon .secret-id { color: #909090; }
+.gts-pokemon ul.gts-pokemon-markings li { display: inline; }
+.gts-pokemon ul.gts-pokemon-ribbons li { display: inline; }
+.gts-pokemon ul.gts-pokemon-leaves li { display: inline-block; width: 16px; height: 16px; }
+.gts-pokemon .gts-pokemon-columns table tbody th { text-align: left; }
diff --git a/splinext/gts/templates/gts/list.mako b/splinext/gts/templates/gts/list.mako
new file mode 100644 (file)
index 0000000..a94259b
--- /dev/null
@@ -0,0 +1,237 @@
+<%inherit file="/base.mako" />
+
+<%def name="title()">Stored Pokémon</%def>
+
+% for savefile in c.savefiles:
+<div class="gts-pokemon">
+    % if savefile.structure.ivs.is_egg:
+    ${h.pokedex.pokedex_img("heartgold-soulsilver/egg.png", class_='icon')}
+    % else:
+    ${h.pokedex.pokedex_img("heartgold-soulsilver/{0}{1}.png".format(
+            'shiny/' if savefile.is_shiny else '',
+            savefile.structure.national_id),
+        class_='icon')}
+    % endif
+    <div class="header">
+        <div class="name">
+            % if savefile.structure.ivs.is_nicknamed:
+            “${savefile.structure.nickname}”
+            % else:
+            ## XXX pokemon name
+            ${savefile.structure.nickname}
+            % endif
+            <span class="gender ${savefile.structure.gender}">
+                % if savefile.structure.gender == 'male':
+                ♂
+                % elif savefile.structure.gender == 'female':
+                ♀
+                % else:
+                &empty;
+                % endif
+            </span>
+            % if savefile.structure.alternate_form:
+            ~ ${savefile.structure.alternate_form}
+            % endif
+        </div>
+        <div class="personality">
+            ${savefile.structure.personality}<br>
+            ${u"0x{0:08x}".format(savefile.structure.personality)}
+        </div>
+    </div>
+
+    <p>
+        Original trainer:
+        ${savefile.structure.original_trainer_name}
+        ${u'♂' if savefile.structure.original_trainer_gender == 'male' else u'♀'}
+        <img src="${h.static_uri('spline', "flags/{0}.png".format(savefile.structure.original_country))}" alt="${savefile.structure.original_country}">,
+        ID ${savefile.structure.original_trainer_id}
+        <span class="secret-id">/ ${savefile.structure.original_trainer_secret_id}</span>
+    </p>
+    <p>
+        % if savefile.structure.date_egg_received == savefile.structure.date_met:
+        Born and hatched on ${savefile.structure.date_egg_received}
+        % elif savefile.structure.date_egg_received:
+        Born on ${savefile.structure.date_egg_received};
+        hatched on ${savefile.structure.date_met})
+        % else:
+        [${savefile.structure.dppt_pokeball} ${savefile.structure.hgss_pokeball}]
+        Caught on ${savefile.structure.date_met}
+        at level ${savefile.structure.met_at_level}
+        % endif
+
+        at place number ${savefile.structure.dp_met_location_id}
+        or maybe ${savefile.structure.dp_egg_location_id}
+        orrrr ${savefile.structure.pt_met_location_id}
+        or???? ${savefile.structure.pt_egg_location_id}
+        ${h.pokedex.pokedex_img("versions/{0}.png".format(savefile.structure.original_version))}
+
+        ps was a ${savefile.structure.encounter_type}
+        % if savefile.structure.fateful_encounter:
+        also fateful
+        % endif
+    </p>
+
+    <h2>Stats</h2>
+    <dl>
+        <dt>Experience</dt>
+        <dd>${savefile.structure.exp}</dd>
+        <dt>Happiness</dt>
+        <dd>${savefile.structure.happiness}</dd>
+        <dt>Held item</dt>
+        <dd>${savefile.structure.held_item_id}</dd>
+        <dt>Ability</dt>
+        <dd>${savefile.structure.ability_id}</dd>
+        <dt>Pokérus</dt>
+        <dd>${savefile.structure.pokerus}</dd>
+        <dt>Markings</dt>
+        <dd>
+            <ul class="gts-pokemon-markings">
+                % if savefile.structure.markings.heart:
+                <li>&#x2665;</li>
+                % else:
+                <li>&#x2661;</li>
+                % endif
+                % if savefile.structure.markings.diamond:
+                <li>&#x25c6;</li>
+                % else:
+                <li>&#x25c7;</li>
+                % endif
+                % if savefile.structure.markings.triangle:
+                <li>&#x25b2;</li>
+                % else:
+                <li>&#x25b3;</li>
+                % endif
+                % if savefile.structure.markings.square:
+                <li>&#x25a0;</li>
+                % else:
+                <li>&#x25a1;</li>
+                % endif
+                % if savefile.structure.markings.star:
+                <li>&#x2605;</li>
+                % else:
+                <li>&#x2606;</li>
+                % endif
+                % if savefile.structure.markings.circle:
+                <li>&#x25cf;</li>
+                % else:
+                <li>&#x25cb;</li>
+                % endif
+            </ul>
+        </dd>
+        <dt>Shiny leaves</dt>
+        <dd>
+            % if savefile.structure.shining_leaves.crown:
+            ${h.pokedex.pokedex_img('chrome/leaf-crown.png', alt='Leaf Crown', title='Leaf Crown')}
+            % else:
+            <ul class="gts-pokemon-leaves">
+                % for leaf_n in range(1, 6):
+                <li>
+                    % if savefile.structure.shining_leaves['leaf' + str(leaf_n)]:
+                    ${h.pokedex.pokedex_img('chrome/shiny-leaf.png', alt='Shiny Leaf', title='Shiny Leaf')}
+                    % endif
+                </li>
+                % endfor
+            </ul>
+            % endif
+        </dd>
+        <dt>Ribbons</dt>
+        <dd>
+            <ul class="gts-pokemon-ribbons">
+            % for region, ribbon_container in ('hoenn',  savefile.structure.hoenn_ribbons), \
+                                              ('sinnoh', savefile.structure.sinnoh_ribbons), \
+                                              ('sinnoh', savefile.structure.sinnoh_contest_ribbons):
+                % for ribbon in reversed(ribbon_container.__attrs__):
+                % if ribbon_container[ribbon]:
+                <li>${h.pokedex.pokedex_img("ribbons/{0}/{1}.png".format(region, ribbon.replace(u'_', u'-')), alt=ribbon.replace(u'_', u' ').title(), title=ribbon.replace(u'_', u' ').title())}</li>
+                % endif
+                % endfor
+            % endfor
+            </ul>
+        </dd>
+    </dl>
+
+    <div class="dex-column-container gts-pokemon-columns">
+    <div class="dex-column">
+        <table>
+        <thead>
+            <tr class="header-row">
+                <th>Stat</th>
+                <th>Gene</th>
+                <th>Exp</th>
+            </tr>
+        </thead>
+        <tbody>
+            <tr>
+                <th>HP</th>
+                <td>${savefile.structure.ivs.iv_hp}</td>
+                <td>${savefile.structure.effort_hp}</td>
+            </tr>
+            <tr>
+                <th>Attack</th>
+                <td>${savefile.structure.ivs.iv_attack}</td>
+                <td>${savefile.structure.effort_attack}</td>
+            </tr>
+            <tr>
+                <th>Defense</th>
+                <td>${savefile.structure.ivs.iv_defense}</td>
+                <td>${savefile.structure.effort_defense}</td>
+            </tr>
+            <tr>
+                <th>Special Attack</th>
+                <td>${savefile.structure.ivs.iv_special_attack}</td>
+                <td>${savefile.structure.effort_special_attack}</td>
+            </tr>
+            <tr>
+                <th>Special Defense</th>
+                <td>${savefile.structure.ivs.iv_special_defense}</td>
+                <td>${savefile.structure.effort_special_defense}</td>
+            </tr>
+            <tr>
+                <th>Speed</th>
+                <td>${savefile.structure.ivs.iv_speed}</td>
+                <td>${savefile.structure.effort_speed}</td>
+            </tr>
+        </tbody>
+        </table>
+    </div>
+    <div class="dex-column">
+        <table>
+        <thead>
+            <tr class="header-row">
+                <th>move_id</th>
+                <th>pp</th>
+                <th>pp_ups</th>
+            </tr>
+        </thead>
+        <tbody>
+            % for i in range(1, 5):
+            <tr>
+                <td>${savefile.structure['move' + str(i) + '_id']}</td>
+                <td>${savefile.structure['move' + str(i) + '_pp']}</td>
+                <td>${savefile.structure['move' + str(i) + '_pp_ups']}</td>
+            </tr>
+            % endfor
+        </tbody>
+        </table>
+    </div>
+    <div class="dex-column">
+        <table>
+        <thead>
+            <tr class="header-row">
+                <th></th>
+                <th></th>
+            </tr>
+        </thead>
+        <tbody>
+            % for contest_stat in ('beauty', 'cool', 'cute', 'smart', 'tough'):
+            <tr>
+                <th>${contest_stat}</th>
+                <td>${savefile.structure['contest_' + contest_stat]}</td>
+            </tr>
+            % endfor
+        </tbody>
+        </table>
+    </div>
+    </div>
+</div>
+% endfor