<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# complexity documentation build configuration file, created by
# sphinx-quickstart on Tue Jul  9 22:26:36 2013.
#
# 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 os
import sys

# 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('.'))

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
project_root = os.path.dirname(cwd)

# Insert the project root dir as the first element in the PYTHONPATH.
# This lets us ensure that the source package is imported, and that its
# version is used.
sys.path.insert(0, project_root)

# add the _ext/ dir for local extensions
sys.path.insert(1, os.path.abspath('_ext'))

# configure paths and names once
project_name = "dotfiles"
project_name_slug = "dotfiles"
project_orgname = "westurner"
project_twitter_user = project_orgname
project_author = u"Wes Turner"
project_copyright = u'2014, {}'.format(project_author)
project_github_path = "{}/{}".format(project_orgname, project_name)
project_github_url = "https://github.com/{}".format(project_github_path)
project_src_url = project_github_url
project_src_path = project_github_path
project_url = project_github_url
project_title = u'{} Documentation'.format(project_name)
project_description_oneline = (
    u'Documentation for the {} project'.format(project_name))
project_og_site_name = project_src_path  # e.g. westurner/dotfiles

srclink_project = project_github_url  # project_github_path
srclink_src_path = 'docs/'
srclink_branch = 'master'

# current_git_branch=subprocess.check_output("git b") && parse

import dotfiles

# -- 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.viewcode',
    'sphinxcontrib.napoleon',
    'sphinxcontrib.srclinks'
]

try:
    import sphinxcontrib.programoutput
    extensions.append('sphinxcontrib.ansi')
    extensions.append('sphinxcontrib.programoutput')
    programoutput_use_ansi = True
except ImportError:
    pass

try:
    import sphinx_git
    extensions.append('sphinx_git')
except ImportError:
    pass
    # TODO

try:
    import sphinxcontrib.issuetracker
    extensions.append('sphinxcontrib.issuetracker')
    issuetracker = 'github'
    issuetracker_project = project_github_path
except ImportError:
    pass
    # TODO

try:
    import changelog
    extensions.append('changelog')
    # section names - optional
    changelog_sections = ["general", "rendering", "tests"]

    # tags to sort on inside of sections - also optional
    changelog_inner_tag_sort = ["feature", "bug"]

    changelog_url = project_github_url

    # how to render changelog links - these are plain
    # python string templates, ticket/pullreq/changeset number goes
    # in "%s"
    changelog_render_ticket = "%s/issue/%%s" % changelog_url
    changelog_render_pullreq = "%s/pullrequest/%%s" % changelog_url
    changelog_render_changeset = "%s/changeset/%%s" % changelog_url
except ImportError:
    #print("ERROR: failed to import 'changelog'")
    pass

autodoc_member_order = 'bysource'

# 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-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = project_src_path
copyright = project_copyright

# 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 = dotfiles.__version__
# The full version, including alpha/beta/rc tags.
release = dotfiles.__version__

# 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', 'tools/**']

# 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 = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# -- Options for HTML output ---------------------------------------------

# see: http://git.io/Pk7SGA
# on_rtd is whether we are on readthedocs.org, this line of code grabbed
# from docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'

if False:  # only import and set the theme if we're building docs locally
    import sphinx_rtd_theme
    # The theme to use for HTML and HTML Help pages.  See the documentation for
    # a list of builtin themes.
    html_theme = 'sphinx_rtd_theme'
    # Add any paths that contain custom themes here, relative to this
    # directory.
    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'basicstrap'

# 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 = {
    'lang': 'en',
    'nosidebar': False,
    'rightsidebar': True,
    'sidebar_span': 5,
    'nav_fixed_top': False,
    'nav_fixed': False,
    'nav_width': '900px',
    'content_fixed': False,
    'content_width': '768px',
    'row_fixed': False,
    'noresponsive': False,
    'noresponsiverelbar': True,
    'googlewebfont': False,
    'googlewebfont_url': 'http://fonts.googleapis.com/css?family=Lily+Script+One',
    'googlewebfont_style': u"font-family: 'Lily Script One' cursive;",
    'header_inverse': False,
    'relbar_inverse': False,
    'inner_theme': False,
    'inner_theme_name': 'bootswatch-readable',
#    'h1_size': '3.0em',
#    'h2_size': '2.6em',
#    'h3_size': '2.2em',
#    'h4_size': '1.8em',
#    'h5_size': '1.4em',
#    'h6_size': '1.1em',
}

# 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 = {
    '**': [
        'localtoc.html',
        'relations.html',
        'searchbox.html',
        'srclinks.html',
        'links.html',
        ],
    'index': [
        'globaltoc.html',
        'relations.html',
        'searchbox.html',
        'srclinks.html',
        'links.html',
        ],
}

# 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 = True

# 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

# Filename affix
filename_affix = "{}".format(project_name_slug)

# Output file base name for HTML help builder.
htmlhelp_basename = '{}-doc'.format(filename_affix)

# -- Options for LaTeX output --------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
    ('index',
     '{}.tex'.format(filename_affix),
     project_title,
     project_author,
     '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

# 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',
     project_name_slug,
     project_title,
     [project_author],
     1)
]

# If true, show URL addresses after external links.
#man_show_urls = False

# -- Options for Texinfo output ------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    ('index',
     project_name_slug,
     project_title,
     project_author,
     project_name,
     project_description_oneline,
     'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False

def configure_meta_tags(app, pagename, templatename, context, doctree):
    metatags = context.get('metatags', '')
    metatags += """
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- OpenGraph metadata: ogp.me -->
    <meta property="og:title" content="{title}" />
    <meta property="og:type" content="website" />
    <meta property="og:site_name" content="{og_site_name}" />
    <!--
    <meta property="og:description" content="{description}" />
    -->
    <meta property="og:image" content="{og_image_url}" />
    <meta property="og:image:width" content="{og_image_width}" />
    <meta property="og:image:height" content="{og_image_height}" />
    <!--
    <meta property="og:image:secure_url" content="./_static/img/logo.png" />
    -->
    <!-- Twitter metadata -->
    <meta property="twitter:card" content="summary" />
    <meta property="twitter:title" content="{title}" />
    <meta property="twitter:description" content="{description}" />
    <meta property="twitter:site" content="{twitter_user}" />
    <meta property="twitter:creator" content="{twitter_user}" />
    """.format(
        title=context.get('title',''),
        description=context.get('description', project_description_oneline),
        og_site_name=project_og_site_name,
        og_image_url="",  # 470x242.png
        og_image_width="470",
        og_image_height="242",
        twitter_user=project_twitter_user)
    context['metatags'] = metatags

def setup(app):
    app.add_javascript('js/local.js')
    app.add_stylesheet('css/local.css')
    app.connect('html-page-context', configure_meta_tags)

if __name__ == "__main__":
    context = {}
    output = configure_meta_tags(None, None, None, context, None)
    print(context.get('metatags'))
<commit_msg>CLN: docs/conf.py: exclude_patterns += ['tools/**']<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# complexity documentation build configuration file, created by
# sphinx-quickstart on Tue Jul  9 22:26:36 2013.
#
# 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 os
import sys

# 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('.'))

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
project_root = os.path.dirname(cwd)

# Insert the project root dir as the first element in the PYTHONPATH.
# This lets us ensure that the source package is imported, and that its
# version is used.
sys.path.insert(0, project_root)

# add the _ext/ dir for local extensions
sys.path.insert(1, os.path.abspath('_ext'))

# configure paths and names once
project_name = "dotfiles"
project_name_slug = "dotfiles"
project_orgname = "westurner"
project_twitter_user = project_orgname
project_author = u"Wes Turner"
project_copyright = u'2014, {}'.format(project_author)
project_github_path = "{}/{}".format(project_orgname, project_name)
project_github_url = "https://github.com/{}".format(project_github_path)
project_src_url = project_github_url
project_src_path = project_github_path
project_url = project_github_url
project_title = u'{} Documentation'.format(project_name)
project_description_oneline = (
    u'Documentation for the {} project'.format(project_name))
project_og_site_name = project_src_path  # e.g. westurner/dotfiles

srclink_project = project_github_url  # project_github_path
srclink_src_path = 'docs/'
srclink_branch = 'master'

# current_git_branch=subprocess.check_output("git b") && parse

import dotfiles

# -- 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.viewcode',
    'sphinxcontrib.napoleon',
    'sphinxcontrib.srclinks'
]

try:
    import sphinxcontrib.programoutput
    extensions.append('sphinxcontrib.ansi')
    extensions.append('sphinxcontrib.programoutput')
    programoutput_use_ansi = True
except ImportError:
    pass

try:
    import sphinx_git
    extensions.append('sphinx_git')
except ImportError:
    pass
    # TODO

try:
    import sphinxcontrib.issuetracker
    extensions.append('sphinxcontrib.issuetracker')
    issuetracker = 'github'
    issuetracker_project = project_github_path
except ImportError:
    pass
    # TODO

try:
    import changelog
    extensions.append('changelog')
    # section names - optional
    changelog_sections = ["general", "rendering", "tests"]

    # tags to sort on inside of sections - also optional
    changelog_inner_tag_sort = ["feature", "bug"]

    changelog_url = project_github_url

    # how to render changelog links - these are plain
    # python string templates, ticket/pullreq/changeset number goes
    # in "%s"
    changelog_render_ticket = "%s/issue/%%s" % changelog_url
    changelog_render_pullreq = "%s/pullrequest/%%s" % changelog_url
    changelog_render_changeset = "%s/changeset/%%s" % changelog_url
except ImportError:
    #print("ERROR: failed to import 'changelog'")
    pass

autodoc_member_order = 'bysource'

# 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-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = project_src_path
copyright = project_copyright

# 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 = dotfiles.__version__
# The full version, including alpha/beta/rc tags.
release = dotfiles.__version__

# 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', 'tools/']

# 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 = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# -- Options for HTML output ---------------------------------------------

# see: http://git.io/Pk7SGA
# on_rtd is whether we are on readthedocs.org, this line of code grabbed
# from docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'

if False:  # only import and set the theme if we're building docs locally
    import sphinx_rtd_theme
    # The theme to use for HTML and HTML Help pages.  See the documentation for
    # a list of builtin themes.
    html_theme = 'sphinx_rtd_theme'
    # Add any paths that contain custom themes here, relative to this
    # directory.
    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'basicstrap'

# 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 = {
    'lang': 'en',
    'nosidebar': False,
    'rightsidebar': True,
    'sidebar_span': 5,
    'nav_fixed_top': False,
    'nav_fixed': False,
    'nav_width': '900px',
    'content_fixed': False,
    'content_width': '768px',
    'row_fixed': False,
    'noresponsive': False,
    'noresponsiverelbar': True,
    'googlewebfont': False,
    'googlewebfont_url': 'http://fonts.googleapis.com/css?family=Lily+Script+One',
    'googlewebfont_style': u"font-family: 'Lily Script One' cursive;",
    'header_inverse': False,
    'relbar_inverse': False,
    'inner_theme': False,
    'inner_theme_name': 'bootswatch-readable',
#    'h1_size': '3.0em',
#    'h2_size': '2.6em',
#    'h3_size': '2.2em',
#    'h4_size': '1.8em',
#    'h5_size': '1.4em',
#    'h6_size': '1.1em',
}

# 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 = {
    '**': [
        'localtoc.html',
        'relations.html',
        'searchbox.html',
        'srclinks.html',
        'links.html',
        ],
    'index': [
        'globaltoc.html',
        'relations.html',
        'searchbox.html',
        'srclinks.html',
        'links.html',
        ],
}

# 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 = True

# 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

# Filename affix
filename_affix = "{}".format(project_name_slug)

# Output file base name for HTML help builder.
htmlhelp_basename = '{}-doc'.format(filename_affix)

# -- Options for LaTeX output --------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
    ('index',
     '{}.tex'.format(filename_affix),
     project_title,
     project_author,
     '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

# 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',
     project_name_slug,
     project_title,
     [project_author],
     1)
]

# If true, show URL addresses after external links.
#man_show_urls = False

# -- Options for Texinfo output ------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    ('index',
     project_name_slug,
     project_title,
     project_author,
     project_name,
     project_description_oneline,
     'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False

def configure_meta_tags(app, pagename, templatename, context, doctree):
    metatags = context.get('metatags', '')
    metatags += """
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- OpenGraph metadata: ogp.me -->
    <meta property="og:title" content="{title}" />
    <meta property="og:type" content="website" />
    <meta property="og:site_name" content="{og_site_name}" />
    <!--
    <meta property="og:description" content="{description}" />
    -->
    <meta property="og:image" content="{og_image_url}" />
    <meta property="og:image:width" content="{og_image_width}" />
    <meta property="og:image:height" content="{og_image_height}" />
    <!--
    <meta property="og:image:secure_url" content="./_static/img/logo.png" />
    -->
    <!-- Twitter metadata -->
    <meta property="twitter:card" content="summary" />
    <meta property="twitter:title" content="{title}" />
    <meta property="twitter:description" content="{description}" />
    <meta property="twitter:site" content="{twitter_user}" />
    <meta property="twitter:creator" content="{twitter_user}" />
    """.format(
        title=context.get('title',''),
        description=context.get('description', project_description_oneline),
        og_site_name=project_og_site_name,
        og_image_url="",  # 470x242.png
        og_image_width="470",
        og_image_height="242",
        twitter_user=project_twitter_user)
    context['metatags'] = metatags

def setup(app):
    app.add_javascript('js/local.js')
    app.add_stylesheet('css/local.css')
    app.connect('html-page-context', configure_meta_tags)

if __name__ == "__main__":
    context = {}
    output = configure_meta_tags(None, None, None, context, None)
    print(context.get('metatags'))
<|endoftext|>


<commit_before><commit_msg>view QtdEmLote não aceita informar quantidade maior que o tamanho do lote<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# complexity documentation build configuration file, created by
# sphinx-quickstart on Tue Jul  9 22:26:36 2013.
#
# 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

# 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('.'))

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
project_root = os.path.dirname(cwd)

# Insert the project root dir as the first element in the PYTHONPATH.
# This lets us ensure that the source package is imported, and that its
# version is used.
sys.path.insert(0, project_root)

# -- 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.viewcode']

# 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-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'DataSounds'
copyright = u'2013, DataSounds'

# 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 = imSound.__version__
version = '1.2.0'
# The full version, including alpha/beta/rc tags.
#release = imSound.__version__
release = '1.2.0'

# 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 = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# -- 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 = True

# 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 = 'DataSoundsdoc'

# -- Options for LaTeX output --------------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('index', 'DataSounds.tex', u'DataSounds Documentation',
   u'DataSounds', '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

# 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', 'DataSounds', u'DataSounds Documentation',
     [u'DataSounds'], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False

# -- Options for Texinfo output ------------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
  ('index', 'DataSounds', u'DataSounds Documentation',
   u'DataSounds', 'Get sounds from temporal series, or another sequecial data.'
   ),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
<commit_msg>docs header logo<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# complexity documentation build configuration file, created by
# sphinx-quickstart on Tue Jul  9 22:26:36 2013.
#
# 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

# 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('.'))

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
project_root = os.path.dirname(cwd)

# Insert the project root dir as the first element in the PYTHONPATH.
# This lets us ensure that the source package is imported, and that its
# version is used.
sys.path.insert(0, project_root)

# -- 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.viewcode']

# 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-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'DataSounds'
copyright = u'2013, DataSounds'

# 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 = imSound.__version__
version = '1.2.0'
# The full version, including alpha/beta/rc tags.
#release = imSound.__version__
release = '1.2.0'

# 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 = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# -- 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
html_logo = ['https://avatars1.githubusercontent.com/u/4330863?v=3&s=200']

# 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 = True

# 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 = 'DataSoundsdoc'

# -- Options for LaTeX output --------------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('index', 'DataSounds.tex', u'DataSounds Documentation',
   u'DataSounds', '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

# 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', 'DataSounds', u'DataSounds Documentation',
     [u'DataSounds'], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False

# -- Options for Texinfo output ------------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
  ('index', 'DataSounds', u'DataSounds Documentation',
   u'DataSounds', 'Get sounds from temporal series, or another sequecial data.'
   ),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
<|endoftext|>


<commit_before>#!/usr/bin/python

# author: greyshell

"""
[+] problem description
=======================

[+] reference
=============
http://interactivepython.org/runestone/static/pythonds/Recursion/TowerofHanoi.html

"""

class Solution(object):

    def toh(self, n, x, y, z):
        """
        description: time complexity: O(2^n), space complexity:
        :param n:
        :param x:
        :param y:
        :param z:
        :return:
        """
        if n >= 1:
            self.toh(n-1, x, z, y)
            print "[+] move disk from %s to %s" % (x, y)
            self.toh(n - 1, z, y, x)

        return

def main():
    s = Solution()
    # s.toh(3, 'x', 'y', 'z')
    s.toh(5, 'x', 'y', 'z')

if __name__ == '__main__':
    main()
<commit_msg>improving the nos of function invocation<commit_after>#!/usr/bin/python

# author: greyshell

"""
[+] problem description
=======================

[+] reference
=============
http://interactivepython.org/runestone/static/pythonds/Recursion/TowerofHanoi.html

"""

class Solution(object):

    def toh(self, n, x, y, z):
        """
        tower of hanoi
        time complexity: O(2^(n+1) -1 ) ~ O(2^n)
        space complexity: O(n-1)
        nos of recursive function invocation: 2^n - 1,  considering the base case => I(n) = 1 where n = 1
        nos of movement being done: 2^n -1, considering the base case => M(n) = 0 where n = 0

        :param n: int
        :param x: char
        :param y: char
        :param z: char
        :return: void / none
        """
        if n == 1:  # improve the nos of function invocation
            print "[+] move disk from %s to %s" % (x, y)
        elif n > 1:
            self.toh(n-1, x, z, y)
            print "[+] move disk from %s to %s" % (x, y)
            self.toh(n - 1, z, y, x)

        return

def main():
    s = Solution()
    s.toh(3, 'x', 'y', 'z')
    # s.toh(5, 'x', 'y', 'z')

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# 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.
#
import os
import sys
from datetime import date
from pkg_resources import get_distribution

import orcanet
#sys.path.insert(0, os.path.abspath('.'))

# -- Project information -----------------------------------------------------

project = 'OrcaNet'
copyright = u'{0}, Michael Moser and Stefan Reck'.format(date.today().year)
author = 'Michael Moser and Stefan Reck'

# The full version, including alpha/beta/rc tags
release = get_distribution('orcanet').version
# The short X.Y version
version = '.'.join(release.split('.')[:2])

# -- 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.todo',
    'sphinx.ext.mathjax',
    'sphinx.ext.viewcode',
    'sphinx.ext.autosummary',
    'autoapi.extension',
    'numpydoc',
]

autosummary_generate = True

# Document Python Code
autoapi_type = 'python'
autoapi_dirs = ['../orcanet']
autoapi_options = [
    'members', 'undoc-members'
    # , 'private-members', 'special-members'
]
autoapi_ignore = [
    "*/tests/*", "*test_*.py", "*/docs/conf.py", "*/pydataskel*", "*/style/*"
]
autoapi_include_summaries = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
#source_parsers = {
#   '.md': 'recommonmark.parser.CommonMarkParser',}
#source_suffix = ['.rst', '.md']
source_suffix = ['.rst']

# The master toctree document.
master_doc = 'index'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 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 = 'sphinx_rtd_theme'

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_theme_options = {
    'logo_only': True,
}
html_logo = "_static/orcanet_wide_transparent_white.png"

# 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 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']

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself.  Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}

# -- Options for HTMLHelp output ---------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'OrcaNetdoc'

# -- Options for LaTeX output ------------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'OrcaNet.tex', 'OrcaNet Documentation',
     'Michael Moser', 'manual'),
]

# -- Options for manual page output ------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'orcanet', 'OrcaNet Documentation',
     [author], 1)
]

# -- Options for Texinfo output ----------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'OrcaNet', 'OrcaNet Documentation',
     author, 'OrcaNet', 'One line description of project.',
     'Miscellaneous'),
]

# -- Options for Epub output -------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']

# -- Extension configuration -------------------------------------------------

# -- Options for todo extension ----------------------------------------------

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
def setup(app):
    app.add_stylesheet('_static/style.css')<commit_msg>Add orcanet_contrib to AutoAPI docs.<commit_after># -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# 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.
#
import os
import sys
from datetime import date
from pkg_resources import get_distribution

import orcanet
#sys.path.insert(0, os.path.abspath('.'))

# -- Project information -----------------------------------------------------

project = 'OrcaNet'
copyright = u'{0}, Michael Moser and Stefan Reck'.format(date.today().year)
author = 'Michael Moser and Stefan Reck'

# The full version, including alpha/beta/rc tags
release = get_distribution('orcanet').version
# The short X.Y version
version = '.'.join(release.split('.')[:2])

# -- 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.todo',
    'sphinx.ext.mathjax',
    'sphinx.ext.viewcode',
    'sphinx.ext.autosummary',
    'autoapi.extension',
    'numpydoc',
]

autosummary_generate = True

# Document Python Code
autoapi_type = 'python'
autoapi_dirs = ['../orcanet', '../orcanet_contrib']
autoapi_options = [
    'members', 'undoc-members'
    # , 'private-members', 'special-members'
]
autoapi_ignore = [
    "*/tests/*", "*test_*.py", "*/docs/conf.py", "*/pydataskel*", "*/style/*"
]
autoapi_include_summaries = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
#source_parsers = {
#   '.md': 'recommonmark.parser.CommonMarkParser',}
#source_suffix = ['.rst', '.md']
source_suffix = ['.rst']

# The master toctree document.
master_doc = 'index'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 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 = 'sphinx_rtd_theme'

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_theme_options = {
    'logo_only': True,
}
html_logo = "_static/orcanet_wide_transparent_white.png"

# 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 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']

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself.  Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}

# -- Options for HTMLHelp output ---------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'OrcaNetdoc'

# -- Options for LaTeX output ------------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'OrcaNet.tex', 'OrcaNet Documentation',
     'Michael Moser', 'manual'),
]

# -- Options for manual page output ------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'orcanet', 'OrcaNet Documentation',
     [author], 1)
]

# -- Options for Texinfo output ----------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'OrcaNet', 'OrcaNet Documentation',
     author, 'OrcaNet', 'One line description of project.',
     'Miscellaneous'),
]

# -- Options for Epub output -------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']

# -- Extension configuration -------------------------------------------------

# -- Options for todo extension ----------------------------------------------

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
def setup(app):
    app.add_stylesheet('_static/style.css')<|endoftext|>


<commit_before>import Tkinter as Tk
from Tkinter import *

class Rotor(object):
    """Basic Rotor class for Enigma Machine."""

    def __init__(self, data):
        self.data = data
        self.POSITION = 0   #Current position on Rotor
        self.current = None

    @property
    def current(self):
        return self._current

    @current.setter
    def current(self, current):
        self._current = self.data[self.POSITION]

    @property
    def POSITION(self):
        return self._POSITION

    @POSITION.setter
    def POSITION(self, POSITION):
        if POSITION >= len(self.data):
            POSITION = POSITION % len(self.data)
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]
        elif POSITION < 0:
            POSITION = len(self.data)-1
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]

        else:
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]

    def rotate(self):
        if len(self.data) != None:
            self.POSITION += 1
        else:
            print "There is no Rotor object to rotate."

#---------------------------------------------------------------------------------------------

class Core(object):

    def __init__(self, first, second, third):
        self.r1 = first
        self.r2 = second
        self.r3 = third

    def config(self, first, second, third, p1, p2, p3):
        #Sets the current rotor configuration and positions of each respective Rotor.

        self.r1 = first
        self.r2 = second
        self.r3 = third

        self.r1.POSITION = p1
        self.r2.POSITION = p2
        self.r3.POSITION = p3

    def encrypt(self, plain):
        #TODO: determine why some symbols appear in cipher
        cipher = list(plain)

        for i in range(len(cipher)):
            cipher[i] = ord(cipher[i])

            if cipher[i] is 32:
                cipher[i] = chr(cipher[i])
                self.iterate()

            elif cipher[i] > 64 and cipher[i] < 91:
                temp = (cipher[i] + ord(self.r1.current) + ord(self.r2.current) + ord(self.r3.current)) % 65
                temp += 65
                if temp >= 91:
                    temp -= 90
                    temp += 64
                    cipher[i] = chr(temp)
                else:
                    cipher[i] = chr(temp)

                self.iterate()

            elif cipher[i] > 96 and cipher[i] < 123:
                cipher[i] -= 32 #Changes lowercase to uppercase to keep with Enigma-style output.
                temp = (cipher[i] + ord(self.r1.current) + ord(self.r2.current) + ord(self.r3.current)) % 65
                temp += 65
                if temp >= 91:
                    temp -= 90
                    temp += 64
                    cipher[i] = chr(temp)
                else:
                    cipher[i] = chr(temp)

                self.iterate()

            else:
                cipher[i] = chr(cipher[i])
                self.iterate()

        output = ''.join(cipher)
        return output

    def decrypt(self, cipher):
        plain = list(cipher)

        for i in range(len(plain)):
            plain[i] = ord(plain[i])

            if plain[i] is 32:
                plain[i] = chr(plain[i])
                self.iterate()

            elif plain[i] > 64 and plain[i] < 91:
                temp = (plain[i] - ord(self.r1.current) - ord(self.r2.current) - ord(self.r3.current)) % 26
                temp += 65
                if temp <= 64:
                    temp += 26
                    plain[i] = chr(temp)
                else:
                    plain[i] = chr(temp)

                self.iterate()
            elif plain[i] > 96 and plain[i] < 123:
                plain[i] -= 32 #Changes lowercase input to uppercase to keep with Enigma-style output.
                temp = (plain[i] - ord(self.r1.current) - ord(self.r2.current) - ord(self.r3.current)) % 26
                temp += 65
                if temp <= 64:
                    temp += 26
                    plain[i] = chr(temp)
                else:
                    plain[i] = chr(temp)
                self.iterate()

            else:
                plain[i] = chr(plain[i])
                self.iterate()

        output= ''.join(plain)
        return output

    def iterate(self):
        self.r3.rotate()
        if self.r3.POSITION == 0:
            self.r2.rotate()
            if self.r2.POSITION == 0:
                self.r1.rotate()

#-------------------------------------------------------------------------------------------

"""
This is the letter arrangement from the 1930 Enigma I.

"""

class Machine:

#TODO: Step 1: Welcomes, prompts to begin or quit.
#Step 2: Ask for Rotor configuration (I-II-III, I-III-II, II-I-III, II-III-I, III-I-II, or III-II-I).
#Step 3: Ask for position for each rotor (0-25).
#Step 4: Ask whether the user wishes to encrypt or decrypt.
#Step 5: Ask the user to input the plaintext/ciphertext.
#TODO: Step 6: Returns the appropriate text.
#TODO: Step 7: Prompts to continue the program with the rotor settings, different settings, or to quit.

    def __init__(self, master):
        self.master = master
        self.core = None
        self.R1 = Rotor(['E', 'K', 'M', 'F', 'L', 'G', 'D', 'Q', 'V', 'Z', 'N', 'T', 'O', 'W', 'Y', 'H', 'X', 'U', 'S', 'P', 'A', 'I', 'B', 'R', 'C', 'J'])
        self.R2 = Rotor(['A', 'J', 'D', 'K', 'S', 'I', 'R', 'U', 'X', 'B', 'L', 'H', 'W', 'T', 'M', 'C', 'Q', 'G', 'Z', 'N', 'P', 'Y', 'F', 'V', 'O', 'E'])
        self.R3 = Rotor(['B', 'D', 'F', 'H', 'J', 'L', 'C', 'P', 'R', 'T', 'X', 'V', 'Z', 'N', 'Y', 'E', 'I', 'W', 'G', 'A', 'K', 'M', 'U', 'S', 'Q', 'O'])

        frame = Frame(master)
        frame.pack()

        q1 = Label(master, text = 'Which rotor configuration are you using?')
        q1.pack()
        listbox = Listbox(master, selectmode = SINGLE)
        listbox.pack()

        for item in ['I-II-III', 'I-III-II', 'II-I-III', 'II-III-I', 'III-I-II', 'III-II-I']:
            listbox.insert(END, item)

        listbox.bind('<<ListboxSelect>>', self.onConfigClick)

        q2 = Label(text = 'Which position will each rotor be set to?')
        q2.pack()
        lb1 = Listbox(selectmode = SINGLE)
        lb2 = Listbox(selectmode = SINGLE)
        lb3 = Listbox(selectmode = SINGLE)
        lb1.pack()
        lb2.pack()
        lb3.pack()

        for item in ['0','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']:
            lb1.insert(END, item)
            lb2.insert(END, item)
            lb3.insert(END, item)

        lb1.bind('<<ListboxSelect>>', self.onP1Click)
        lb2.bind('<<ListboxSelect>>', self.onP2Click)
        lb3.bind('<<ListboxSelect>>', self.onP3Click)

        confirm = Button(text = 'Confirm', command = self.messageInput)
        confirm.pack()

    def messageInput(self):
        #TODO: Kill previous frame, reveal only entry box.
        greeting = Label(text = 'Would you like to encrypt or decrypt this message?')
        greeting.pack(side = TOP)

        e = Entry()
        e.pack()

        #TODO: Create a frame for the (en/de)crypt buttons
        encryptButton = Button(text = 'Encrypt', fg = 'black', command = lambda: self.enBut(e.get()))
        encryptButton.pack()
        decryptButton = Button(text = 'Decrypt', fg = 'black', command = lambda: self.deBut(e.get()))
        decryptButton.pack()

    def enBut(self, plain):
        cipher = self.core.encrypt(plain)
        print cipher
        output = Label(text = cipher)
        output.pack()

    def deBut(self, cipher):
        plain = self.core.decrypt(cipher)
        print plain
        output = Label(text = plain)
        output.pack()

    def onConfigClick(self, evt):
        #Initializes the Core and Rotor configuration on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value

        rotorCon = {
            0: Core(self.R1, self.R2, self.R3),
            1: Core(self.R1, self.R3, self.R2),
            2: Core(self.R2, self.R1, self.R3),
            3: Core(self.R2, self.R3, self.R1),
            4: Core(self.R3, self.R1, self.R2),
            5: Core(self.R3, self.R2, self.R1)
        }
        self.core = rotorCon.get(index)

    def onP1Click(self, evt):
        #Sets the first Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r1.POSITION = index

    def onP2Click(self, evt):
        #Sets the second Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r2.POSITION = index

    def onP3Click(self, evt):
        #Sets the third Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r3.POSITION = index

root = Tk()
machine = Machine(root)
root.mainloop()

if __name__ == "__main___":
    main()
<commit_msg>added first frame refresh<commit_after>import Tkinter as Tk
from Tkinter import *

class Rotor(object):
    """Basic Rotor class for Enigma Machine."""

    def __init__(self, data):
        self.data = data
        self.POSITION = 0   #Current position on Rotor
        self.current = None

    @property
    def current(self):
        return self._current

    @current.setter
    def current(self, current):
        self._current = self.data[self.POSITION]

    @property
    def POSITION(self):
        return self._POSITION

    @POSITION.setter
    def POSITION(self, POSITION):
        if POSITION >= len(self.data):
            POSITION = POSITION % len(self.data)
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]
        elif POSITION < 0:
            POSITION = len(self.data)-1
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]

        else:
            self._POSITION = POSITION
            self._current = self.data[self.POSITION]

    def rotate(self):
        if len(self.data) != None:
            self.POSITION += 1
        else:
            print "There is no Rotor object to rotate."

#---------------------------------------------------------------------------------------------

class Core(object):

    def __init__(self, first, second, third):
        self.r1 = first
        self.r2 = second
        self.r3 = third

    def config(self, first, second, third, p1, p2, p3):
        #Sets the current rotor configuration and positions of each respective Rotor.

        self.r1 = first
        self.r2 = second
        self.r3 = third

        self.r1.POSITION = p1
        self.r2.POSITION = p2
        self.r3.POSITION = p3

    def encrypt(self, plain):
        #TODO: determine why some symbols appear in cipher
        cipher = list(plain)

        for i in range(len(cipher)):
            cipher[i] = ord(cipher[i])

            if cipher[i] is 32:
                cipher[i] = chr(cipher[i])
                self.iterate()

            elif cipher[i] > 64 and cipher[i] < 91:
                temp = (cipher[i] + ord(self.r1.current) + ord(self.r2.current) + ord(self.r3.current)) % 65
                temp += 65
                if temp >= 91:
                    temp -= 90
                    temp += 64
                    cipher[i] = chr(temp)
                else:
                    cipher[i] = chr(temp)

                self.iterate()

            elif cipher[i] > 96 and cipher[i] < 123:
                cipher[i] -= 32 #Changes lowercase to uppercase to keep with Enigma-style output.
                temp = (cipher[i] + ord(self.r1.current) + ord(self.r2.current) + ord(self.r3.current)) % 65
                temp += 65
                if temp >= 91:
                    temp -= 90
                    temp += 64
                    cipher[i] = chr(temp)
                else:
                    cipher[i] = chr(temp)

                self.iterate()

            else:
                cipher[i] = chr(cipher[i])
                self.iterate()

        output = ''.join(cipher)
        return output

    def decrypt(self, cipher):
        plain = list(cipher)

        for i in range(len(plain)):
            plain[i] = ord(plain[i])

            if plain[i] is 32:
                plain[i] = chr(plain[i])
                self.iterate()

            elif plain[i] > 64 and plain[i] < 91:
                temp = (plain[i] - ord(self.r1.current) - ord(self.r2.current) - ord(self.r3.current)) % 26
                temp += 65
                if temp <= 64:
                    temp += 26
                    plain[i] = chr(temp)
                else:
                    plain[i] = chr(temp)

                self.iterate()
            elif plain[i] > 96 and plain[i] < 123:
                plain[i] -= 32 #Changes lowercase input to uppercase to keep with Enigma-style output.
                temp = (plain[i] - ord(self.r1.current) - ord(self.r2.current) - ord(self.r3.current)) % 26
                temp += 65
                if temp <= 64:
                    temp += 26
                    plain[i] = chr(temp)
                else:
                    plain[i] = chr(temp)
                self.iterate()

            else:
                plain[i] = chr(plain[i])
                self.iterate()

        output= ''.join(plain)
        return output

    def iterate(self):
        self.r3.rotate()
        if self.r3.POSITION == 0:
            self.r2.rotate()
            if self.r2.POSITION == 0:
                self.r1.rotate()

#-------------------------------------------------------------------------------------------

"""
This is the letter arrangement from the 1930 Enigma I.

"""

class Machine:

#TODO: Step 1: Welcomes, prompts to begin or quit.
#Step 2: Ask for Rotor configuration (I-II-III, I-III-II, II-I-III, II-III-I, III-I-II, or III-II-I).
#Step 3: Ask for position for each rotor (0-25).
#Step 4: Ask whether the user wishes to encrypt or decrypt.
#Step 5: Ask the user to input the plaintext/ciphertext.
#TODO: Step 6: Returns the appropriate text.
#TODO: Step 7: Prompts to continue the program with the rotor settings, different settings, or to quit.

    def __init__(self, master):
        self.master = master
        self.core = None
        self.R1 = Rotor(['E', 'K', 'M', 'F', 'L', 'G', 'D', 'Q', 'V', 'Z', 'N', 'T', 'O', 'W', 'Y', 'H', 'X', 'U', 'S', 'P', 'A', 'I', 'B', 'R', 'C', 'J'])
        self.R2 = Rotor(['A', 'J', 'D', 'K', 'S', 'I', 'R', 'U', 'X', 'B', 'L', 'H', 'W', 'T', 'M', 'C', 'Q', 'G', 'Z', 'N', 'P', 'Y', 'F', 'V', 'O', 'E'])
        self.R3 = Rotor(['B', 'D', 'F', 'H', 'J', 'L', 'C', 'P', 'R', 'T', 'X', 'V', 'Z', 'N', 'Y', 'E', 'I', 'W', 'G', 'A', 'K', 'M', 'U', 'S', 'Q', 'O'])

        self.frame = Frame(master)
        self.frame.pack()
        self.sub = Frame(self.frame)
        self.sub.pack()

        q1 = Label(self.sub, text = 'Which rotor configuration are you using?')
        q1.pack()
        listbox = Listbox(self.sub, selectmode = SINGLE)
        listbox.pack()

        for item in ['I-II-III', 'I-III-II', 'II-I-III', 'II-III-I', 'III-I-II', 'III-II-I']:
            listbox.insert(END, item)

        listbox.bind('<<ListboxSelect>>', self.onConfigClick)

        q2 = Label(self.sub, text = 'Which position will each rotor be set to?')
        q2.pack()
        lb1 = Listbox(self.sub, selectmode = SINGLE)
        lb2 = Listbox(self.sub, selectmode = SINGLE)
        lb3 = Listbox(self.sub, selectmode = SINGLE)
        lb1.pack()
        lb2.pack()
        lb3.pack()

        for item in ['0','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']:
            lb1.insert(END, item)
            lb2.insert(END, item)
            lb3.insert(END, item)

        lb1.bind('<<ListboxSelect>>', self.onP1Click)
        lb2.bind('<<ListboxSelect>>', self.onP2Click)
        lb3.bind('<<ListboxSelect>>', self.onP3Click)

        confirm = Button(self.sub, text = 'Confirm', command = self.messageInput)
        confirm.pack()

    def messageInput(self):
        #TODO: Kill previous frame, reveal only entry box.
        self.sub.destroy()
        self.sub2 = Frame(self.frame)
        self.sub2.pack()
        greeting = Label(self.sub2, text = 'Would you like to encrypt or decrypt this message?')
        greeting.pack(side = TOP)

        e = Entry(self.sub2)
        e.pack()

        #TODO: Create a frame for the (en/de)crypt buttons
        encryptButton = Button(self.sub2, text = 'Encrypt', fg = 'black', command = lambda: self.enBut(e.get()))
        encryptButton.pack()
        decryptButton = Button(self.sub2, text = 'Decrypt', fg = 'black', command = lambda: self.deBut(e.get()))
        decryptButton.pack()

    def enBut(self, plain):
        cipher = self.core.encrypt(plain)
        print cipher
        self.sub2.destroy()
        self.sub3 = Frame(self.frame)
        self.sub3.pack()

        #TODO: Make third frame presentable
        output = Label(self.sub3, text = cipher)
        output.pack()

    def deBut(self, cipher):
        plain = self.core.decrypt(cipher)
        print plain
        self.sub2.destroy()
        self.sub3 = Frame(self.frame)
        self.sub3.pack()
        output = Label(self.sub3, text = plain)
        output.pack()

    def onConfigClick(self, evt):
        #Initializes the Core and Rotor configuration on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value

        rotorCon = {
            0: Core(self.R1, self.R2, self.R3),
            1: Core(self.R1, self.R3, self.R2),
            2: Core(self.R2, self.R1, self.R3),
            3: Core(self.R2, self.R3, self.R1),
            4: Core(self.R3, self.R1, self.R2),
            5: Core(self.R3, self.R2, self.R1)
        }
        self.core = rotorCon.get(index)

    def onP1Click(self, evt):
        #Sets the first Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r1.POSITION = index

    def onP2Click(self, evt):
        #Sets the second Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r2.POSITION = index

    def onP3Click(self, evt):
        #Sets the third Rotor's position on click
        w = evt.widget
        index = int(w.curselection()[0])
        value = w.get(index)
        print index, value
        self.core.r3.POSITION = index

root = Tk()
machine = Machine(root)
root.mainloop()

if __name__ == "__main___":
    main()
<|endoftext|>


<commit_before>import datetime
import collections

import pupa.scrape
from opencivicdata import common as ocd_common

from legistar.utils.itemgenerator import make_item
from legistar.jurisdictions.utils import try_jxn_delegation
from legistar.ext.pupa.base import Adapter, Converter

def _get_date(date):
    if isinstance(date, datetime.datetime):
        return date.strftime('%Y-%m-%d')
    else:
        return date

class ActionAdapter(Adapter):
    aliases = [('text', 'description')]
    extras_keys = ['version', 'media', 'result']
    drop_keys = ['sources', 'journal_page']

    @make_item('date')
    def get_date(self):
        return _get_date(self.data['date'])

class VoteAdapter(Adapter):
    pupa_model = pupa.scrape.Vote
    text_fields = ['organization']
    aliases = [
        ('text', 'motion_text'),
        ]
    drop_keys = ['date']
    extras_keys = ['version', 'media', 'journal_page']

    @make_item('start_date')
    def get_date(self):
        return _get_date(self.data.get('date'))

    @make_item('result')
    def get_result(self):
        if not self.data['result']:
            raise self.SkipItem()
        result = self.get_vote_result(self.data['result'])
        return result

    @make_item('votes', wrapwith=list)
    def gen_votes(self):
        for data in self.data['votes']:
            if not data:
                continue
            res = {}
            res['option'] = self.get_vote_option(data['vote'])
            res['note'] = data['vote']
            res['voter'] = data['person']
            yield res

    def get_instance(self, **extra_instance_data):
        data = self.get_instance_data()
        data.update(extra_instance_data)

        motion_text = data['motion_text']
        data['classification'] = self.classify_motion_text(motion_text)

        # Drop the org if necessary. When org is the top-level org, omit.
        if self.should_drop_organization(data):
            data.pop('organization', None)

        vote_data_list = data.pop('votes')
        extras = data.pop('extras')
        sources = data.pop('sources')

        vote = self.pupa_model(**data)

        counts = collections.Counter()
        for vote_data in vote_data_list:
            counts[vote_data['option']] += 1
            vote.vote(**vote_data)

        for option, value in counts.items():
            vote.set_count(option, value)

        for source in sources:
            vote.add_source(**source)

        vote.extras.update(extras)

        # Skip no-result "votes"
        # https://sfgov.legistar.com/LegislationDetail.aspx?ID=1866659&GUID=A23A12AB-C833-4235-81A1-02AD7B8E7CF0&Options=Advanced&Search
        if vote.result is None:
            return

        return vote

    # ------------------------------------------------------------------------
    # Overridables
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def get_vote_result(self, result):
        '''Noramalizes the vote result value using the default values on
        Config base, possibly overridded by jxn.BILL_VOTE_RESULT_MAP.
        '''
        result = result.replace('-', ' ').lower()
        result = self.cfg._BILL_VOTE_RESULT_MAP[result]
        return result

    @try_jxn_delegation
    def get_vote_option(self, option_text):
        '''Noramalizes the vote option value using the default values on
        Config base, possibly overridded by jxn.BILL_VOTE_OPTION_MAP.
        '''
        option_text = option_text.replace('-', ' ').lower()
        return self.cfg._BILL_VOTE_OPTION_MAP[option_text]

    @try_jxn_delegation
    def should_drop_organization(self, data):
        '''If this function returns True, the org is dropped from the vote obj.

        XXX: Right now, always drops the org.
        '''
        return True

    @try_jxn_delegation
    def classify_motion_text(self, motion_text):
        '''Jurisdiction configs can override this to determine how
        vote motions will be classified.
        '''
        return []

class BillsAdapter(Adapter):
    pupa_model = pupa.scrape.Bill
    aliases = [
        ('file_number', 'identifier'),
        ]
    extras_keys = [
        'law_number', 'status']

    @make_item('classification')
    def get_classn(self):
        return self.get_bill_classification(self.data.pop('type'))

    @make_item('actions', wrapwith=list)
    def gen_actions(self):
        for data in self.data.get('actions'):
            data = dict(data)
            data.pop('votes')
            action = self.make_child(ActionAdapter, data).get_instance_data()
            if action['description'] is None:
                action['description'] = ''
            yield action

    @make_item('sponsorships')
    def get_sponsorships(self):
        return self.data.get('sponsors', [])

    @make_item('votes', wrapwith=list)
    def gen_votes(self):
        for data in self.data.get('actions'):
            converter = self.make_child(VoteAdapter, data)
            more_data = dict(
                legislative_session=self.data['legislative_session'])
            vote = converter.get_instance(**more_data)
            if vote is not None and vote.votes:
                yield vote

    @make_item('subject')
    def _gen_subjects(self, wrapwith=list):
        yield from self.gen_subjects()

    def get_instance(self):
        '''Build a pupa instance from the data.
        '''
        data = self.get_instance_data()
        data_copy = dict(data)
        bill = pupa.scrape.Bill(
            identifier=data['identifier'],
            legislative_session=data['legislative_session'],
            classification=data.get('classification', []),
            title=data['title'],
            )

        for action in data.pop('actions'):
            action.pop('extras')
            self.drop_action_organization(action)
            bill.add_action(**action)

        for sponsorship in data.pop('sponsorships'):
            if not self.should_drop_sponsor(sponsorship):
                kwargs = dict(
                    classification=self.get_sponsor_classification(sponsorship),
                    entity_type=self.get_sponsor_entity_type(sponsorship),
                    primary=self.get_sponsor_primary(sponsorship))
                kwargs.update(sponsorship)
                bill.add_sponsorship(**kwargs)

        for source in data.pop('sources'):
            bill.add_source(**source)

        bill.extras.update(data.pop('extras'))

        for identifier in data.pop('identifiers'):
            bill.add_identifier(**identifier)

        if bill.title is None:
            bill.title = ''

        yield bill

        for vote in data.pop('votes'):
            vote.set_bill(bill)
            yield vote

    # ------------------------------------------------------------------------
    # Overridables: sponsorships
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def should_drop_sponsor(self, data):
        '''If this function retruns True, the sponsor is dropped.
        '''
        return False

    @try_jxn_delegation
    def get_sponsor_classification(self, data):
        '''Return the sponsor's pupa classification. Legistar generally
        doesn't provide any info like this, so we just return "".
        '''
        return 'sponsor'

    @try_jxn_delegation
    def get_sponsor_entity_type(self, data):
        '''Return the sponsor's pupa entity type.
        '''
        return 'person'

    @try_jxn_delegation
    def get_sponsor_primary(self, data):
        '''Return whether the sponsor is primary. Legistar generally doesn't
        provide this.
        '''
        return False

    # ------------------------------------------------------------------------
    # Overridables: actions
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def drop_action_organization(self, data):
        '''
        XXX: This temporarily drops the action['organization'] from all
        actions. See pupa issue #105 https://github.com/opencivicdata/pupa/issues/105/

        When the organization is the top-level org, it doesn't get set
        on the action.
        '''
        data.pop('organization', None)

    # ------------------------------------------------------------------------
    # Overridables: miscellaneous
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def gen_subjects(self, data):
        '''Get whatever data from the scraped data represents subjects.
        '''
        raise StopIteration()

    @try_jxn_delegation
    def get_bill_classification(self, billtype):
        '''Convert the legistar bill `type` column into
        a pupa classification array.
        '''
        # Try to get the classn from the subtype.
        classn = getattr(self, '_BILL_CLASSIFICATIONS', {})
        classn = dict(classn).get(billtype)
        if classn is not None:
            return [classn]

        # Bah, no matches--try to guess it.
        type_lower = billtype.lower()
        for classn in dict(ocd_common.BILL_CLASSIFICATION_CHOICES):
            if classn in type_lower:
                return [classn]

        # None found; return emtpy array.
        return []

class BillsConverter(Converter):
    adapter = BillsAdapter
<commit_msg>Add unique identifiers onto votes<commit_after>import datetime
import collections
from urllib.parse import urlparse, parse_qsl

import pupa.scrape
from opencivicdata import common as ocd_common
from hercules import CachedAttr

from legistar.utils.itemgenerator import make_item
from legistar.jurisdictions.utils import try_jxn_delegation
from legistar.ext.pupa.base import Adapter, Converter

def _get_date(date):
    if isinstance(date, datetime.datetime):
        return date.strftime('%Y-%m-%d')
    else:
        return date

class ActionAdapter(Adapter):
    aliases = [('text', 'description')]
    extras_keys = ['version', 'media', 'result']
    drop_keys = ['sources', 'journal_page']

    @make_item('date')
    def get_date(self):
        return _get_date(self.data['date'])

class VoteAdapter(Adapter):
    pupa_model = pupa.scrape.Vote
    text_fields = ['organization']
    aliases = [
        ('text', 'motion_text'),
        ]
    drop_keys = ['date']
    extras_keys = ['version', 'media', 'journal_page']

    @make_item('identifier')
    def get_identifier(self):
        '''The internal legistar bill id and guid found
        in the detail page url.
        '''
        i = self.data.pop('i')
        for source in self.data['sources']:
            if not 'historydetail' in source['url'].lower():
                continue
            url = urlparse(source['url'])
            ids = {}
            for idtype, ident in parse_qsl(url.query):
                if idtype == 'options':
                    continue
                ids[idtype.lower()] = ident
            return ids['guid']

        # The vote has no "action details" page, thus no identifier.
        # Fudge one based on the bill's guid.
        for source in self.bill_adapter.data['identifiers']:
            if source['scheme'] != 'legistar_guid':
                continue
            return '%s-vote%d' % (source['identifier'], i)

        import pdb; pdb.set_trace()

    @make_item('start_date')
    def get_date(self):
        return _get_date(self.data.get('date'))

    @make_item('result')
    def get_result(self):
        if not self.data['result']:
            raise self.SkipItem()
        result = self.get_vote_result(self.data['result'])
        return result

    @make_item('votes', wrapwith=list)
    def gen_votes(self):
        for data in self.data['votes']:
            if not data:
                continue
            res = {}
            res['option'] = self.get_vote_option(data['vote'])
            res['note'] = data['vote']
            res['voter'] = data['person']
            yield res

    def get_instance(self, **extra_instance_data):
        data = self.get_instance_data()
        data.update(extra_instance_data)

        motion_text = data['motion_text']
        data['classification'] = self.classify_motion_text(motion_text)

        # Drop the org if necessary. When org is the top-level org, omit.
        if self.should_drop_organization(data):
            data.pop('organization', None)

        vote_data_list = data.pop('votes')
        extras = data.pop('extras')
        sources = data.pop('sources')

        data.pop('i', None)
        vote = self.pupa_model(**data)

        counts = collections.Counter()
        for vote_data in vote_data_list:
            counts[vote_data['option']] += 1
            vote.vote(**vote_data)

        for option, value in counts.items():
            vote.set_count(option, value)

        for source in sources:
            vote.add_source(**source)

        vote.extras.update(extras)

        # Skip no-result "votes"
        # https://sfgov.legistar.com/LegislationDetail.aspx?ID=1866659&GUID=A23A12AB-C833-4235-81A1-02AD7B8E7CF0&Options=Advanced&Search
        if vote.result is None:
            return

        return vote

    # ------------------------------------------------------------------------
    # Overridables
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def get_vote_result(self, result):
        '''Noramalizes the vote result value using the default values on
        Config base, possibly overridded by jxn.BILL_VOTE_RESULT_MAP.
        '''
        result = result.replace('-', ' ').lower()
        result = self.cfg._BILL_VOTE_RESULT_MAP[result]
        return result

    @try_jxn_delegation
    def get_vote_option(self, option_text):
        '''Noramalizes the vote option value using the default values on
        Config base, possibly overridded by jxn.BILL_VOTE_OPTION_MAP.
        '''
        option_text = option_text.replace('-', ' ').lower()
        return self.cfg._BILL_VOTE_OPTION_MAP[option_text]

    @try_jxn_delegation
    def should_drop_organization(self, data):
        '''If this function returns True, the org is dropped from the vote obj.

        XXX: Right now, always drops the org.
        '''
        return True

    @try_jxn_delegation
    def classify_motion_text(self, motion_text):
        '''Jurisdiction configs can override this to determine how
        vote motions will be classified.
        '''
        return []

class BillsAdapter(Adapter):
    pupa_model = pupa.scrape.Bill
    aliases = [
        ('file_number', 'identifier'),
        ]
    extras_keys = [
        'law_number', 'status']

    @make_item('classification')
    def get_classn(self):
        return self.get_bill_classification(self.data.pop('type'))

    @make_item('actions', wrapwith=list)
    def gen_actions(self):
        for data in self.data.get('actions'):
            data = dict(data)
            data.pop('votes')
            action = self.make_child(ActionAdapter, data).get_instance_data()
            if action['description'] is None:
                action['description'] = ''
            yield action

    @make_item('sponsorships')
    def get_sponsorships(self):
        return self.data.get('sponsors', [])

    @make_item('votes', wrapwith=list)
    def gen_votes(self):
        for i, data in enumerate(self.data.get('actions')):
            data['i'] = i
            converter = self.make_child(VoteAdapter, data)
            converter.bill_adapter = self
            more_data = dict(
                legislative_session=self.data['legislative_session'])
            vote = converter.get_instance(**more_data)
            if vote is not None and vote.votes:
                yield vote

    @make_item('subject')
    def _gen_subjects(self, wrapwith=list):
        yield from self.gen_subjects()

    def get_instance(self):
        '''Build a pupa instance from the data.
        '''
        data = self.get_instance_data()
        data_copy = dict(data)
        bill = pupa.scrape.Bill(
            identifier=data['identifier'],
            legislative_session=data['legislative_session'],
            classification=data.get('classification', []),
            title=data['title'],
            )

        for action in data.pop('actions'):
            action.pop('extras')
            self.drop_action_organization(action)
            bill.add_action(**action)

        for sponsorship in data.pop('sponsorships'):
            if not self.should_drop_sponsor(sponsorship):
                kwargs = dict(
                    classification=self.get_sponsor_classification(sponsorship),
                    entity_type=self.get_sponsor_entity_type(sponsorship),
                    primary=self.get_sponsor_primary(sponsorship))
                kwargs.update(sponsorship)
                bill.add_sponsorship(**kwargs)

        for source in data.pop('sources'):
            bill.add_source(**source)

        bill.extras.update(data.pop('extras'))

        for identifier in data.pop('identifiers'):
            bill.add_identifier(**identifier)

        if bill.title is None:
            bill.title = ''

        yield bill

        for vote in data.pop('votes'):
            vote.set_bill(bill)
            yield vote

    # ------------------------------------------------------------------------
    # Overridables: sponsorships
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def should_drop_sponsor(self, data):
        '''If this function retruns True, the sponsor is dropped.
        '''
        return False

    @try_jxn_delegation
    def get_sponsor_classification(self, data):
        '''Return the sponsor's pupa classification. Legistar generally
        doesn't provide any info like this, so we just return "".
        '''
        return 'sponsor'

    @try_jxn_delegation
    def get_sponsor_entity_type(self, data):
        '''Return the sponsor's pupa entity type.
        '''
        return 'person'

    @try_jxn_delegation
    def get_sponsor_primary(self, data):
        '''Return whether the sponsor is primary. Legistar generally doesn't
        provide this.
        '''
        return False

    # ------------------------------------------------------------------------
    # Overridables: actions
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def drop_action_organization(self, data):
        '''
        XXX: This temporarily drops the action['organization'] from all
        actions. See pupa issue #105 https://github.com/opencivicdata/pupa/issues/105/

        When the organization is the top-level org, it doesn't get set
        on the action.
        '''
        data.pop('organization', None)

    # ------------------------------------------------------------------------
    # Overridables: miscellaneous
    # ------------------------------------------------------------------------
    @try_jxn_delegation
    def gen_subjects(self, data):
        '''Get whatever data from the scraped data represents subjects.
        '''
        raise StopIteration()

    @try_jxn_delegation
    def get_bill_classification(self, billtype):
        '''Convert the legistar bill `type` column into
        a pupa classification array.
        '''
        # Try to get the classn from the subtype.
        classn = getattr(self, '_BILL_CLASSIFICATIONS', {})
        classn = dict(classn).get(billtype)
        if classn is not None:
            return [classn]

        # Bah, no matches--try to guess it.
        type_lower = billtype.lower()
        for classn in dict(ocd_common.BILL_CLASSIFICATION_CHOICES):
            if classn in type_lower:
                return [classn]

        # None found; return emtpy array.
        return []

class BillsConverter(Converter):
    adapter = BillsAdapter
<|endoftext|>