mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Merge branch 'doc'
This commit is contained in:
commit
2af1d5f428
12 changed files with 1287 additions and 18 deletions
146
doc/Makefile
Normal file
146
doc/Makefile
Normal file
|
@ -0,0 +1,146 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
all: doctest
|
||||
$(MAKE) html coverage
|
||||
|
||||
commit:
|
||||
mkdir -p _gh-pages
|
||||
(cd _gh-pages && git init || true)
|
||||
rm -rf _build/html/.git
|
||||
cp -r _gh-pages/.git _build/html
|
||||
(cd _build/html && git add . && git commit -m "sphinx build $$(date --rfc-3339=seconds)" || true)
|
||||
(cd _gh-pages && git pull ../_build/html)
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
touch $(BUILDDIR)/html/.nojekyll
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pokedex.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pokedex.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/pokedex"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pokedex"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
make -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
cat $(BUILDDIR)/coverage/*.txt
|
230
doc/conf.py
Normal file
230
doc/conf.py
Normal file
|
@ -0,0 +1,230 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# pokedex documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Apr 12 17:43:05 2011.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding("UTF-8")
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.pngmath',
|
||||
'sphinx.ext.intersphinx',
|
||||
#'sphinx.ext.viewcode',
|
||||
'sphinx.ext.coverage',
|
||||
'pokedex.doc.tabledoc',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
source_encoding = 'utf-8'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'pokedex'
|
||||
copyright = u'2011, Alex Munroe (Eevee)'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
intersphinx_mapping = {'sqlalchemy': ('http://www.sqlalchemy.org/docs', None)}
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
html_show_copyright = False
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'pokedexdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'pokedex.tex', u'Pokedex Documentation',
|
||||
u'veekun', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'pokedex', u'Pokedex Documentation',
|
||||
[u'veekun'], 1)
|
||||
]
|
25
doc/index.rst
Normal file
25
doc/index.rst
Normal file
|
@ -0,0 +1,25 @@
|
|||
.. pokedex documentation master file, created by
|
||||
sphinx-quickstart on Tue Apr 12 17:43:05 2011.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
The pokedex documentation
|
||||
=========================
|
||||
|
||||
Jump right in!
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installing
|
||||
usage
|
||||
schema
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
156
doc/installing.rst
Normal file
156
doc/installing.rst
Normal file
|
@ -0,0 +1,156 @@
|
|||
Installing the pokedex library
|
||||
==============================
|
||||
|
||||
Quick startup with Ubuntu/Debian-like systems
|
||||
---------------------------------------------
|
||||
|
||||
Run the following from an empty directory::
|
||||
|
||||
$ sudo apt-get install git python python-pip python-sqlalchemy
|
||||
$ git clone git://github.com/veekun/pokedex.git
|
||||
$ pip install -E env -e pokedex
|
||||
$ source env/bin/activate
|
||||
(env)$ pokedex setup -v
|
||||
(env)$ pokedex lookup eevee
|
||||
|
||||
If it all goes smoothly, you can now use ``env/bin/pokedex``, the command-line
|
||||
tool, and ``env/bin/python``, a Python interpreter configured to use the
|
||||
pokedex library.
|
||||
|
||||
That is all you need. Feel free to skip the rest of this chapter if you're not
|
||||
interested in the details.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Linux
|
||||
^^^^^
|
||||
|
||||
Ubuntu/Debian users should run the following::
|
||||
|
||||
$ sudo apt-get install git python python-pip
|
||||
|
||||
With other Linuxes, install the packages for git, python (2.6 or 2.7,
|
||||
*not* 3.x), and python-pip.
|
||||
|
||||
If you succeeded, skip the Detailed instructions.
|
||||
|
||||
Detailed instructions
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You should know what a command line is and how to work with it.
|
||||
The here we assume you're using Linux [#]_, if that's not the case, make
|
||||
sure you have enough computer knowledge to translate the instructions to your
|
||||
operating system.
|
||||
|
||||
Pokedex is distributed via Git_. So, get Git.
|
||||
|
||||
You will also need Python_ 2; the language pokedex is written in. Be sure to get
|
||||
version **2.6** or **2.7**. Pokedex does not work with Python 3.x yet, and it
|
||||
most likely won't work with 2.5 or earlier.
|
||||
|
||||
Next, get pip_, a tool to install Python packages. Experts can use another
|
||||
tool, of course.
|
||||
|
||||
Make sure git and pip are on your path.
|
||||
|
||||
Optionally you can install SQLAlchemy_, `Python markdown`_, Whoosh_,
|
||||
or construct_. If you don't, pip will atuomatically download and install a copy
|
||||
for you, but some are pretty big so you might want to install it system-wide.
|
||||
(Unfortunately, many distros have outdated versions of these libraries, so pip
|
||||
will install pokedex's own copy anyway.)
|
||||
|
||||
Getting and installing pokedex
|
||||
------------------------------
|
||||
|
||||
Run the following from an empty directory::
|
||||
|
||||
$ git clone git://git.veekun.com/pokedex.git
|
||||
$ pip install -E env -e pokedex
|
||||
|
||||
This will give you two directories: pokedex (containing the source code and
|
||||
data), and env (a virtualenv_).
|
||||
|
||||
In env/bin, there are three interesting files:
|
||||
|
||||
* pokedex: The pokedex program
|
||||
* python: A copy of Python that knows about pokedex and its prerequisites.
|
||||
* activate: Typing ``source env/bin/activate`` in a shell will put
|
||||
pokedex and our bin/python on the $PATH, and generally set things up to work
|
||||
with them. Your prompt will change to let you know of this. You can end such
|
||||
a session by typing ``deactivate``.
|
||||
|
||||
This documentation will assume that you've activated the virtualenv, so
|
||||
``pokedex`` means ``env/bin/pokedex``.
|
||||
|
||||
Advanced
|
||||
^^^^^^^^
|
||||
|
||||
You can of course install into an existing virtualenv, by either using its pip
|
||||
and leaving out the ``-E env``, or running the setup script directly::
|
||||
|
||||
(anotherenv)$ cd pokedex
|
||||
(anotherenv)pokedex$ python setup.py develop
|
||||
|
||||
It is also possible to install pokedex system-wide. There are problems with
|
||||
that. Don't do it. The only time you need ``sudo`` is for getting the
|
||||
prerequisites.
|
||||
|
||||
Loading the database
|
||||
--------------------
|
||||
|
||||
Before you can do anything useful with pokedex, you need to load the database::
|
||||
|
||||
$ pokedex setup -v
|
||||
|
||||
This will load the data into a default SQLite database and create a default
|
||||
Whoosh index.
|
||||
|
||||
Advanced
|
||||
^^^^^^^^
|
||||
|
||||
If you want to use another database, make sure you have the corresponding
|
||||
`SQLAlchemy engine`_ for it and either use the ``-e`` switch, (e.g.
|
||||
``-e postgresql://@/pokedex``), or set the ``POKEDEX_DB_ENGINE`` environment
|
||||
variable.
|
||||
|
||||
To use another lookup index directory, specify it with ``-i`` or the
|
||||
``POKEDEX_INDEX_DIR`` variable.
|
||||
|
||||
Make sure you always use the same options whenever you use pokedex.
|
||||
|
||||
If you're confused about what pokedex thinks its settings are, check
|
||||
``pokedex status``.
|
||||
|
||||
See ``pokedex help`` for even more options.
|
||||
|
||||
All done
|
||||
--------
|
||||
|
||||
To verify that all went smoothly, check that the pokedex tool finds your
|
||||
favorite pokémon::
|
||||
|
||||
$ pokedex lookup eevee
|
||||
|
||||
Yes, that was a bit anti-climatic. The command-line tool doesn't do much,
|
||||
currently.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. _Git: http://git-scm.com/
|
||||
.. _Python: http://www.python.org/
|
||||
.. _pip: http://pypi.python.org/pypi/pip
|
||||
.. _SQLAlchemy: www.sqlalchemy.org/
|
||||
.. _`Python markdown`: http://www.freewisdom.org/projects/python-markdown/
|
||||
.. _Whoosh: http://whoosh.ca/
|
||||
.. _construct: pypi.python.org/pypi/construct
|
||||
.. _virtualenv: http://www.virtualenv.org/en/latest/
|
||||
.. _`SQLAlchemy engine`: http://www.sqlalchemy.org/docs/core/engines.html
|
||||
|
||||
.. rubric:: Footnotes
|
||||
.. [#] If you write instructions for another OS, well be happy to include them
|
||||
here. The reason your OS is not listed here is because the author doesn't
|
||||
use it, so naturally he can't write instructions for it.
|
179
doc/main-tables.rst
Normal file
179
doc/main-tables.rst
Normal file
|
@ -0,0 +1,179 @@
|
|||
The pokédex tables
|
||||
==================
|
||||
|
||||
.. module:: pokedex.db.tables
|
||||
|
||||
The :mod:`pokedex.db.tables` module defines all of the tables in the Pokédex.
|
||||
They are all defined with SQLAlchemy's
|
||||
:mod:`~sqlalchemy.ext.declarative` extension.
|
||||
|
||||
To introspect the tables programmatically, you can use the following:
|
||||
|
||||
.. data:: mapped_classes
|
||||
|
||||
A list of all the classes you see below.
|
||||
|
||||
.. data:: metadata
|
||||
|
||||
The SQLAlchemy :class:`~sqlalchemy.schema.MetaData` containing all the
|
||||
tables.
|
||||
|
||||
Each of the classes has a ``translation_classes`` attribute: a potentially
|
||||
empty list of translation classes. See :mod:`pokedex.db.multilang` for how
|
||||
these work.
|
||||
|
||||
Many tables have these columns:
|
||||
|
||||
- **id**: An integer primary key. Sometimes it's semantically meaningful, most
|
||||
often it isn't.
|
||||
- **identifier**: A string identifier of the class, and the preferred way to
|
||||
access individual items.
|
||||
- **name**: A name (uses the multilang functionality)
|
||||
|
||||
Pokémon
|
||||
-------
|
||||
|
||||
.. dex-table:: PokemonSpecies
|
||||
.. dex-table:: Pokemon
|
||||
.. dex-table:: PokemonForm
|
||||
.. dex-table:: EvolutionChain
|
||||
.. dex-table:: PokemonEvolution
|
||||
|
||||
Moves
|
||||
-----
|
||||
|
||||
.. dex-table:: Move
|
||||
.. dex-table:: MoveEffect
|
||||
.. dex-table:: MoveMeta
|
||||
|
||||
Items
|
||||
-----
|
||||
|
||||
.. dex-table:: Item
|
||||
.. dex-table:: Berry
|
||||
|
||||
Types
|
||||
-----
|
||||
|
||||
.. dex-table:: Type
|
||||
|
||||
Abilities
|
||||
---------
|
||||
|
||||
.. dex-table:: Ability
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
.. dex-table:: Language
|
||||
|
||||
Version stuff
|
||||
-------------
|
||||
|
||||
.. dex-table:: Generation
|
||||
.. dex-table:: VersionGroup
|
||||
.. dex-table:: Version
|
||||
.. dex-table:: Pokedex
|
||||
.. dex-table:: Region
|
||||
|
||||
Encounters
|
||||
----------
|
||||
|
||||
.. dex-table:: Location
|
||||
.. dex-table:: LocationArea
|
||||
.. dex-table:: LocationAreaEncounterRate
|
||||
.. dex-table:: Encounter
|
||||
.. dex-table:: EncounterCondition
|
||||
.. dex-table:: EncounterConditionValue
|
||||
.. dex-table:: EncounterMethod
|
||||
.. dex-table:: EncounterSlot
|
||||
|
||||
|
||||
Contests
|
||||
--------
|
||||
|
||||
.. dex-table:: ContestCombo
|
||||
.. dex-table:: ContestEffect
|
||||
.. dex-table:: SuperContestCombo
|
||||
.. dex-table:: SuperContestEffect
|
||||
|
||||
Enum tables
|
||||
-----------
|
||||
|
||||
.. dex-table:: BerryFirmness
|
||||
.. dex-table:: ContestType
|
||||
.. dex-table:: EggGroup
|
||||
.. dex-table:: EvolutionTrigger
|
||||
.. dex-table:: GrowthRate
|
||||
.. dex-table:: ItemCategory
|
||||
.. dex-table:: ItemFlingEffect
|
||||
.. dex-table:: ItemPocket
|
||||
.. dex-table:: MoveBattleStyle
|
||||
.. dex-table:: MoveDamageClass
|
||||
.. dex-table:: MoveMetaAilment
|
||||
.. dex-table:: MoveMetaCategory
|
||||
.. dex-table:: MoveTarget
|
||||
.. dex-table:: Nature
|
||||
.. dex-table:: PalParkArea
|
||||
.. dex-table:: PokemonColor
|
||||
.. dex-table:: PokemonMoveMethod
|
||||
.. dex-table:: PokemonShape
|
||||
.. dex-table:: Stat
|
||||
|
||||
Changelogs
|
||||
----------
|
||||
|
||||
.. dex-table:: AbilityChangelog
|
||||
.. dex-table:: MoveEffectChangelog
|
||||
.. dex-table:: MoveChangelog
|
||||
|
||||
Flavor text
|
||||
-----------
|
||||
|
||||
.. dex-table:: ItemFlavorText
|
||||
.. dex-table:: AbilityFlavorText
|
||||
.. dex-table:: MoveFlavorText
|
||||
.. dex-table:: PokemonSpeciesFlavorText
|
||||
|
||||
Association tables
|
||||
------------------
|
||||
|
||||
.. dex-table:: BerryFlavor
|
||||
.. dex-table:: EncounterConditionValueMap
|
||||
.. dex-table:: ItemFlag
|
||||
.. dex-table:: ItemFlagMap
|
||||
.. dex-table:: Machine
|
||||
.. dex-table:: MoveFlag
|
||||
.. dex-table:: MoveFlagMap
|
||||
.. dex-table:: MoveMetaStatChange
|
||||
.. dex-table:: NatureBattleStylePreference
|
||||
.. dex-table:: NaturePokeathlonStat
|
||||
.. dex-table:: PokeathlonStat
|
||||
.. dex-table:: PokemonAbility
|
||||
.. dex-table:: PokemonEggGroup
|
||||
.. dex-table:: PokemonFormPokeathlonStat
|
||||
.. dex-table:: PokemonHabitat
|
||||
.. dex-table:: PokemonMove
|
||||
.. dex-table:: PokemonStat
|
||||
.. dex-table:: PokemonItem
|
||||
.. dex-table:: PokemonType
|
||||
.. dex-table:: TypeEfficacy
|
||||
.. dex-table:: VersionGroupPokemonMoveMethod
|
||||
.. dex-table:: VersionGroupRegion
|
||||
|
||||
Index maps
|
||||
----------
|
||||
|
||||
.. dex-table:: ItemGameIndex
|
||||
.. dex-table:: LocationGameIndex
|
||||
.. dex-table:: PokemonDexNumber
|
||||
.. dex-table:: PokemonFormGeneration
|
||||
.. dex-table:: PokemonGameIndex
|
||||
|
||||
Mics tables
|
||||
-----------
|
||||
|
||||
.. dex-table:: Experience
|
||||
.. dex-table:: PalPark
|
||||
.. dex-table:: StatHint
|
||||
|
6
doc/schema.rst
Normal file
6
doc/schema.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
The database schema
|
||||
===================
|
||||
|
||||
.. toctree::
|
||||
|
||||
main-tables
|
193
doc/usage.rst
Normal file
193
doc/usage.rst
Normal file
|
@ -0,0 +1,193 @@
|
|||
Using pokedex
|
||||
=============
|
||||
|
||||
The pokédex is, first and foremost, a Python library. To get the most of it,
|
||||
you'll need to learn `Python`_ and `SQLAlchemy`_.
|
||||
|
||||
Here is a small example of using pokedex:
|
||||
|
||||
.. testcode::
|
||||
|
||||
from pokedex.db import connect, tables, util
|
||||
session = connect()
|
||||
pokemon = util.get(session, tables.PokemonSpecies, 'bulbasaur')
|
||||
print u'{0.name}, the {0.genus} Pokemon'.format(pokemon)
|
||||
|
||||
Running this will give you some Bulbasaur info:
|
||||
|
||||
.. testoutput::
|
||||
|
||||
Bulbasaur, the Seed Pokemon
|
||||
|
||||
Connecting
|
||||
----------
|
||||
|
||||
To get information out of the Pokédex, you will need to create a
|
||||
:class:`Session <pokedex.db.multilang.MultilangSession>`. To do that, use
|
||||
:func:`pokedex.db.connect`. For simple uses, you don't need to give it any
|
||||
arguments: it the database that ``pokedex load`` fills up by default. If you
|
||||
need to select another database, give its URI as the first argument.
|
||||
|
||||
The object :func:`~pokedex.db.connect` gives you is actually a
|
||||
:class:`SQLAlchemy session <sqlalchemy.orm.session.Session>`, giving you the
|
||||
full power of SQLAlchemy for working with the data. We'll cover some basics
|
||||
here, but if you intend to do some serious work, do read SQLAlchemy's docs.
|
||||
|
||||
Pokédex tables
|
||||
--------------
|
||||
|
||||
Data in the pokédex is organized in tables, defined in
|
||||
:mod:`pokedex.db.tables`.
|
||||
There is quite a few or them. To get you started, here are a few common ones:
|
||||
|
||||
* :class:`~pokedex.db.tables.PokemonSpecies`
|
||||
* :class:`~pokedex.db.tables.Move`
|
||||
* :class:`~pokedex.db.tables.Item`
|
||||
* :class:`~pokedex.db.tables.Type`
|
||||
|
||||
Getting things
|
||||
--------------
|
||||
|
||||
If you know what you want from the pokédex, you can use the
|
||||
:func:`pokedex.db.util.get` function. It looks up a thing in a table, based on
|
||||
its identifier, name, or ID, and returns it.
|
||||
|
||||
.. testcode::
|
||||
|
||||
def print_pokemon(pokemon):
|
||||
print u'{0.name}, the {0.genus} Pokemon'.format(pokemon)
|
||||
|
||||
print_pokemon(util.get(session, tables.PokemonSpecies, identifier='eevee'))
|
||||
print_pokemon(util.get(session, tables.PokemonSpecies, name=u'Ho-Oh'))
|
||||
print_pokemon(util.get(session, tables.PokemonSpecies, id=50))
|
||||
|
||||
def print_item(item):
|
||||
print u'{0.name}: ${0.cost}'.format(item)
|
||||
|
||||
print_item(util.get(session, tables.Item, identifier='great-ball'))
|
||||
print_item(util.get(session, tables.Item, name='Potion'))
|
||||
print_item(util.get(session, tables.Item, id=30))
|
||||
|
||||
.. testoutput::
|
||||
|
||||
Eevee, the Evolution Pokemon
|
||||
Ho-Oh, the Rainbow Pokemon
|
||||
Diglett, the Mole Pokemon
|
||||
Great Ball: $600
|
||||
Potion: $300
|
||||
Fresh Water: $200
|
||||
|
||||
Querying
|
||||
--------
|
||||
|
||||
So, how do you get data from the session? You use the session's
|
||||
:meth:`~sqlalchemy.orm.session.Session.query` method, and give it a pokédex
|
||||
Table as an argument. This will give you a :class:`SQLAlchemy query
|
||||
<sqlalchemy.orm.query.Query>`.
|
||||
|
||||
Ordering
|
||||
^^^^^^^^
|
||||
|
||||
As always with SQL, you should not rely on query results being in some
|
||||
particular order – unless you have ordered the query first. This means that
|
||||
you'll want to sort just about every query you will make.
|
||||
|
||||
For example, you can get a list of all pokémon species, sorted by their
|
||||
:attr:`~pokedex.db.tables.PokemonSpecies.id`, like so:
|
||||
|
||||
.. testcode::
|
||||
|
||||
for pokemon in session.query(tables.PokemonSpecies).order_by(tables.PokemonSpecies.id):
|
||||
print pokemon.name
|
||||
|
||||
.. testoutput::
|
||||
|
||||
Bulbasaur
|
||||
Ivysaur
|
||||
Venusaur
|
||||
Charmander
|
||||
Charmeleon
|
||||
...
|
||||
Keldeo
|
||||
Meloetta
|
||||
Genesect
|
||||
|
||||
Or to order by :attr:`~pokedex.db.tables.PokemonSpecies.name`:
|
||||
|
||||
.. testcode::
|
||||
|
||||
for pokemon in session.query(tables.PokemonSpecies).order_by(tables.PokemonSpecies.name):
|
||||
print pokemon.name
|
||||
|
||||
.. testoutput::
|
||||
|
||||
Abomasnow
|
||||
...
|
||||
Zweilous
|
||||
|
||||
|
||||
Filtering
|
||||
^^^^^^^^^
|
||||
|
||||
Another major operation on queries is filtering, using the query's
|
||||
:meth:`~sqlalchemy.orm.query.Query.filter` or
|
||||
:meth:`~sqlalchemy.orm.query.Query.filter_by` methods:
|
||||
|
||||
.. testcode::
|
||||
|
||||
for move in session.query(tables.Move).filter(tables.Move.power > 200):
|
||||
print move.name
|
||||
|
||||
.. testoutput::
|
||||
|
||||
Explosion
|
||||
|
||||
Joining
|
||||
^^^^^^^
|
||||
|
||||
The final operation we'll cover here is joining other tables to the query,
|
||||
using the query's :meth:`~sqlalchemy.orm.query.Query.join`.
|
||||
You will usually want to join on a relationship, such as in the following
|
||||
example:
|
||||
|
||||
.. testcode::
|
||||
|
||||
query = session.query(tables.Move)
|
||||
query = query.join(tables.Move.type)
|
||||
query = query.filter(tables.Type.identifier == 'grass')
|
||||
query = query.filter(tables.Move.power >= 100)
|
||||
query = query.order_by(tables.Move.power)
|
||||
query = query.order_by(tables.Move.name)
|
||||
|
||||
print 'The most powerful Grass-type moves:'
|
||||
for move in query:
|
||||
print u'{0.name} ({0.power})'.format(move)
|
||||
|
||||
.. testoutput::
|
||||
|
||||
The most powerful Grass-type moves:
|
||||
Petal Dance (120)
|
||||
Power Whip (120)
|
||||
Seed Flare (120)
|
||||
SolarBeam (120)
|
||||
Wood Hammer (120)
|
||||
Leaf Storm (140)
|
||||
Frenzy Plant (150)
|
||||
|
||||
That concludes our brief tutorial.
|
||||
If you need to do more, consult the `SQLAlchemy documentation`_.
|
||||
|
||||
API documentation
|
||||
-----------------
|
||||
|
||||
.. autofunction:: pokedex.db.connect
|
||||
|
||||
See :class:`sqlalchemy.orm.session.Session` for more documentation on the
|
||||
returned object.
|
||||
|
||||
.. autofunction:: pokedex.db.util.get
|
||||
|
||||
|
||||
.. _Python: http://www.python.org
|
||||
.. _SQLAlchemy: http://www.sqlalchemy.org
|
||||
.. _`SQLAlchemy documentation`: http://www.sqlalchemy.org/docs/orm/tutorial.html
|
|
@ -118,6 +118,7 @@ def create_translation_table(_table_name, foreign_class, relation_name,
|
|||
|
||||
Translations = type(_table_name, (object,), {
|
||||
'_language_identifier': association_proxy('local_language', 'identifier'),
|
||||
'relation_name': relation_name,
|
||||
})
|
||||
|
||||
# Create the table object
|
||||
|
|
|
@ -1272,6 +1272,7 @@ class PokemonForm(TableBase):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of this form: the form_name, if set; otherwise the species name"""
|
||||
return self.pokemon_name or self.species.name
|
||||
|
||||
create_translation_table('pokemon_form_names', PokemonForm, 'names',
|
||||
|
@ -1705,7 +1706,6 @@ ContestCombo.second = relationship(Move,
|
|||
innerjoin=True, lazy='joined',
|
||||
backref='contest_combo_second')
|
||||
|
||||
|
||||
Encounter.condition_value_map = relationship(EncounterConditionValueMap,
|
||||
backref='encounter')
|
||||
Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
|
||||
|
@ -1954,10 +1954,8 @@ Pokemon.all_abilities = relationship(Ability,
|
|||
secondary=PokemonAbility.__table__,
|
||||
order_by=PokemonAbility.slot.asc(),
|
||||
innerjoin=True,
|
||||
backref=backref('all_pokemon',
|
||||
order_by=Pokemon.order.asc(),
|
||||
),
|
||||
)
|
||||
backref=backref('all_pokemon', order_by=Pokemon.order.asc()),
|
||||
doc=u"All abilities the Pokémon can have, including the Hidden Ability")
|
||||
Pokemon.abilities = relationship(Ability,
|
||||
secondary=PokemonAbility.__table__,
|
||||
primaryjoin=and_(
|
||||
|
@ -1966,10 +1964,8 @@ Pokemon.abilities = relationship(Ability,
|
|||
),
|
||||
innerjoin=True,
|
||||
order_by=PokemonAbility.slot.asc(),
|
||||
backref=backref('pokemon',
|
||||
order_by=Pokemon.order.asc(),
|
||||
),
|
||||
)
|
||||
backref=backref('pokemon', order_by=Pokemon.order.asc()),
|
||||
doc=u"Abilities the Pokémon can have in the wild")
|
||||
Pokemon.dream_ability = relationship(Ability,
|
||||
secondary=PokemonAbility.__table__,
|
||||
primaryjoin=and_(
|
||||
|
@ -1977,10 +1973,8 @@ Pokemon.dream_ability = relationship(Ability,
|
|||
PokemonAbility.is_dream == True,
|
||||
),
|
||||
uselist=False,
|
||||
backref=backref('dream_pokemon',
|
||||
order_by=Pokemon.order,
|
||||
),
|
||||
)
|
||||
backref=backref('dream_pokemon', order_by=Pokemon.order),
|
||||
doc=u"The Pokémon's Hidden Ability")
|
||||
Pokemon.forms = relationship(PokemonForm,
|
||||
primaryjoin=Pokemon.id==PokemonForm.pokemon_id,
|
||||
order_by=(PokemonForm.order.asc(), PokemonForm.form_identifier.asc()),
|
||||
|
@ -1989,9 +1983,11 @@ Pokemon.default_form = relationship(PokemonForm,
|
|||
primaryjoin=and_(
|
||||
Pokemon.id==PokemonForm.pokemon_id,
|
||||
PokemonForm.is_default==True),
|
||||
uselist=False, lazy='joined')
|
||||
uselist=False, lazy='joined',
|
||||
doc=u"A representative form of this pokémon")
|
||||
Pokemon.items = relationship(PokemonItem,
|
||||
backref='pokemon')
|
||||
backref='pokemon',
|
||||
doc=u"Info about items this pokémon holds in the wild")
|
||||
Pokemon.stats = relationship(PokemonStat,
|
||||
innerjoin=True,
|
||||
order_by=PokemonStat.stat_id.asc(),
|
||||
|
@ -2077,7 +2073,9 @@ PokemonStat.stat = relationship(Stat,
|
|||
PokemonSpecies.parent_species = relationship(PokemonSpecies,
|
||||
primaryjoin=PokemonSpecies.evolves_from_species_id==PokemonSpecies.id,
|
||||
remote_side=[PokemonSpecies.id],
|
||||
backref='child_species')
|
||||
backref=backref('child_species',
|
||||
doc=u"The species to which this one evolves"),
|
||||
doc=u"The species from which this one evolves")
|
||||
PokemonSpecies.evolutions = relationship(PokemonEvolution,
|
||||
primaryjoin=PokemonSpecies.id==PokemonEvolution.evolved_species_id,
|
||||
backref=backref('evolved_species', innerjoin=True, lazy='joined'))
|
||||
|
@ -2108,7 +2106,8 @@ PokemonSpecies.default_form = relationship(PokemonForm,
|
|||
Pokemon.is_default==True),
|
||||
secondaryjoin=and_(Pokemon.id==PokemonForm.pokemon_id,
|
||||
PokemonForm.is_default==True),
|
||||
uselist=False)
|
||||
uselist=False,
|
||||
doc=u"A representative form of this species")
|
||||
PokemonSpecies.default_pokemon = relationship(Pokemon,
|
||||
primaryjoin=and_(
|
||||
PokemonSpecies.id==Pokemon.species_id,
|
||||
|
|
0
pokedex/doc/__init__.py
Normal file
0
pokedex/doc/__init__.py
Normal file
334
pokedex/doc/tabledoc.py
Normal file
334
pokedex/doc/tabledoc.py
Normal file
|
@ -0,0 +1,334 @@
|
|||
# Encoding: UTF-8
|
||||
|
||||
u"""Automatic documentation generation for pokédex tables
|
||||
|
||||
This adds a "dex-table" directive to Sphinx, which works like "autoclass",
|
||||
but documents Pokédex mapped classes.
|
||||
"""
|
||||
# XXX: This assumes all the tables are in pokedex.db.tables
|
||||
|
||||
import functools
|
||||
import textwrap
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.statemachine import ViewList
|
||||
from sphinx.util.compat import Directive, make_admonition
|
||||
from sphinx.locale import _
|
||||
from sphinx.domains.python import PyClasslike
|
||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||
from sphinx.ext.autodoc import ClassLevelDocumenter
|
||||
|
||||
from sqlalchemy import types
|
||||
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
||||
from sqlalchemy.orm.properties import RelationshipProperty
|
||||
from sqlalchemy.orm import Mapper, configure_mappers
|
||||
from sqlalchemy.ext.associationproxy import AssociationProxy
|
||||
from pokedex.db.markdown import MoveEffectPropertyMap, MoveEffectProperty
|
||||
|
||||
from pokedex.db import tables, markdown
|
||||
|
||||
# Make sure all the backrefs are in place
|
||||
configure_mappers()
|
||||
|
||||
|
||||
column_to_cls = {}
|
||||
for cls in tables.mapped_classes:
|
||||
for column in cls.__table__.c:
|
||||
column_to_cls[column] = cls
|
||||
|
||||
class dextabledoc(nodes.Admonition, nodes.Element):
|
||||
pass
|
||||
|
||||
def visit_todo_node(self, node):
|
||||
self.visit_admonition(node)
|
||||
|
||||
def depart_todo_node(self, node):
|
||||
self.depart_admonition(node)
|
||||
|
||||
def column_type_str(column):
|
||||
"""Extract the type name from a SQLA column
|
||||
"""
|
||||
type_ = column.type
|
||||
# We're checking the specific type here: no issubclass
|
||||
if type(type_) in (types.Integer, types.SmallInteger):
|
||||
return 'int'
|
||||
if type(type_) == types.Boolean:
|
||||
return 'bool'
|
||||
if type(type_) == types.Unicode:
|
||||
return u'unicode – %s' % column.info['format']
|
||||
if type(type_) == types.Enum:
|
||||
return 'enum: [%s]' % ', '.join(type_.enums)
|
||||
if type(type_) == markdown.MarkdownColumn:
|
||||
return 'markdown'
|
||||
raise ValueError(repr(type_))
|
||||
|
||||
common_columns = 'id identifier name'.split()
|
||||
|
||||
def column_header(c, class_name=None, transl_name=None, show_type=True,
|
||||
relation=None, relation_name=None):
|
||||
"""Return the column header for the given column"""
|
||||
result = []
|
||||
if relation_name:
|
||||
name = relation_name
|
||||
else:
|
||||
name = c.name
|
||||
if class_name:
|
||||
result.append(u'%s.\ **%s**' % (class_name, name))
|
||||
else:
|
||||
result.append(u'**%s**' % c.name)
|
||||
if c.foreign_keys:
|
||||
for fk in c.foreign_keys:
|
||||
if fk.column in column_to_cls:
|
||||
foreign_cls = column_to_cls[fk.column]
|
||||
if relation_name and relation_name + '_id' == c.name:
|
||||
result.append(u'(%s →' % c.name)
|
||||
elif relation_name:
|
||||
result.append(u'(**%s** →' % c.name)
|
||||
else:
|
||||
result.append(u'(→')
|
||||
result.append(u':class:`~pokedex.db.tables.%s`.%s)' % (
|
||||
foreign_cls.__name__,
|
||||
fk.column.name
|
||||
))
|
||||
break
|
||||
elif show_type:
|
||||
result.append(u'(*%s*)' % column_type_str(c))
|
||||
if transl_name:
|
||||
result.append(u'via *%s*' % transl_name)
|
||||
return ' '.join(result)
|
||||
|
||||
|
||||
def with_header(header=None):
|
||||
"""Decorator that adds a section header if there's a any output
|
||||
|
||||
The decorated function should yield output lines; if there are any the
|
||||
header gets added.
|
||||
"""
|
||||
def wrap(func):
|
||||
@functools.wraps(func)
|
||||
def wrapped(cls, remaining_attrs):
|
||||
result = list(func(cls, remaining_attrs))
|
||||
if result:
|
||||
# Sphinx/ReST doesn't allow "-----" just anywhere :(
|
||||
yield u''
|
||||
yield u'.. raw:: html'
|
||||
yield u''
|
||||
yield u' <hr>'
|
||||
yield u''
|
||||
if header:
|
||||
yield header + u':'
|
||||
yield u''
|
||||
for row in result:
|
||||
yield row
|
||||
return wrapped
|
||||
return wrap
|
||||
|
||||
### Section generation functions
|
||||
|
||||
def generate_table_header(cls, remaining_attrs):
|
||||
first_line, sep, next_lines = unicode(cls.__doc__).partition(u'\n')
|
||||
yield first_line
|
||||
for line in textwrap.dedent(next_lines).split('\n'):
|
||||
yield line
|
||||
yield ''
|
||||
|
||||
yield u'Table name: *%s*' % cls.__tablename__
|
||||
try:
|
||||
yield u'(single: *%s*)' % cls.__singlename__
|
||||
except AttributeError:
|
||||
pass
|
||||
yield u''
|
||||
|
||||
yield u'Primary key: %s.' % u', '.join(
|
||||
u'**%s**' % col.key for col in cls.__table__.primary_key.columns)
|
||||
yield u''
|
||||
|
||||
def generate_common(cls, remaining_attrs):
|
||||
common_col_headers = []
|
||||
for c in cls.__table__.c:
|
||||
if c.name in common_columns:
|
||||
common_col_headers.append(column_header(c, show_type=False))
|
||||
remaining_attrs.remove(c.name)
|
||||
for translation_class in cls.translation_classes:
|
||||
for c in translation_class.__table__.c:
|
||||
if c.name in common_columns:
|
||||
common_col_headers.append(column_header(c, None,
|
||||
translation_class.__table__.name, show_type=False))
|
||||
remaining_attrs.remove(c.name)
|
||||
|
||||
if common_col_headers:
|
||||
if len(common_col_headers) > 1:
|
||||
common_col_headers[-1] = 'and ' + common_col_headers[-1]
|
||||
if len(common_col_headers) > 2:
|
||||
separator = u', '
|
||||
else:
|
||||
separator = u' '
|
||||
yield u'Has'
|
||||
yield separator.join(common_col_headers) + '.'
|
||||
yield u''
|
||||
|
||||
@with_header(u'Columns')
|
||||
def generate_columns(cls, remaining_attrs):
|
||||
name = cls.__name__
|
||||
for c in [c for c in cls.__table__.c if c.name not in common_columns]:
|
||||
remaining_attrs.remove(c.name)
|
||||
relation_name = c.name[:-3]
|
||||
if c.name.endswith('_id') and relation_name in remaining_attrs:
|
||||
relation = getattr(cls, relation_name)
|
||||
yield column_header(c, name,
|
||||
relation=relation, relation_name=relation_name)
|
||||
remaining_attrs.remove(relation_name)
|
||||
else:
|
||||
yield column_header(c, name) + ':'
|
||||
yield u''
|
||||
yield u' ' + unicode(c.info['description'])
|
||||
yield u''
|
||||
|
||||
@with_header(u'Internationalized strings')
|
||||
def generate_strings(cls, remaining_attrs):
|
||||
for translation_class in cls.translation_classes:
|
||||
for c in translation_class.__table__.c:
|
||||
if 'format' in c.info:
|
||||
remaining_attrs.discard(c.name)
|
||||
remaining_attrs.discard(c.name + '_map')
|
||||
if c.name in common_columns:
|
||||
continue
|
||||
yield column_header(c, cls.__name__,
|
||||
translation_class.__table__.name)
|
||||
yield u''
|
||||
yield u' ' + unicode(c.info['description'])
|
||||
yield u''
|
||||
|
||||
@with_header(u'Relationships')
|
||||
def generate_relationships(cls, remaining_attrs):
|
||||
def isrelationship(prop):
|
||||
return isinstance(prop, InstrumentedAttribute) and isinstance(prop.property, RelationshipProperty)
|
||||
|
||||
for attr_name in sorted(remaining_attrs):
|
||||
prop = getattr(cls, attr_name)
|
||||
if not isrelationship(prop):
|
||||
continue
|
||||
rel = prop.property
|
||||
yield u'%s.\ **%s**' % (cls.__name__, attr_name)
|
||||
class_name = u':class:`~pokedex.db.tables.%s`' % rel.mapper.class_.__name__
|
||||
if rel.uselist:
|
||||
class_name = u'[%s]' % class_name
|
||||
yield u'(→ %s)' % class_name
|
||||
if rel.doc:
|
||||
yield u''
|
||||
yield u' ' + unicode(rel.doc)
|
||||
if rel.secondary is not None:
|
||||
yield u''
|
||||
yield ' Association table: ``%s``' % rel.secondary
|
||||
#if rel.primaryjoin is not None:
|
||||
# yield u''
|
||||
# yield ' Join condition: ``%s``' % rel.primaryjoin
|
||||
# if rel.secondaryjoin is not None:
|
||||
# yield ' , ``%s``' % rel.secondaryjoin
|
||||
if rel.order_by:
|
||||
yield u''
|
||||
yield u' '
|
||||
yield ' Ordered by: ' + u', '.join(
|
||||
u'``%s``' % o for o in rel.order_by)
|
||||
yield u''
|
||||
remaining_attrs.remove(attr_name)
|
||||
|
||||
@with_header(u'Association Proxies')
|
||||
def generate_associationproxies(cls, remaining_attrs):
|
||||
for attr_name in sorted(remaining_attrs):
|
||||
prop = getattr(cls, attr_name)
|
||||
if isinstance(prop, AssociationProxy):
|
||||
yield u'%s.\ **%s**:' % (cls.__name__, attr_name)
|
||||
yield '``{prop.remote_attr.key}`` of ``self.{prop.local_attr.key}``'.format(
|
||||
prop=prop)
|
||||
'''if 'description' in info:
|
||||
yield u''
|
||||
yield u' ' + unicode(info['description'])'''
|
||||
yield u''
|
||||
remaining_attrs.remove(attr_name)
|
||||
|
||||
|
||||
@with_header(u'Undocumented')
|
||||
def generate_undocumented(cls, remaining_attrs):
|
||||
for c in sorted([c for c in remaining_attrs if isinstance(getattr(cls, c),
|
||||
(InstrumentedAttribute, AssociationProxy,
|
||||
MoveEffectPropertyMap, MoveEffectProperty))]):
|
||||
yield u''
|
||||
yield u'%s.\ **%s**' % (cls.__name__, c)
|
||||
remaining_attrs.remove(c)
|
||||
|
||||
@with_header(None)
|
||||
def generate_other(cls, remaining_attrs):
|
||||
for c in sorted(remaining_attrs):
|
||||
yield u''
|
||||
member = getattr(cls, c)
|
||||
if callable(member):
|
||||
yield '.. automethod:: %s.%s' % (cls.__name__, c)
|
||||
else:
|
||||
yield '.. autoattribute:: %s.%s' % (cls.__name__, c)
|
||||
yield u''
|
||||
remaining_attrs.clear()
|
||||
|
||||
|
||||
class DexTable(PyClasslike):
|
||||
"""The actual Sphinx documentation generation whatchamacallit
|
||||
"""
|
||||
doc_field_types = [
|
||||
TypedField('field', label='Fields',
|
||||
typerolename='obj', typenames=('fieldname', 'type')),
|
||||
]
|
||||
|
||||
def get_signature_prefix(self, sig):
|
||||
return ''
|
||||
#return u'mapped class '
|
||||
|
||||
def run(self):
|
||||
section = nodes.section()
|
||||
super_result = super(DexTable, self).run()
|
||||
title_text = self.names[0][0]
|
||||
section += nodes.title(text=title_text)
|
||||
section += super_result
|
||||
section['ids'] = ['dex-table-%s' % title_text.lower()]
|
||||
return [section]
|
||||
|
||||
def before_content(self):
|
||||
name = self.names[0][0]
|
||||
for cls in tables.mapped_classes:
|
||||
if name == cls.__name__:
|
||||
break
|
||||
else:
|
||||
raise ValueError('Table %s not found' % name)
|
||||
table = cls.__table__
|
||||
|
||||
remaining_attrs = set(x for x in dir(cls) if not x.startswith('_'))
|
||||
remaining_attrs.difference_update(['metadata', 'translation_classes',
|
||||
'add_relationships', 'summary_column'])
|
||||
for transl_class in cls.translation_classes:
|
||||
remaining_attrs.difference_update([
|
||||
transl_class.relation_name,
|
||||
transl_class.relation_name + '_table',
|
||||
transl_class.relation_name + '_local',
|
||||
])
|
||||
|
||||
generated_content = [] # Just a list of lines!
|
||||
|
||||
generated_content.extend(generate_table_header(cls, remaining_attrs))
|
||||
generated_content.extend(generate_common(cls, remaining_attrs))
|
||||
generated_content.extend(generate_columns(cls, remaining_attrs))
|
||||
generated_content.extend(generate_strings(cls, remaining_attrs))
|
||||
generated_content.extend(generate_relationships(cls, remaining_attrs))
|
||||
generated_content.extend(generate_associationproxies(cls, remaining_attrs))
|
||||
generated_content.extend(generate_undocumented(cls, remaining_attrs))
|
||||
generated_content.extend(generate_other(cls, remaining_attrs))
|
||||
|
||||
generated_content.append(u'')
|
||||
self.content = ViewList(generated_content + list(self.content))
|
||||
return super(DexTable, self).before_content()
|
||||
|
||||
def get_index_text(self, modname, name_cls):
|
||||
return '%s (mapped class)' % name_cls[0]
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('dex-table', DexTable)
|
||||
|
||||
# XXX: Specify that this depends on pokedex.db.tables ...?
|
2
setup.py
2
setup.py
|
@ -8,7 +8,7 @@ setup(
|
|||
'pokedex': ['data/csv/*.csv']
|
||||
},
|
||||
install_requires=[
|
||||
'SQLAlchemy>=0.7',
|
||||
'SQLAlchemy>=0.7.3',
|
||||
'whoosh>=2.2.2',
|
||||
'markdown',
|
||||
'construct',
|
||||
|
|
Loading…
Reference in a new issue