Commits

Tohru Ike  committed 66a3b7c

first commit.

  • Participants

Comments (0)

Files changed (17)

+syntax: regexp
+\.installed\.cfg
+_build
+bin
+develop-eggs
+eggs
+parts
+src\/book\.isbn\.egg-info/
+.*\.pyc
+`book.isbn` is written and maintained by the Rokujyouhitoma Team and various
+contributors:
+
+Project Leader / Developer:
+
+- Tohru Ike <tohru.ike@gmail.com>
+History
+========
+
+Version 0.0.1 
+--------------
+(released May 29th 2011)
+
+- Initial release
+Copyright (c) 2011 by the Rokujyouhitoma Team,
+see AUTHORS for more details.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+include AUTHORS
+include CHANGES
+include LICENSE
+include MANIFEST.in
+include README.rst
+include bootstrap.py
+include buildout.cfg
+include setup.cfg
+recursive-include src *.py *.txt
+`book.isbn` is a package for book ISBN.
+
+======
+setup
+======
+
+easy_install
+=============
+
+.. code-block:: bash
+
+   $ easy_install book.isbn
+
+pip
+====
+
+.. code-block:: bash
+
+   $ pip install book.isbn

File bootstrap.py

+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

File buildout.cfg

+[buildout]
+parts = book.isbn test
+develop = .
+
+[book.isbn]
+recipe = zc.recipe.egg
+eggs = book.isbn
+interpreter = py
+
+[test]
+recipe = pbp.recipe.noserunner
+eggs =
+    nose
+    pep8
+    book.isbn [test]
+defaults =
+    --verbosity=3
+    --with-doctest
+[egg_info]
+;tag_build = dev
+
+[build]
+build-base = _build
+
+[sdist]
+formats = gztar
+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+import sys
+
+sys.path.insert(0, 'src')
+import book
+
+version = book.__version__
+name='book.isbn'
+short_description = '`book.isbn` is a package for book ISBN.'
+long_description= \
+    open("README.rst").read()+ \
+    open("CHANGES").read()
+
+classifiers = [
+    'Development Status :: 1 - Planning',
+    'License :: OSI Approved :: NEW BSD License',
+    'Programming Language :: Python',
+    'Topic :: Utilities',
+    ]
+
+setup(
+    name='book.isbn',
+    version=version,
+    description=short_description,
+    long_description=long_description,
+    classifiers=classifiers,
+    keywords=['book',],
+    author='Tohru Ike',
+    author_email='tohru.ike@gmail.com',
+    url='http://pypi.python.org/pypi/book.isbn',
+    license='NEW BSD',
+    packages=find_packages('src'),
+    package_dir={'': 'src'},
+    package_data = {'': ['buildout.cfg']},
+    include_package_data=True,
+    namespace_packages=['book'],
+    zip_safe=False,
+    install_requires=[
+        'setuptools',
+        ],
+    extras_require=dict(
+        test=[
+            'Nose',
+            'pep8',
+        ],
+    ),
+    test_suite='nose.collector',
+    tests_require=['Nose','pep8'],
+    )

File src/book/__init__.py

+# -*- coding:utf-8 -*-
+# this is a namespace package
+try:
+    import pkg_resources
+    pkg_resources.declare_namespace(__name__)
+except ImportError:
+    import pkgutil
+    __path__ = pkgutil.extend_path(__path__, __name__)
+
+__version__ = "0.0.1"

File src/book/isbn/__init__.py

+# -*- coding: utf-8 -*-
+
+
+__all__ = ['check10',
+           'check13',
+           'modulus11weight10to2',
+           'modulus11weight3',
+           'encode10to13',
+           'encode13to10',
+           ]
+
+
+def check10(isbn10):
+    u"""
+    >>> check10(u'0306406152')
+    True
+    """
+
+    if len(isbn10) != 10:
+        raise ValueError(len(isbn10))
+
+    check_sum = modulus11weight10to2(isbn10[:-1])
+    if isbn10[-1] == check_sum:
+        return True
+    else:
+        return False
+
+
+def check13(isbn13):
+    u"""
+    >>> check13(u'9780306406157')
+    True
+    """
+
+    if len(isbn13) != 13:
+        raise ValueError(len(isbn13))
+
+    check_sum = modulus11weight3(isbn13[:-1])
+    if isbn13[-1] == check_sum:
+        return True
+    else:
+        return False
+
+
+def modulus11weight10to2(c9):
+    u"""
+    >>> modulus11weight10to2(u'030640615')
+    u'2'
+    """
+
+    if len(c9) != 9:
+        raise ValueError(len(c9))
+
+    sum = 0
+    for i in range(len(c9)):
+        try:
+            c = int(c9[i])
+        except ValueError:
+            return False
+        weight = 10 - i
+        sum += weight * c
+
+    remainder = sum % 11
+    result = 11 - remainder
+
+    if result == 10:
+        return u'X'
+    else:
+        return unicode(result)
+
+
+def modulus11weight3(c12):
+    u"""
+    >>> modulus11weight3(u'978030640615')
+    u'7'
+    """
+
+    if len(c12) != 12:
+        raise ValueError(len(c12))
+
+    sum = 0
+    for i in range(len(c12)):
+        try:
+            c = int(c12[i])
+        except ValueError:
+            return False
+        if i % 2:
+            weight = 3
+        else:
+            weight = 1
+        sum += weight * c
+
+    remainder = sum % 10
+    result = 10 - remainder
+
+    if result == 10:
+        return u'0'
+    else:
+        return unicode(result)
+
+
+def encode10to13(isbn10):
+    u"""
+    >>> encode10to13(u'0306406152')
+    u'9780306406157'
+    >>> encode10to13(u'487311361X')
+    u'9784873113616'
+    >>> encode10to13(u'4873114209')
+    u'9784873114200'
+    """
+
+    if len(isbn10) != 10:
+        raise ValueError(len(isbn10))
+
+    prefix = u'978' + isbn10[:-1]
+    check_digit = modulus11weight3(prefix)
+    return prefix + check_digit
+
+
+def encode13to10(isbn13):
+    u"""
+    >>> encode13to10(u'9780306406157')
+    u'0306406152'
+    >>> encode13to10(u'9784873113616')
+    u'487311361X'
+    >>> encode13to10(u'9784873114200')
+    u'4873114209'
+    """
+
+    if len(isbn13) != 13:
+        raise ValueError(len(isbn13))
+
+    prefix = isbn13[3:-1]
+    check_digit = modulus11weight10to2(prefix)
+    return prefix + check_digit

File src/book/isbn/tests/test_isbn.py

+# -*- coding: utf-8 -*-
+
+import unittest
+from book import isbn
+
+
+class TestISBN(unittest.TestCase):
+
+    def setUp(self):
+        pass
+
+    def test_check10(self):
+        goodcase = (
+            u'0306406152',
+            )
+        for isbn10 in goodcase:
+            self.assertTrue(isbn.check10(isbn10))
+
+        badcase = (
+            u'1234567890',
+            )
+        for isbn10 in badcase:
+            self.assertFalse(isbn.check10(isbn10))
+
+        errorcase = (
+            u'',
+            #1, #TODO: Number
+            u'123456789',
+            u'12345678901',
+            )
+        for invalid_isbn in errorcase:
+            try:
+                isbn.check10(invalid_isbn)
+                self.fail()
+            except ValueError:
+                pass
+
+    def test_check13(self):
+        goodcase = (
+            u'9780306406157',
+            )
+        for isbn13 in goodcase:
+            self.assertTrue(isbn.check13(isbn13))
+
+        badcase = (
+            )
+
+    def test_modulus11weight10to2(self):
+        goodcase = (
+            (u'030640615', u'2',),
+            )
+        for (isbn9, digit) in goodcase:
+            self.assertEqual(isbn.modulus11weight10to2(isbn9), digit)
+
+    def test_modulus11weight3(self):
+        goodcase = (
+            (u'978030640615', u'7',),
+            )
+        for (isbn10, digit) in goodcase:
+            self.assertEqual(isbn.modulus11weight3(isbn10), digit)
+
+    def test_encode10to13(self):
+        goodcase = (
+            (u'0306406152', u'9780306406157'),
+            (u'487311361X', u'9784873113616'),
+            (u'4873114209', u'9784873114200'),
+            )
+        for (isbn10, isbn13) in goodcase:
+            self.assertEqual(isbn.encode10to13(isbn10), isbn13)
+
+    def test_encode13to10(self):
+        goodcase = (
+            (u'0306406152', u'9780306406157'),
+            (u'487311361X', u'9784873113616'),
+            (u'4873114209', u'9784873114200'),
+            )
+        for (isbn10, isbn13) in goodcase:
+            self.assertEqual(isbn.encode13to10(isbn13), isbn10)
+
+
+if __name__ == '__main__':
+    unittest.main()

File src/book/isbn/tests/test_pep8.py

+# -*- coding: utf-8 -*-
+
+import os
+import pep8
+
+CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
+BASE_DIR = os.path.dirname(CURRENT_DIR)
+
+
+def test_pep8():
+    arglist = [
+        '--statistics',
+        '--filename=*.py',
+        '--show-source',
+        '--repeat',
+        '--exclude=SVGdraw.py',
+        #'--show-pep8',
+        #'-qq',
+        #'-v',
+        BASE_DIR,
+    ]
+
+    options, args = pep8.process_options(arglist)
+    runner = pep8.input_file
+
+    for path in args:
+        if os.path.isdir(path):
+            pep8.input_dir(path, runner=runner)
+        elif not pep8.excluded(path):
+            options.counters['files'] += 1
+            runner(path)
+
+    pep8.print_statistics()
+    errors = pep8.get_count('E')
+    warnings = pep8.get_count('W')
+    message = 'pep8: %d errors / %d warnings' % (errors, warnings)
+    print message
+    assert errors + warnings == 0, message

File src/book/isbn/wsgi.py

+# -*- coding:utf-8 -*-
+
+import urlparse
+from book import isbn
+import functools
+
+default_message = """\
+book.isbn provide below urls:
+ * /check10/<\d{10}>/
+ * /check13/<\d{13}>/
+ * /modulus11weight10to2/<\d9>/
+ * /modulus11weight3/<\d12>/
+ * /encode10to13/<\d{10}>/
+ * /encode13to10/<\d{13}>/
+"""
+
+
+def check_args(num):
+    def _decorator(func):
+        @functools.wraps(func)
+        def __decorator(*args, **kw):
+            if  len(args) == num:
+                return func(*args, **kw)
+            else:
+                raise Exception('argument is not %s' % str(num))
+        return __decorator
+    return _decorator
+
+
+isbn.check10 = check_args(1)(isbn.check10)
+isbn.check13 = check_args(1)(isbn.check13)
+isbn.modulus11weight10to2 = check_args(1)(isbn.modulus11weight10to2)
+isbn.modulus11weight3 = check_args(1)(isbn.modulus11weight3)
+isbn.encode10to13 = check_args(1)(isbn.encode10to13)
+isbn.encode13to10 = check_args(1)(isbn.encode13to10)
+
+
+def wsgi_app(environ, start_response):
+    split_result = urlparse.urlsplit(environ['PATH_INFO'])
+    paths = filter(None, split_result[2].split('/'))
+    headers = [('Content-Type', 'text/plain')]
+
+    if not paths:
+        start_response('200 OK', headers)
+        return [default_message]
+
+    api_name = paths[0]
+
+    try:
+        method = getattr(isbn, api_name)
+    except Exception, e:
+        status = '404 Not Found'
+        start_response(status, headers)
+        return [status]
+
+    try:
+        result = str(method(paths[1])).encode('utf-8')
+    except Exception, e:
+        status = '500 Internal Server Error'
+        start_response(status, headers)
+        return [status]
+
+    start_response('200 OK', headers)
+    return [result]
+
+
+def app_factory(global_config, **local_conf):
+    """ wsgi app factory for Paste """
+    return wsgi_app

File src/book/isbn/wsgi_run.py

+# -*- coding: utf-8 -*-
+
+from wsgiref.simple_server import make_server
+from book.isbn import wsgi
+
+if __name__ == '__main__':
+    server = make_server('localhost', 8080, wsgi.wsgi_app)
+    server.serve_forever()
+Development Environment
+========================
+
+bootstrap
+----------
+
+.. code-block:: bash
+   $ python bootstrap.py -d
+   $ bin/buildout
+
+
+run tests
+----------
+
+.. code-block:: bash
+   $ bin/test
+
+run some doctest
+-----------------
+
+.. code-block:: bash
+   $ python -m doctest src/book/isbn/__init__.py -v