Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

initial release. working qr/url shortening creation. asynchronous data

saving on couchdb via PUSH/PULL model. Thos model need to be reworked to
a XREQ system.
  • Loading branch information...
commit 2c9e18d5f3ef7d361241b7f1306b953e80f23ef0 0 parents
Benoit Chesneau authored
15 .gitignore
... ... @@ -0,0 +1,15 @@
  1 +*.gem
  2 +*.swp
  3 +*.pyc
  4 +*.pyo
  5 +*#*
  6 +build
  7 +dist
  8 +setuptools-*
  9 +.svn/*
  10 +.DS_Store
  11 +*.so
  12 +qrurl.egg-info
  13 +nohup.out
  14 +.coverage
  15 +
22 LICENSE
... ... @@ -0,0 +1,22 @@
  1 +20011 (c) Benoît Chesneau <benoitc@e-engura.org>
  2 +
  3 +Permission is hereby granted, free of charge, to any person
  4 +obtaining a copy of this software and associated documentation
  5 +files (the "Software"), to deal in the Software without
  6 +restriction, including without limitation the rights to use,
  7 +copy, modify, merge, publish, distribute, sublicense, and/or sell
  8 +copies of the Software, and to permit persons to whom the
  9 +Software is furnished to do so, subject to the following
  10 +conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be
  13 +included in all copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  17 +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19 +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20 +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22 +OTHER DEALINGS IN THE SOFTWARE.
11 MANIFEST.in
... ... @@ -0,0 +1,11 @@
  1 +include NOTICE
  2 +include LICENSE
  3 +include README.rst
  4 +include TODO.txt
  5 +include THANKS
  6 +include bootstrap.py
  7 +include buildout.cfg
  8 +recursive-include debian *
  9 +recursive-include examples *
  10 +recursive-include tests *
  11 +recursive-include doc *
7 NOTICE
... ... @@ -0,0 +1,7 @@
  1 +qrurl
  2 +-----
  3 +
  4 +2011 (c) Benoît Chesneau <benoitc@e-engura.org>
  5 +
  6 +qrurl is released under the MIT license. See the LICENSE file for the
  7 +complete license.
0  README.rst
Source Rendered
No changes.
7 bin/qrurl-consumer
... ... @@ -0,0 +1,7 @@
  1 +#!/usr/bin/env sh
  2 +# This file is part of qrurl released under the MIT license.
  3 +# See the NOTICE for more information.
  4 +
  5 +PYTHON_BIN=`which python`
  6 +
  7 +$PYTHON_BIN -OO -c "import qrurl.consumer" $@
8 qrurl/__init__.py
... ... @@ -0,0 +1,8 @@
  1 +# -*- coding: utf-8 -
  2 +#
  3 +# This file is part of qrurl released under the MIT license.
  4 +# See the NOTICE for more information.
  5 +
  6 +version_info = (0, 1, 0)
  7 +__version__ = ".".join(map(str, version_info))
  8 +
66 qrurl/api.py
... ... @@ -0,0 +1,66 @@
  1 +# -*- coding: utf-8 -
  2 +#
  3 +# This file is part of qrurl released under the MIT license.
  4 +# See the NOTICE for more information.
  5 +
  6 +import hashlib
  7 +import re
  8 +import time
  9 +
  10 +from qrurl.base62 import b62encode
  11 +
  12 +URL_PATTERN = ur'^[a-z]+://([^/:]+\.[a-z]{2,10}|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]+)?(\/.*)?$'
  13 +RE_URL = re.compile(URL_PATTERN, re.IGNORECASE)
  14 +
  15 +def key(*args):
  16 + return ':'.join(["URL"] + [arg.upper() for arg in args])
  17 +
  18 +def valid_url(url):
  19 + if not RE_URL.match(url):
  20 + raise ValueError("invalid url")
  21 + return url
  22 +
  23 +def create_url(conn, sock, url):
  24 + url = valid_url(url)
  25 +
  26 + uri_key = key(hashlib.sha1(url).hexdigest())
  27 +
  28 + uri_id = str(b62encode(int(conn.incr(key("id")))))
  29 + conn.set(uri_key, uri_id)
  30 + conn.set(key("hash", uri_id), uri_key)
  31 + t = int(time.time())
  32 + data_key = key("uid", "data", uri_id)
  33 + conn.hset(data_key, 'date_creation', t)
  34 + conn.hset(data_key, 'url', url)
  35 +
  36 + # send url creation to consumers
  37 + sock.send("URL:%s" % uri_id)
  38 + return uri_id
  39 +
  40 +def get_url(conn, uid):
  41 + u = conn.hget(key("uid", "data", uid), 'url')
  42 + if u:
  43 + return u
  44 +
  45 +def get_url_info(conn, uid):
  46 + u = conn.hgetall(key("uid", "data", uid))
  47 + if u:
  48 + return u
  49 +
  50 +def set_click(conn, uid, info):
  51 + conn.hmset(key("uid", "click"), info)
  52 +
  53 +def get_click(conn, uid):
  54 + click = conn.hgetall(key("uid", "click", uid))
  55 + if click:
  56 + return click
  57 +
  58 +def add_consumer(conn, consumer_uri):
  59 + return conn.sadd("consumers", consumer_uri)
  60 +
  61 +def get_consumers(conn):
  62 + return conn.smembers("consumers")
  63 +
  64 +def remove_consumer(conn, consumer_uri):
  65 + return conn.srem("consumers", consumer_uri)
  66 +
46 qrurl/base62.py
... ... @@ -0,0 +1,46 @@
  1 +# -*- coding: utf-8 -
  2 +#
  3 +# This file is part of friendpaste released under Apache License, Version 2.0.
  4 +# See the NOTICE for more information.
  5 +
  6 +import string
  7 +
  8 +
  9 +BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  10 +BASE62_VALUES = ''.join([chr(i) for i in range(62)])
  11 +
  12 +E_BASE62_PRIMITIVES = dict([(BASE62_CHARS[i], i) for i in range(62)])
  13 +D_BASE62_PRIMITIVES = string.maketrans(BASE62_VALUES, BASE62_CHARS)
  14 +
  15 +def b62encode(value):
  16 + """ encode int/long to base62 stsring.
  17 +
  18 + >>> b62encode(1123458)
  19 + '4iGI'
  20 + """
  21 + number = value
  22 + result = ''
  23 + while number != 0:
  24 + result = D_BASE62_PRIMITIVES[number % 62] + result
  25 + number /= 62
  26 + return result
  27 +
  28 +def b62decode(value):
  29 + """ decode string to int/long
  30 +
  31 + >>> b62decode('4iGI')
  32 + 1123458
  33 + """
  34 + value = str(value)
  35 + i = 0
  36 + i_out = 0
  37 + for c in value[::-1]:
  38 + place = 62 ** i
  39 + i_out += int(E_BASE62_PRIMITIVES[c]) * place
  40 + i += 1
  41 + return i_out
  42 +
  43 +
  44 +if __name__ == '__main__':
  45 + import doctest
  46 + doctest.testmod()
158 qrurl/consumer.py
... ... @@ -0,0 +1,158 @@
  1 +# -*- coding: utf-8 -
  2 +#
  3 +# This file is part of qrurl released under the MIT license.
  4 +# See the NOTICE for more information.
  5 +
  6 +import json
  7 +from optparse import OptionParser, make_option
  8 +import sys
  9 +import time
  10 +
  11 +import couchdbkit
  12 +import gevent
  13 +from gevent import monkey; monkey.patch_socket()
  14 +from gevent_zeromq import zmq
  15 +import redis
  16 +
  17 +from qrurl import api
  18 +
  19 +class Consumer(object):
  20 + """ simple consumer class saving infos from redis on couchdb to
  21 + process them later and allows their replication to final users """
  22 +
  23 +
  24 + def __init__(self, couch_uri="http://127.0.0.1:5984/lqr",
  25 + redis_host="127.0.0.1", redis_port=6379, redis_db=0,
  26 + zmq_uri="tcp://127.0.0.1:5000"):
  27 +
  28 + self.conf = dict(
  29 + couch_uri = couch_uri,
  30 + redis_host = redis_host,
  31 + redis_port = redis_port,
  32 + redis_db = redis_db,
  33 + zmq_uri = zmq_uri
  34 + )
  35 +
  36 + # set redis connections
  37 + self.conn_redis = redis.Redis(host=redis_host, port=redis_port,
  38 + db=redis_db)
  39 +
  40 + # set couch database
  41 + self.couch_db = couchdbkit.Database(couch_uri, create=True)
  42 + self.docs = []
  43 + self.last_updated = 0
  44 +
  45 + # create zmq context
  46 + self.zmq_ctx = zmq.Context()
  47 + self.zmq_sock = self.zmq_ctx.socket(zmq.PULL)
  48 + self.zmq_sock.bind(zmq_uri)
  49 +
  50 + # we are alive
  51 + self.alive = True
  52 +
  53 + # register consumer so it can receive messages
  54 + self.register()
  55 +
  56 + # start doc loop
  57 + self.start_batch()
  58 +
  59 +
  60 + def start_batch(self):
  61 + """Start the batch Greenlet used to send docs each mn"""
  62 +
  63 + def batch():
  64 + while self.alive:
  65 + gevent.sleep(60.0)
  66 + if len(self.docs) > 0:
  67 + self.couch_db.save_docs(self.docs)
  68 + self.docs = []
  69 +
  70 + return gevent.spawn(batch)
  71 +
  72 + def stop(self):
  73 + self.alive = False
  74 +
  75 +
  76 + def register(self):
  77 + api.add_consumer(self.conn_redis, self.conf['zmq_uri'])
  78 +
  79 + def unregister(self):
  80 + api.remove_consumer(self.conn_redis, self.conf['zmq_uri'])
  81 +
  82 + try:
  83 + self.zmq_sock.close()
  84 + self.zmq_ctx.term()
  85 + except:
  86 + pass
  87 +
  88 + def handle_message(self, msg):
  89 + kind, uri = msg.split(":", 1)
  90 +
  91 + print uri
  92 + if kind == "URL":
  93 + doc = api.get_url_info(self.conn_redis, uri)
  94 + print "got doc"
  95 + if kind == "CLICK":
  96 + doc = api.get_click(self.conn_redis, uri)
  97 +
  98 + diff = time.time() - self.last_updated
  99 + if len(self.docs) == 100 or (len(self.docs) > 0 and diff >= 60):
  100 + # we update each 100 docs or each minutes
  101 + self.couch_db.save_docs(self.docs)
  102 + self.docs = []
  103 +
  104 + if not doc:
  105 + return
  106 + self.docs.append(doc)
  107 + self.last_updated = time.time()
  108 +
  109 + def listen(self):
  110 + while True:
  111 + msg = self.zmq_sock.recv()
  112 + if not msg:
  113 + break
  114 + print "got msg %s" % msg
  115 + gevent.spawn(self.handle_message, msg)
  116 +
  117 + self.alive = False
  118 +
  119 +
  120 +def run():
  121 + usage = "usage: %prog [options]"
  122 + options = [
  123 + make_option("--with-couch", action="store",
  124 + type="string", dest="couch_uri", help="couchdb uri"),
  125 + make_option("--with-redis-host", action="store",
  126 + type="string", dest="redis_host", help="redis host"),
  127 + make_option("--with-redis-port", action="store",
  128 + type="string", dest="redis_port", help="redis port"),
  129 + make_option("--with-redis-db", action="store", type="int",
  130 + dest="redis_db", help="redis db"),
  131 + make_option("--with-zmq", action="store", type="string",
  132 + dest="zmq_uri", help="zmq uri")
  133 +
  134 + ]
  135 + parser = OptionParser(usage=usage, option_list=options)
  136 + opts, args = parser.parse_args()
  137 +
  138 + # settings default here is not needed but while we are here...
  139 + couchdb_uri = opts.couch_uri or "http://127.0.0.1:5984/lqr"
  140 + redis_host = opts.redis_host or "127.0.0.1"
  141 + redis_port = opts.redis_port or 6379
  142 + redis_db = opts.redis_db or 0
  143 + zmq_uri = opts.zmq_uri or "tcp://127.0.0.1:5000"
  144 +
  145 + consumer = Consumer(couch_uri=couchdb_uri, redis_host=redis_host,
  146 + redis_port=redis_port, redis_db=redis_db, zmq_uri=zmq_uri)
  147 +
  148 + try:
  149 + consumer.listen()
  150 + except (KeyboardInterrupt, SystemExit):
  151 + consumer.stop()
  152 + finally:
  153 + consumer.unregister()
  154 +
  155 + sys.exit(0)
  156 +
  157 +if __name__ in ('__main__', 'qrurl.consumer'):
  158 + run()
1,977 qrurl/qrencode.c
... ... @@ -0,0 +1,1977 @@
  1 +/* Generated by Cython 0.14 on Sun Jan 23 16:28:43 2011 */
  2 +
  3 +#define PY_SSIZE_T_CLEAN
  4 +#include "Python.h"
  5 +#ifndef Py_PYTHON_H
  6 + #error Python headers needed to compile C extensions, please install development version of Python.
  7 +#else
  8 +
  9 +#include <stddef.h> /* For offsetof */
  10 +#ifndef offsetof
  11 +#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
  12 +#endif
  13 +
  14 +#if !defined(WIN32) && !defined(MS_WINDOWS)
  15 + #ifndef __stdcall
  16 + #define __stdcall
  17 + #endif
  18 + #ifndef __cdecl
  19 + #define __cdecl
  20 + #endif
  21 + #ifndef __fastcall
  22 + #define __fastcall
  23 + #endif
  24 +#endif
  25 +
  26 +#ifndef DL_IMPORT
  27 + #define DL_IMPORT(t) t
  28 +#endif
  29 +#ifndef DL_EXPORT
  30 + #define DL_EXPORT(t) t
  31 +#endif
  32 +
  33 +#ifndef PY_LONG_LONG
  34 + #define PY_LONG_LONG LONG_LONG
  35 +#endif
  36 +
  37 +#if PY_VERSION_HEX < 0x02040000
  38 + #define METH_COEXIST 0
  39 + #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
  40 + #define PyDict_Contains(d,o) PySequence_Contains(d,o)
  41 +#endif
  42 +
  43 +#if PY_VERSION_HEX < 0x02050000
  44 + typedef int Py_ssize_t;
  45 + #define PY_SSIZE_T_MAX INT_MAX
  46 + #define PY_SSIZE_T_MIN INT_MIN
  47 + #define PY_FORMAT_SIZE_T ""
  48 + #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
  49 + #define PyInt_AsSsize_t(o) PyInt_AsLong(o)
  50 + #define PyNumber_Index(o) PyNumber_Int(o)
  51 + #define PyIndex_Check(o) PyNumber_Check(o)
  52 + #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
  53 +#endif
  54 +
  55 +#if PY_VERSION_HEX < 0x02060000
  56 + #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
  57 + #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
  58 + #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
  59 + #define PyVarObject_HEAD_INIT(type, size) \
  60 + PyObject_HEAD_INIT(type) size,
  61 + #define PyType_Modified(t)
  62 +
  63 + typedef struct {
  64 + void *buf;
  65 + PyObject *obj;
  66 + Py_ssize_t len;
  67 + Py_ssize_t itemsize;
  68 + int readonly;
  69 + int ndim;
  70 + char *format;
  71 + Py_ssize_t *shape;
  72 + Py_ssize_t *strides;
  73 + Py_ssize_t *suboffsets;
  74 + void *internal;
  75 + } Py_buffer;
  76 +
  77 + #define PyBUF_SIMPLE 0
  78 + #define PyBUF_WRITABLE 0x0001
  79 + #define PyBUF_FORMAT 0x0004
  80 + #define PyBUF_ND 0x0008
  81 + #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
  82 + #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
  83 + #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
  84 + #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
  85 + #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
  86 +
  87 +#endif
  88 +
  89 +#if PY_MAJOR_VERSION < 3
  90 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
  91 +#else
  92 + #define __Pyx_BUILTIN_MODULE_NAME "builtins"
  93 +#endif
  94 +
  95 +#if PY_MAJOR_VERSION >= 3
  96 + #define Py_TPFLAGS_CHECKTYPES 0
  97 + #define Py_TPFLAGS_HAVE_INDEX 0
  98 +#endif
  99 +
  100 +#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
  101 + #define Py_TPFLAGS_HAVE_NEWBUFFER 0
  102 +#endif
  103 +
  104 +#if PY_MAJOR_VERSION >= 3
  105 + #define PyBaseString_Type PyUnicode_Type
  106 + #define PyStringObject PyUnicodeObject
  107 + #define PyString_Type PyUnicode_Type
  108 + #define PyString_Check PyUnicode_Check
  109 + #define PyString_CheckExact PyUnicode_CheckExact
  110 +#endif
  111 +
  112 +#if PY_VERSION_HEX < 0x02060000
  113 + #define PyBytesObject PyStringObject
  114 + #define PyBytes_Type PyString_Type
  115 + #define PyBytes_Check PyString_Check
  116 + #define PyBytes_CheckExact PyString_CheckExact
  117 + #define PyBytes_FromString PyString_FromString
  118 + #define PyBytes_FromStringAndSize PyString_FromStringAndSize
  119 + #define PyBytes_FromFormat PyString_FromFormat
  120 + #define PyBytes_DecodeEscape PyString_DecodeEscape
  121 + #define PyBytes_AsString PyString_AsString
  122 + #define PyBytes_AsStringAndSize PyString_AsStringAndSize
  123 + #define PyBytes_Size PyString_Size
  124 + #define PyBytes_AS_STRING PyString_AS_STRING
  125 + #define PyBytes_GET_SIZE PyString_GET_SIZE
  126 + #define PyBytes_Repr PyString_Repr
  127 + #define PyBytes_Concat PyString_Concat
  128 + #define PyBytes_ConcatAndDel PyString_ConcatAndDel
  129 + #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
  130 + #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
  131 +#endif
  132 +
  133 +#ifndef PySet_CheckExact
  134 +# define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
  135 +#endif
  136 +
  137 +#if PY_MAJOR_VERSION >= 3
  138 + #define PyIntObject PyLongObject
  139 + #define PyInt_Type PyLong_Type
  140 + #define PyInt_Check(op) PyLong_Check(op)
  141 + #define PyInt_CheckExact(op) PyLong_CheckExact(op)
  142 + #define PyInt_FromString PyLong_FromString
  143 + #define PyInt_FromUnicode PyLong_FromUnicode
  144 + #define PyInt_FromLong PyLong_FromLong
  145 + #define PyInt_FromSize_t PyLong_FromSize_t
  146 + #define PyInt_FromSsize_t PyLong_FromSsize_t
  147 + #define PyInt_AsLong PyLong_AsLong
  148 + #define PyInt_AS_LONG PyLong_AS_LONG
  149 + #define PyInt_AsSsize_t PyLong_AsSsize_t
  150 + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
  151 + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
  152 +#endif
  153 +
  154 +#if PY_MAJOR_VERSION >= 3
  155 + #define PyBoolObject PyLongObject
  156 +#endif
  157 +
  158 +
  159 +#if PY_MAJOR_VERSION >= 3
  160 + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
  161 + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
  162 +#else
  163 + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
  164 + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
  165 +#endif
  166 +
  167 +#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
  168 + #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
  169 + #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
  170 + #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
  171 +#else
  172 + #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
  173 + (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
  174 + (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
  175 + (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
  176 + #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
  177 + (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
  178 + (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
  179 + (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
  180 + #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
  181 + (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
  182 + (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
  183 + (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
  184 +#endif
  185 +
  186 +#if PY_MAJOR_VERSION >= 3
  187 + #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
  188 +#endif
  189 +
  190 +#if PY_VERSION_HEX < 0x02050000
  191 + #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
  192 + #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
  193 + #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
  194 +#else
  195 + #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
  196 + #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
  197 + #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
  198 +#endif
  199 +
  200 +#if PY_VERSION_HEX < 0x02050000
  201 + #define __Pyx_NAMESTR(n) ((char *)(n))
  202 + #define __Pyx_DOCSTR(n) ((char *)(n))
  203 +#else
  204 + #define __Pyx_NAMESTR(n) (n)
  205 + #define __Pyx_DOCSTR(n) (n)
  206 +#endif
  207 +
  208 +#ifdef __cplusplus
  209 +#define __PYX_EXTERN_C extern "C"
  210 +#else
  211 +#define __PYX_EXTERN_C extern
  212 +#endif
  213 +
  214 +#if defined(WIN32) || defined(MS_WINDOWS)
  215 +#define _USE_MATH_DEFINES
  216 +#endif
  217 +#include <math.h>
  218 +#define __PYX_HAVE_API__qrurl__qrencode
  219 +#include "stdlib.h"
  220 +#include "qrencode.h"
  221 +
  222 +#ifdef PYREX_WITHOUT_ASSERTIONS
  223 +#define CYTHON_WITHOUT_ASSERTIONS
  224 +#endif
  225 +
  226 +
  227 +/* inline attribute */
  228 +#ifndef CYTHON_INLINE
  229 + #if defined(__GNUC__)
  230 + #define CYTHON_INLINE __inline__
  231 + #elif defined(_MSC_VER)
  232 + #define CYTHON_INLINE __inline
  233 + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
  234 + #define CYTHON_INLINE inline
  235 + #else
  236 + #define CYTHON_INLINE
  237 + #endif
  238 +#endif
  239 +
  240 +/* unused attribute */
  241 +#ifndef CYTHON_UNUSED
  242 +# if defined(__GNUC__)
  243 +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
  244 +# define CYTHON_UNUSED __attribute__ ((__unused__))
  245 +# else
  246 +# define CYTHON_UNUSED
  247 +# endif
  248 +# elif defined(__ICC) || defined(__INTEL_COMPILER)
  249 +# define CYTHON_UNUSED __attribute__ ((__unused__))
  250 +# else
  251 +# define CYTHON_UNUSED
  252 +# endif
  253 +#endif
  254 +
  255 +typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
  256 +
  257 +
  258 +/* Type Conversion Predeclarations */
  259 +
  260 +#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
  261 +#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s))
  262 +
  263 +#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
  264 +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
  265 +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
  266 +
  267 +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
  268 +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
  269 +static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
  270 +
  271 +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
  272 +
  273 +
  274 +#ifdef __GNUC__
  275 +/* Test for GCC > 2.95 */
  276 +#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
  277 +#define likely(x) __builtin_expect(!!(x), 1)
  278 +#define unlikely(x) __builtin_expect(!!(x), 0)
  279 +#else /* __GNUC__ > 2 ... */
  280 +#define likely(x) (x)
  281 +#define unlikely(x) (x)
  282 +#endif /* __GNUC__ > 2 ... */
  283 +#else /* __GNUC__ */
  284 +#define likely(x) (x)
  285 +#define unlikely(x) (x)
  286 +#endif /* __GNUC__ */
  287 +
  288 +static PyObject *__pyx_m;
  289 +static PyObject *__pyx_b;
  290 +static PyObject *__pyx_empty_tuple;
  291 +static PyObject *__pyx_empty_bytes;
  292 +static int __pyx_lineno;
  293 +static int __pyx_clineno = 0;
  294 +static const char * __pyx_cfilenm= __FILE__;
  295 +static const char *__pyx_filename;
  296 +
  297 +
  298 +static const char *__pyx_f[] = {
  299 + "qrencode.pyx",
  300 +};
  301 +
  302 +/* Type declarations */
  303 +
  304 +#ifndef CYTHON_REFNANNY
  305 + #define CYTHON_REFNANNY 0
  306 +#endif
  307 +
  308 +#if CYTHON_REFNANNY
  309 + typedef struct {
  310 + void (*INCREF)(void*, PyObject*, int);
  311 + void (*DECREF)(void*, PyObject*, int);
  312 + void (*GOTREF)(void*, PyObject*, int);
  313 + void (*GIVEREF)(void*, PyObject*, int);
  314 + void* (*SetupContext)(const char*, int, const char*);
  315 + void (*FinishContext)(void**);
  316 + } __Pyx_RefNannyAPIStruct;
  317 + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
  318 + static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
  319 + PyObject *m = NULL, *p = NULL;
  320 + void *r = NULL;
  321 + m = PyImport_ImportModule((char *)modname);
  322 + if (!m) goto end;
  323 + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
  324 + if (!p) goto end;
  325 + r = PyLong_AsVoidPtr(p);
  326 + end:
  327 + Py_XDECREF(p);
  328 + Py_XDECREF(m);
  329 + return (__Pyx_RefNannyAPIStruct *)r;
  330 + }
  331 + #define __Pyx_RefNannySetupContext(name) void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
  332 + #define __Pyx_RefNannyFinishContext() __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
  333 + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  334 + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  335 + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  336 + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  337 + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
  338 +#else
  339 + #define __Pyx_RefNannySetupContext(name)
  340 + #define __Pyx_RefNannyFinishContext()
  341 + #define __Pyx_INCREF(r) Py_INCREF(r)
  342 + #define __Pyx_DECREF(r) Py_DECREF(r)
  343 + #define __Pyx_GOTREF(r)
  344 + #define __Pyx_GIVEREF(r)
  345 + #define __Pyx_XDECREF(r) Py_XDECREF(r)
  346 +#endif /* CYTHON_REFNANNY */
  347 +#define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
  348 +#define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
  349 +
  350 +static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
  351 +
  352 +static void __Pyx_RaiseDoubleKeywordsError(
  353 + const char* func_name, PyObject* kw_name); /*proto*/
  354 +
  355 +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
  356 + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
  357 +
  358 +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/
  359 +
  360 +static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
  361 +static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
  362 +
  363 +static CYTHON_INLINE long __Pyx_mod_long(long, long); /* proto */
  364 +
  365 +static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
  366 +
  367 +static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
  368 +
  369 +static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
  370 +
  371 +static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
  372 +
  373 +static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
  374 +
  375 +static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
  376 +
  377 +static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
  378 +
  379 +static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
  380 +
  381 +static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
  382 +
  383 +static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
  384 +
  385 +static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
  386 +
  387 +static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
  388 +
  389 +static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
  390 +
  391 +static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
  392 +
  393 +static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
  394 +
  395 +static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
  396 +
  397 +static void __Pyx_AddTraceback(const char *funcname); /*proto*/
  398 +
  399 +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
  400 +/* Module declarations from libc.stdlib */
  401 +
  402 +/* Module declarations from qrurl.qrencode */
  403 +
  404 +#define __Pyx_MODULE_NAME "qrurl.qrencode"
  405 +int __pyx_module_is_main_qrurl__qrencode = 0;
  406 +
  407 +/* Implementation of qrurl.qrencode */
  408 +static PyObject *__pyx_builtin_range;
  409 +static char __pyx_k_4[] = "\000";
  410 +static char __pyx_k_5[] = "qrurl.qrencode";
  411 +static char __pyx_k__data[] = "data";
  412 +static char __pyx_k__mode[] = "mode";
  413 +static char __pyx_k__level[] = "level";
  414 +static char __pyx_k__range[] = "range";
  415 +static char __pyx_k__width[] = "width";
  416 +static char __pyx_k__append[] = "append";
  417 +static char __pyx_k__encode[] = "encode";
  418 +static char __pyx_k__string[] = "string";
  419 +static char __pyx_k__version[] = "version";
  420 +static char __pyx_k____main__[] = "__main__";
  421 +static char __pyx_k____test__[] = "__test__";
  422 +static char __pyx_k__to_matrix[] = "to_matrix";
  423 +static char __pyx_k__case_sensitive[] = "case_sensitive";
  424 +static PyObject *__pyx_kp_s_4;
  425 +static PyObject *__pyx_n_s_5;
  426 +static PyObject *__pyx_n_s____main__;
  427 +static PyObject *__pyx_n_s____test__;
  428 +static PyObject *__pyx_n_s__append;
  429 +static PyObject *__pyx_n_s__case_sensitive;
  430 +static PyObject *__pyx_n_s__data;
  431 +static PyObject *__pyx_n_s__encode;
  432 +static PyObject *__pyx_n_s__level;
  433 +static PyObject *__pyx_n_s__mode;
  434 +static PyObject *__pyx_n_s__range;
  435 +static PyObject *__pyx_n_s__string;
  436 +static PyObject *__pyx_n_s__to_matrix;
  437 +static PyObject *__pyx_n_s__version;
  438 +static PyObject *__pyx_n_s__width;
  439 +static PyObject *__pyx_int_0;
  440 +static PyObject *__pyx_int_1;
  441 +static PyObject *__pyx_int_5;
  442 +static PyObject *__pyx_k_1;
  443 +static PyObject *__pyx_k_2;
  444 +static PyObject *__pyx_k_3;
  445 +
  446 +/* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":28
  447 + *
  448 + *
  449 + * def encode(char *string, version=5, case_sensitive=True, # <<<<<<<<<<<<<<
  450 + * mode=QR_MODE_8, level=QR_MODE_8):
  451 + * """ create a QR code from a String """
  452 + */
  453 +
  454 +static PyObject *__pyx_pf_5qrurl_8qrencode_0encode(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
  455 +static char __pyx_doc_5qrurl_8qrencode_0encode[] = " create a QR code from a String ";
  456 +static PyMethodDef __pyx_mdef_5qrurl_8qrencode_0encode = {__Pyx_NAMESTR("encode"), (PyCFunction)__pyx_pf_5qrurl_8qrencode_0encode, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_5qrurl_8qrencode_0encode)};
  457 +static PyObject *__pyx_pf_5qrurl_8qrencode_0encode(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  458 + char *__pyx_v_string;
  459 + PyObject *__pyx_v_version = 0;
  460 + PyObject *__pyx_v_case_sensitive = 0;
  461 + PyObject *__pyx_v_mode = 0;
  462 + PyObject *__pyx_v_level = 0;
  463 + QRcode *__pyx_v__qrcode;
  464 + PyObject *__pyx_v_str_copy;
  465 + PyObject *__pyx_v_qrcode;
  466 + PyObject *__pyx_r = NULL;
  467 + PyObject *__pyx_t_1 = NULL;
  468 + char *__pyx_t_2;
  469 + PyObject *__pyx_t_3 = NULL;
  470 + int __pyx_t_4;
  471 + int __pyx_t_5;
  472 + int __pyx_t_6;
  473 + int __pyx_t_7;
  474 + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__string,&__pyx_n_s__version,&__pyx_n_s__case_sensitive,&__pyx_n_s__mode,&__pyx_n_s__level,0};
  475 + __Pyx_RefNannySetupContext("encode");
  476 + __pyx_self = __pyx_self;
  477 + if (unlikely(__pyx_kwds)) {
  478 + Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
  479 + PyObject* values[5] = {0,0,0,0,0};
  480 + values[1] = ((PyObject *)__pyx_int_5);
  481 + values[2] = __pyx_k_1;
  482 + values[3] = __pyx_k_2;
  483 + values[4] = __pyx_k_3;
  484 + switch (PyTuple_GET_SIZE(__pyx_args)) {
  485 + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
  486 + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
  487 + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
  488 + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
  489 + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
  490 + case 0: break;
  491 + default: goto __pyx_L5_argtuple_error;
  492 + }
  493 + switch (PyTuple_GET_SIZE(__pyx_args)) {
  494 + case 0:
  495 + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__string);
  496 + if (likely(values[0])) kw_args--;
  497 + else goto __pyx_L5_argtuple_error;
  498 + case 1:
  499 + if (kw_args > 0) {
  500 + PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__version);
  501 + if (value) { values[1] = value; kw_args--; }
  502 + }
  503 + case 2:
  504 + if (kw_args > 0) {
  505 + PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__case_sensitive);
  506 + if (value) { values[2] = value; kw_args--; }
  507 + }
  508 + case 3:
  509 + if (kw_args > 0) {
  510 + PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__mode);
  511 + if (value) { values[3] = value; kw_args--; }
  512 + }
  513 + case 4:
  514 + if (kw_args > 0) {
  515 + PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__level);
  516 + if (value) { values[4] = value; kw_args--; }
  517 + }
  518 + }
  519 + if (unlikely(kw_args > 0)) {
  520 + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "encode") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  521 + }
  522 + __pyx_v_string = PyBytes_AsString(values[0]); if (unlikely((!__pyx_v_string) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  523 + __pyx_v_version = values[1];
  524 + __pyx_v_case_sensitive = values[2];
  525 + __pyx_v_mode = values[3];
  526 + __pyx_v_level = values[4];
  527 + } else {
  528 + __pyx_v_version = ((PyObject *)__pyx_int_5);
  529 + __pyx_v_case_sensitive = __pyx_k_1;
  530 + __pyx_v_mode = __pyx_k_2;
  531 + __pyx_v_level = __pyx_k_3;
  532 + switch (PyTuple_GET_SIZE(__pyx_args)) {
  533 + case 5: __pyx_v_level = PyTuple_GET_ITEM(__pyx_args, 4);
  534 + case 4: __pyx_v_mode = PyTuple_GET_ITEM(__pyx_args, 3);
  535 + case 3: __pyx_v_case_sensitive = PyTuple_GET_ITEM(__pyx_args, 2);
  536 + case 2: __pyx_v_version = PyTuple_GET_ITEM(__pyx_args, 1);
  537 + case 1: __pyx_v_string = PyBytes_AsString(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((!__pyx_v_string) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  538 + break;
  539 + default: goto __pyx_L5_argtuple_error;
  540 + }
  541 + }
  542 + goto __pyx_L4_argument_unpacking_done;
  543 + __pyx_L5_argtuple_error:;
  544 + __Pyx_RaiseArgtupleInvalid("encode", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  545 + __pyx_L3_error:;
  546 + __Pyx_AddTraceback("qrurl.qrencode.encode");
  547 + __Pyx_RefNannyFinishContext();
  548 + return NULL;
  549 + __pyx_L4_argument_unpacking_done:;
  550 + __pyx_v_str_copy = Py_None; __Pyx_INCREF(Py_None);
  551 + __pyx_v_qrcode = ((PyObject*)Py_None); __Pyx_INCREF(Py_None);
  552 +
  553 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":34
  554 + * cdef QRcode *_qrcode
  555 + *
  556 + * str_copy = string # <<<<<<<<<<<<<<
  557 + * str_copy = str_copy + '\0'
  558 + * try:
  559 + */
  560 + __pyx_t_1 = PyBytes_FromString(__pyx_v_string); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  561 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  562 + __Pyx_DECREF(__pyx_v_str_copy);
  563 + __pyx_v_str_copy = ((PyObject *)__pyx_t_1);
  564 + __pyx_t_1 = 0;
  565 +
  566 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":35
  567 + *
  568 + * str_copy = string
  569 + * str_copy = str_copy + '\0' # <<<<<<<<<<<<<<
  570 + * try:
  571 + * _qrcode = QRcode_encodeString(str_copy, int(version), int(level),
  572 + */
  573 + __pyx_t_1 = PyNumber_Add(__pyx_v_str_copy, ((PyObject *)__pyx_kp_s_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  574 + __Pyx_GOTREF(__pyx_t_1);
  575 + __Pyx_DECREF(__pyx_v_str_copy);
  576 + __pyx_v_str_copy = __pyx_t_1;
  577 + __pyx_t_1 = 0;
  578 +
  579 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":36
  580 + * str_copy = string
  581 + * str_copy = str_copy + '\0'
  582 + * try: # <<<<<<<<<<<<<<
  583 + * _qrcode = QRcode_encodeString(str_copy, int(version), int(level),
  584 + * int(mode), int(case_sensitive))
  585 + */
  586 + /*try:*/ {
  587 +
  588 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":37
  589 + * str_copy = str_copy + '\0'
  590 + * try:
  591 + * _qrcode = QRcode_encodeString(str_copy, int(version), int(level), # <<<<<<<<<<<<<<
  592 + * int(mode), int(case_sensitive))
  593 + * qrcode = dict(
  594 + */
  595 + __pyx_t_2 = PyBytes_AsString(__pyx_v_str_copy); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  596 + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  597 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  598 + __Pyx_INCREF(__pyx_v_version);
  599 + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_version);
  600 + __Pyx_GIVEREF(__pyx_v_version);
  601 + __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  602 + __Pyx_GOTREF(__pyx_t_3);
  603 + __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
  604 + __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  605 + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  606 + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  607 + __Pyx_GOTREF(((PyObject *)__pyx_t_3));
  608 + __Pyx_INCREF(__pyx_v_level);
  609 + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_level);
  610 + __Pyx_GIVEREF(__pyx_v_level);
  611 + __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  612 + __Pyx_GOTREF(__pyx_t_1);
  613 + __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
  614 + __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L7;}
  615 + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  616 +
  617 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":38
  618 + * try:
  619 + * _qrcode = QRcode_encodeString(str_copy, int(version), int(level),
  620 + * int(mode), int(case_sensitive)) # <<<<<<<<<<<<<<
  621 + * qrcode = dict(
  622 + * version = _qrcode.version,
  623 + */
  624 + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  625 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  626 + __Pyx_INCREF(__pyx_v_mode);
  627 + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_mode);
  628 + __Pyx_GIVEREF(__pyx_v_mode);
  629 + __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  630 + __Pyx_GOTREF(__pyx_t_3);
  631 + __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
  632 + __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_3); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  633 + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  634 + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  635 + __Pyx_GOTREF(((PyObject *)__pyx_t_3));
  636 + __Pyx_INCREF(__pyx_v_case_sensitive);
  637 + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_case_sensitive);
  638 + __Pyx_GIVEREF(__pyx_v_case_sensitive);
  639 + __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyInt_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  640 + __Pyx_GOTREF(__pyx_t_1);
  641 + __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
  642 + __pyx_t_7 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L7;}
  643 + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  644 + __pyx_v__qrcode = QRcode_encodeString(__pyx_t_2, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7);
  645 +
  646 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":39
  647 + * _qrcode = QRcode_encodeString(str_copy, int(version), int(level),
  648 + * int(mode), int(case_sensitive))
  649 + * qrcode = dict( # <<<<<<<<<<<<<<
  650 + * version = _qrcode.version,
  651 + * width = _qrcode.width,
  652 + */
  653 + __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L7;}
  654 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  655 +
  656 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":40
  657 + * int(mode), int(case_sensitive))
  658 + * qrcode = dict(
  659 + * version = _qrcode.version, # <<<<<<<<<<<<<<
  660 + * width = _qrcode.width,
  661 + * data = _qrcode.data
  662 + */
  663 + __pyx_t_3 = PyInt_FromLong(__pyx_v__qrcode->version); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L7;}
  664 + __Pyx_GOTREF(__pyx_t_3);
  665 + if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__version), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L7;}
  666 + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  667 +
  668 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":41
  669 + * qrcode = dict(
  670 + * version = _qrcode.version,
  671 + * width = _qrcode.width, # <<<<<<<<<<<<<<
  672 + * data = _qrcode.data
  673 + * )
  674 + */
  675 + __pyx_t_3 = PyInt_FromLong(__pyx_v__qrcode->width); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L7;}
  676 + __Pyx_GOTREF(__pyx_t_3);
  677 + if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__width), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L7;}
  678 + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  679 +
  680 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":42
  681 + * version = _qrcode.version,
  682 + * width = _qrcode.width,
  683 + * data = _qrcode.data # <<<<<<<<<<<<<<
  684 + * )
  685 + * finally:
  686 + */
  687 + __pyx_t_3 = __Pyx_PyBytes_FromUString(__pyx_v__qrcode->data); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L7;}
  688 + __Pyx_GOTREF(((PyObject *)__pyx_t_3));
  689 + if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__data), ((PyObject *)__pyx_t_3)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L7;}
  690 + __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
  691 + __Pyx_DECREF(((PyObject *)__pyx_v_qrcode));
  692 + __pyx_v_qrcode = __pyx_t_1;
  693 + __pyx_t_1 = 0;
  694 + }
  695 +
  696 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":45
  697 + * )
  698 + * finally:
  699 + * free(_qrcode) # <<<<<<<<<<<<<<
  700 + *
  701 + * return qrcode
  702 + */
  703 + /*finally:*/ {
  704 + int __pyx_why;
  705 + PyObject *__pyx_exc_type, *__pyx_exc_value, *__pyx_exc_tb;
  706 + int __pyx_exc_lineno;
  707 + __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
  708 + __pyx_why = 0; goto __pyx_L8;
  709 + __pyx_L7: {
  710 + __pyx_why = 4;
  711 + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  712 + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  713 + __Pyx_ErrFetch(&__pyx_exc_type, &__pyx_exc_value, &__pyx_exc_tb);
  714 + __pyx_exc_lineno = __pyx_lineno;
  715 + goto __pyx_L8;
  716 + }
  717 + __pyx_L8:;
  718 + free(__pyx_v__qrcode);
  719 + switch (__pyx_why) {
  720 + case 4: {
  721 + __Pyx_ErrRestore(__pyx_exc_type, __pyx_exc_value, __pyx_exc_tb);
  722 + __pyx_lineno = __pyx_exc_lineno;
  723 + __pyx_exc_type = 0;
  724 + __pyx_exc_value = 0;
  725 + __pyx_exc_tb = 0;
  726 + goto __pyx_L1_error;
  727 + }
  728 + }
  729 + }
  730 +
  731 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":47
  732 + * free(_qrcode)
  733 + *
  734 + * return qrcode # <<<<<<<<<<<<<<
  735 + *
  736 + * def to_matrix(qrcode):
  737 + */
  738 + __Pyx_XDECREF(__pyx_r);
  739 + __Pyx_INCREF(((PyObject *)__pyx_v_qrcode));
  740 + __pyx_r = ((PyObject *)__pyx_v_qrcode);
  741 + goto __pyx_L0;
  742 +
  743 + __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  744 + goto __pyx_L0;
  745 + __pyx_L1_error:;
  746 + __Pyx_XDECREF(__pyx_t_1);
  747 + __Pyx_XDECREF(__pyx_t_3);
  748 + __Pyx_AddTraceback("qrurl.qrencode.encode");
  749 + __pyx_r = NULL;
  750 + __pyx_L0:;
  751 + __Pyx_DECREF(__pyx_v_str_copy);
  752 + __Pyx_DECREF(__pyx_v_qrcode);
  753 + __Pyx_XGIVEREF(__pyx_r);
  754 + __Pyx_RefNannyFinishContext();
  755 + return __pyx_r;
  756 +}
  757 +
  758 +/* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":49
  759 + * return qrcode
  760 + *
  761 + * def to_matrix(qrcode): # <<<<<<<<<<<<<<
  762 + * """ Convert a QRcode to a matrix of ones and zeros """
  763 + *
  764 + */
  765 +
  766 +static PyObject *__pyx_pf_5qrurl_8qrencode_1to_matrix(PyObject *__pyx_self, PyObject *__pyx_v_qrcode); /*proto*/
  767 +static char __pyx_doc_5qrurl_8qrencode_1to_matrix[] = " Convert a QRcode to a matrix of ones and zeros ";
  768 +static PyMethodDef __pyx_mdef_5qrurl_8qrencode_1to_matrix = {__Pyx_NAMESTR("to_matrix"), (PyCFunction)__pyx_pf_5qrurl_8qrencode_1to_matrix, METH_O, __Pyx_DOCSTR(__pyx_doc_5qrurl_8qrencode_1to_matrix)};
  769 +static PyObject *__pyx_pf_5qrurl_8qrencode_1to_matrix(PyObject *__pyx_self, PyObject *__pyx_v_qrcode) {
  770 + unsigned char *__pyx_v_qdata;
  771 + PyObject *__pyx_v_qwidth;
  772 + PyObject *__pyx_v_matrix;
  773 + PyObject *__pyx_v_y;
  774 + PyObject *__pyx_v_line;
  775 + PyObject *__pyx_v_x;
  776 + PyObject *__pyx_r = NULL;
  777 + PyObject *__pyx_t_1 = NULL;
  778 + unsigned char *__pyx_t_2;
  779 + Py_ssize_t __pyx_t_3;
  780 + PyObject *__pyx_t_4 = NULL;
  781 + Py_ssize_t __pyx_t_5;
  782 + PyObject *__pyx_t_6 = NULL;
  783 + PyObject *__pyx_t_7 = NULL;
  784 + Py_ssize_t __pyx_t_8;
  785 + long __pyx_t_9;
  786 + int __pyx_t_10;
  787 + __Pyx_RefNannySetupContext("to_matrix");
  788 + __pyx_self = __pyx_self;
  789 + __pyx_v_qwidth = Py_None; __Pyx_INCREF(Py_None);
  790 + __pyx_v_matrix = ((PyObject*)Py_None); __Pyx_INCREF(Py_None);
  791 + __pyx_v_y = Py_None; __Pyx_INCREF(Py_None);
  792 + __pyx_v_line = ((PyObject*)Py_None); __Pyx_INCREF(Py_None);
  793 + __pyx_v_x = Py_None; __Pyx_INCREF(Py_None);
  794 +
  795 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":54
  796 + * cdef unsigned char *qdata
  797 + *
  798 + * qwidth = qrcode['width'] # <<<<<<<<<<<<<<
  799 + * qdata = qrcode['data']
  800 + *
  801 + */
  802 + __pyx_t_1 = PyObject_GetItem(__pyx_v_qrcode, ((PyObject *)__pyx_n_s__width)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  803 + __Pyx_GOTREF(__pyx_t_1);
  804 + __Pyx_DECREF(__pyx_v_qwidth);
  805 + __pyx_v_qwidth = __pyx_t_1;
  806 + __pyx_t_1 = 0;
  807 +
  808 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":55
  809 + *
  810 + * qwidth = qrcode['width']
  811 + * qdata = qrcode['data'] # <<<<<<<<<<<<<<
  812 + *
  813 + * # build matrix
  814 + */
  815 + __pyx_t_1 = PyObject_GetItem(__pyx_v_qrcode, ((PyObject *)__pyx_n_s__data)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  816 + __Pyx_GOTREF(__pyx_t_1);
  817 + __pyx_t_2 = __Pyx_PyBytes_AsUString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  818 + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  819 + __pyx_v_qdata = __pyx_t_2;
  820 +
  821 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":58
  822 + *
  823 + * # build matrix
  824 + * matrix = [] # <<<<<<<<<<<<<<
  825 + * for y in range(qwidth):
  826 + * line = []
  827 + */
  828 + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  829 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  830 + __Pyx_DECREF(((PyObject *)__pyx_v_matrix));
  831 + __pyx_v_matrix = __pyx_t_1;
  832 + __pyx_t_1 = 0;
  833 +
  834 + /* "/Users/benoitc/work/qrurl/qrurl/qrurl/qrencode.pyx":59
  835 + * # build matrix
  836 + * matrix = []
  837 + * for y in range(qwidth): # <<<<<<<<<<<<<<
  838 + * line = []
  839 + * for x in range(qwidth):
  840 + */
  841 + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  842 + __Pyx_GOTREF(((PyObject *)__pyx_t_1));
  843 + __Pyx_INCREF(__pyx_v_qwidth);
  844 + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_qwidth);
  845 + __Pyx_GIVEREF(__pyx_v_qwidth);
  846 + __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  847 + __Pyx_GOTREF(__pyx_t_4);
  848 + __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
  849 + if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
  850 + __pyx_t_3 = 0; __pyx_t_1 = __pyx_t_4; __Pyx_INCREF(__pyx_t_1);
  851 + } else {
  852 + __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  853 + __Pyx_GOTREF(__pyx_t_1);
  854 + }
  855 + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  856 + for (;;) {
  857 + if (likely(PyList_CheckExact(__pyx_t_1))) {
  858 + if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
  859 + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++;
  860 + } else if (likely(PyTuple_CheckExact(__pyx_t_1))) {
  861 + if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
  862 + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++;
  863 + } else {
  864 + __pyx_t_4 = PyIter_Next(__pyx_t_1);
  865 + if (!__pyx_t_4) {
  866 + if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  867 + break;
  868 + }
  869 + __Pyx_GOTREF(__pyx_t_4);
  870 + }