<commit_before>import random
import math
from itertools import product
from itertools import chain
from thread_sum import ThreadSum

n = 256
N = 250
#d = 1339324948 #31 bits
d = 265463185775234288092201526257649332892133932494809907679736989141210619872096735078276597605954826202148

#d = 13393249480990767973698914121061987209673507827659760595482620214891467806973397091277092174174393961305025200909026701058146674630543302845868229392185528

#q = 2**252 + 27742317777372353535851937790883648493 #ed25519

#temp = int("8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d", 16)
q = 2^446 + 13818066809895115352007386748515426880336692474882178609894547503885 #Ed448-Goldilocks

window_size = 5
RANDOMIZED_BITS = 128
RANDOMIZE_V_0 = 0
r = []
v = []
alpha = []

def generate_v_values():
    for i in xrange(0, N):
        value = d + (alpha[i]*q)
        v.append(value)

def  generate_alpha_js():
    for i in xrange(1, N+1):
        al = r[i] - r[0]
        alpha.append(int(math.fabs(al)))

def  generate_r_js():
    for i in xrange(0, N+1):
        a = random.getrandbits(n)
        r.append(int(math.fabs(a)))

def bit_flip_fixed(bit_list, nr_of_changes):
    bit_list_t = bit_list[:]
    pos_list = []
    if len(bit_list) < nr_of_changes:
        raise Exception("Randomized bigger then d+(a*r)")
        print "Lenght: ", len(bit_list)
    print "FIXED: ", nr_of_changes
    #position = len(bit_list_t)-1
    for i in xrange(0, nr_of_changes):
        if bit_list_t[i] == 1:
            bit_list_t[i] = 0
        else:
            bit_list_t[i] = 1
        #position = position-1

    return bit_list

def bit_flip_random(bit_list, randomness):
    bit_list_t = bit_list[:]
    pos_list = []
    if len(bit_list) < randomness:
        raise Exception("Randomized bigger then d+(a*r)")
        print "Lenght: ", len(bit_list)
    for i in xrange(0, randomness):
        pos_bit_to_flip = random.randint(0, len(bit_list)-1)
        while(pos_bit_to_flip in pos_list):
            pos_bit_to_flip = random.randint(0, len(bit_list)-1)
        pos_list.append(pos_bit_to_flip)
        if bit_list_t[pos_bit_to_flip] == 1:
            bit_list_t[pos_bit_to_flip] = 0
        else:
            bit_list_t[pos_bit_to_flip] = 1

    return bit_list_t

def generate_v_values_with_bit_flip():
    value = d + (alpha[0]*q)
    bit_list = int_to_bin(value)
    print len(bit_list)
    bit_list_flipped = bit_flip_random(bit_list, RANDOMIZE_V_0)
    value_flipped = bin_to_int(bit_list_flipped)
    v.append(value_flipped)
    for i in xrange(1, N):
        value = d + (alpha[i]*q)
        bit_list = int_to_bin(value)
        #print len(bit_list)
        bit_list_flipped = bit_flip_random(bit_list, RANDOMIZED_BITS)
        value_flipped = bin_to_int(bit_list_flipped)
        v.append(value_flipped)

def int_to_bin(number):
    return [int(x) for x in bin(number)[2:]]

def bin_to_int(bit_list):
    output = 0
    for bit in bit_list:
        output = output * 2 + bit
    return output

def groupsof(n, xs):
    if len(xs) < n:
        return [xs]
    else:
        return chain([xs[0:n]], groupsof(n, xs[n:]))

def sum_all_ds(d_candidates, interval, mod_value):
    pairs = {}
    number_of_threads = 10
    ds = list(groupsof(len(d_candidates)/number_of_threads, d_candidates))
    threads = []
    for i in xrange(0, number_of_threads):
        threads.append(ThreadSum(i, ds[i], v, alpha, N, mod_value, interval))
    for t in threads:
        t.start()
    for t in threads:
        t.join()

    for t in threads:
        key, d = t.return_result()
        try:
            if pairs[key] <> None:
                val = pairs[key]
                if val.count(1) > d.count(1):
                    pairs[key] = d
        except Exception as e:
            pairs[key] = d
    return min(pairs.keys()) , pairs

def test_d(to_test):
    """ Function to test the candidate to d. In our case, it is a comparasion
    with the original d. However, in a real case could be the ciphered text with the original
    and the candidate"""
    return (d==to_test)

def wide_widow_attack():
    generate_r_js()
    generate_alpha_js()
    generate_v_values_with_bit_flip()
    print "d = ",  int_to_bin(d), " len: ", len(int_to_bin(d))
    print "Starting...."
    w_prime = 0
    w = window_size
    d_prime = 0
    variations = []
    for i in product([0,1], repeat=window_size):
        variations.append(list(i))
    while(w < (n + window_size + window_size)):
        print "w: ", w
        print "w_prime: ", w_prime
        mod_value = 2**w
        d_prime = d_prime % mod_value
        d_prime_bin = int_to_bin(d_prime)
        to_iterate = []
        for variation in variations:
            to_iterate.append(variation+d_prime_bin)
        sum_d , d_candidate = sum_all_ds(to_iterate, w, mod_value)
        d_prime = bin_to_int(d_candidate[sum_d])
        print "sum: ", sum_d, " d_candidate = ", int_to_bin(d_prime)
        w_prime = w
        w = w + window_size

        if test_d(d_prime):
            break

    if (d == d_prime):
        print "FOUND KEY."
        return True
    else:
        print "SORRY"
        return False
    print "Finished."

nr_of_attempts = 10
correct = 0
for i in xrange(0,nr_of_attempts):
    if wide_widow_attack():
        correct = correct + 1

print "Correct: ", correct, " of ", nr_of_attempts
<commit_msg>revise the code please!<commit_after>import random
import math
from itertools import product
from itertools import chain
from thread_sum import ThreadSum

n = 1024
N = 500
d = 12339324948 #31 bits
#d = 2654631857752342880925764945
#d = 265463185775234288092201526257649332892133932494809907679736989141210619872096735078276597605954826202148

#d = 13393249480990767973698914121061987209673507827659760595482620214891467806973397091277092174174393961305025200909026701058146674630543302845868229392185528

q = 2**252 + 27742317777372353535851937790883648493 #ed25519

#temp = int("8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d", 16)
#q = 2^446 + 13818066809895115352007386748515426880336692474882178609894547503885 #Ed448-Goldilocks

window_size = 10
RANDOMIZED_BITS = 20
RANDOMIZE_V_0 = 5
r = []
v = []
alpha = []

def generate_v_values():
    for i in xrange(0, N):
        value = d + (alpha[i]*q)
        v.append(value)

def  generate_alpha_js():
    for i in xrange(1, N+1):
        al = r[i] - r[0]
        alpha.append(int(math.fabs(al)))

def  generate_r_js():
    for i in xrange(0, N+1):
        a = random.getrandbits(n)
        r.append(int(math.fabs(a)))

def bit_flip_fixed(bit_list, nr_of_changes):
    bit_list_t = bit_list[:]
    pos_list = []
    if len(bit_list) < nr_of_changes:
        raise Exception("Randomized bigger then d+(a*r)")
        print "Lenght: ", len(bit_list)
    print "FIXED: ", nr_of_changes
    #position = len(bit_list_t)-1
    for i in xrange(0, nr_of_changes):
        if bit_list_t[i] == 1:
            bit_list_t[i] = 0
        else:
            bit_list_t[i] = 1
        #position = position-1

    return bit_list

def bit_flip_random(bit_list, randomness):
    bit_list_t = bit_list[:]
    pos_list = []
    if len(bit_list) < randomness:
        raise Exception("Randomized bigger then d+(a*r)")
        print "Lenght: ", len(bit_list)
    for i in xrange(0, randomness):
        pos_bit_to_flip = random.randint(0, len(bit_list)-1)
        while(pos_bit_to_flip in pos_list):
            pos_bit_to_flip = random.randint(0, len(bit_list)-1)
        pos_list.append(pos_bit_to_flip)
        if bit_list_t[pos_bit_to_flip] == 1:
            bit_list_t[pos_bit_to_flip] = 0
        else:
            bit_list_t[pos_bit_to_flip] = 1

    return bit_list_t

def generate_v_values_with_bit_flip():
    value = d + (alpha[0]*q)
    bit_list = int_to_bin(value)
    bit_list_flipped = bit_flip_random(bit_list, RANDOMIZE_V_0)
    value_flipped = bin_to_int(bit_list_flipped)
    v.append(value_flipped)
    for i in xrange(1, N):
        value = d + (alpha[i]*q)
        bit_list = int_to_bin(value)
        #print len(bit_list)
        bit_list_flipped = bit_flip_random(bit_list, RANDOMIZED_BITS)
        value_flipped = bin_to_int(bit_list_flipped)
        v.append(value_flipped)

def int_to_bin(number):
    return [int(x) for x in bin(number)[2:]]

def bin_to_int(bit_list):
    output = 0
    for bit in bit_list:
        output = output * 2 + bit
    return output

def groupsof(n, xs):
    if len(xs) < n:
        return [xs]
    else:
        return chain([xs[0:n]], groupsof(n, xs[n:]))

def sum_all_ds(d_candidates, interval, mod_value):
    pairs = {}
    number_of_threads = 15
    ds = list(groupsof(len(d_candidates)/number_of_threads, d_candidates))
    threads = []
    for i in xrange(0, number_of_threads):
        threads.append(ThreadSum(i, ds[i], v, alpha, N, mod_value, interval))
    for t in threads:
        t.start()
    for t in threads:
        t.join()

    for t in threads:
        key, d = t.return_result()
        try:
            if pairs[key] <> None:
                val = pairs[key]
                if val.count(1) > d.count(1):
                    pairs[key] = d
        except Exception as e:
            pairs[key] = d
    return min(pairs.keys()) , pairs

def test_d(to_test):
    """ Function to test the candidate to d. In our case, it is a comparasion
    with the original d. However, in a real case could be the ciphered text with the original
    and the candidate"""
    return (d==to_test)

def wide_widow_attack():
    generate_r_js()
    generate_alpha_js()
    generate_v_values_with_bit_flip()
    print "d = ",  int_to_bin(d), " len: ", len(int_to_bin(d))
    print "Starting...."
    w_prime = 0
    w = window_size
    d_prime = 0
    variations = []
    for i in product([0,1], repeat=window_size):
        variations.append(list(i))
    while(w < (n + window_size + window_size)):
        print "w: ", w
        print "w_prime: ", w_prime
        mod_value = 2**w
        d_prime = d_prime % mod_value
        d_prime_bin = int_to_bin(d_prime)
        to_iterate = []
        for variation in variations:
            to_iterate.append(variation+d_prime_bin)
        sum_d , d_candidate = sum_all_ds(to_iterate, w, mod_value)
        d_prime = bin_to_int(d_candidate[sum_d])
        print "sum: ", sum_d, " d_candidate = ", int_to_bin(d_prime)
        w_prime = w
        w = w + window_size

        if test_d(d_prime):
            break

    if (d == d_prime):
        print "FOUND KEY."
        return True
    else:
        print "SORRY"
        return False
    print "Finished."

nr_of_attempts = 10
correct = 0
for i in xrange(0,nr_of_attempts):
    if wide_widow_attack():
        correct = correct + 1

print "Correct: ", correct, " of ", nr_of_attempts
<|endoftext|>


<commit_before># Copyright (c) 2016 Cisco Systems, Inc.
#
#  Permission is hereby granted, free of charge, to any person obtaining a copy
#  of this software and associated documentation files (the "Software"), to
#  deal in the Software without restriction, including without limitation the
#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
#  sell copies of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be included in
#  all copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#  DEALINGS IN THE SOFTWARE.

import os

import click
import click_completion
import fasteners

import gilt
from gilt import config
from gilt import git
from gilt import util

click_completion.init()

class NotFoundError(Exception):
    """Error raised when a config can not be found. """

    pass

@click.group()
@click.option(
    "--config",
    default="gilt.yml",
    help="Path to config file.  Default gilt.yml",
)
@click.option(
    "--debug/--no-debug",
    default=False,
    help="Enable or disable debug mode. Default is disabled.",
)
@click.version_option(version=gilt.__version__)
@click.pass_context
def main(ctx, config, debug):  # pragma: no cover
    """
    \b
           o  o
         o |  |
    o--o   | -o-
    |  | | |  |
    o--O | o  o
       |
    o--o

    gilt - A GIT layering tool.

    Enable autocomplete issue:

    eval "$(_GILT_COMPLETE=source gilt)"
    """  # noqa: H404,H405
    ctx.obj = {}
    ctx.obj["args"] = {}
    ctx.obj["args"]["debug"] = debug
    ctx.obj["args"]["config"] = config

@click.command()
@click.pass_context
def overlay(ctx):  # pragma: no cover
    """Install gilt dependencies """
    args = ctx.obj.get("args")
    filename = args.get("config")
    debug = args.get("debug")
    _setup(filename)

    for c in config.config(filename):
        with fasteners.InterProcessLock(c.lock_file):
            util.print_info("{}:".format(c.name))
            if not os.path.exists(c.src):
                git.clone(c.name, c.git, c.src, debug=debug)
            if c.dst:
                git.extract(c.src, c.dst, c.version, debug=debug)
                post_commands = {c.dst: c.post_commands}
            else:
                git.overlay(c.src, c.files, c.version, debug=debug)
                post_commands = {
                    conf.dst: conf.post_commands for conf in c.files
                }
            # Run post commands if any.
            for dst, commands in post_commands.items():
                for command in commands:
                    msg = "  - running `{}` in {}".format(command, dst)
                    util.print_info(msg)
                    cmd = util.build_sh_cmd(command, cwd=dst)
                    util.run_command(cmd, debug=debug)

def _setup(filename):
    if not os.path.exists(filename):
        msg = "Unable to find {}. Exiting.".format(filename)
        raise NotFoundError(msg)

    working_dirs = [config._get_lock_dir(), config._get_clone_dir()]
    for working_dir in working_dirs:
        if not os.path.exists(working_dir):
            os.makedirs(working_dir)

main.add_command(overlay)
<commit_msg>Allow click to attempt file open (#89)<commit_after># Copyright (c) 2016 Cisco Systems, Inc.
#
#  Permission is hereby granted, free of charge, to any person obtaining a copy
#  of this software and associated documentation files (the "Software"), to
#  deal in the Software without restriction, including without limitation the
#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
#  sell copies of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be included in
#  all copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#  DEALINGS IN THE SOFTWARE.

import os

import click
import click_completion
import fasteners

import gilt
from gilt import config
from gilt import git
from gilt import util

click_completion.init()

class NotFoundError(Exception):
    """Error raised when a config can not be found. """

    pass

@click.group()
@click.option(
    "--config",
    default="gilt.yml",
    help="Path to config file.  Default gilt.yml",
    type=click.File('r'),
)
@click.option(
    "--debug/--no-debug",
    default=False,
    help="Enable or disable debug mode. Default is disabled.",
)
@click.version_option(version=gilt.__version__)
@click.pass_context
def main(ctx, config, debug):  # pragma: no cover
    """
    \b
           o  o
         o |  |
    o--o   | -o-
    |  | | |  |
    o--O | o  o
       |
    o--o

    gilt - A GIT layering tool.

    Enable autocomplete issue:

    eval "$(_GILT_COMPLETE=source gilt)"
    """  # noqa: H404,H405
    ctx.obj = {}
    ctx.obj["args"] = {}
    ctx.obj["args"]["debug"] = debug
    ctx.obj["args"]["config"] = config.name

@click.command()
@click.pass_context
def overlay(ctx):  # pragma: no cover
    """Install gilt dependencies """
    args = ctx.obj.get("args")
    filename = args.get("config")
    debug = args.get("debug")
    _setup(filename)

    for c in config.config(filename):
        with fasteners.InterProcessLock(c.lock_file):
            util.print_info("{}:".format(c.name))
            if not os.path.exists(c.src):
                git.clone(c.name, c.git, c.src, debug=debug)
            if c.dst:
                git.extract(c.src, c.dst, c.version, debug=debug)
                post_commands = {c.dst: c.post_commands}
            else:
                git.overlay(c.src, c.files, c.version, debug=debug)
                post_commands = {
                    conf.dst: conf.post_commands for conf in c.files
                }
            # Run post commands if any.
            for dst, commands in post_commands.items():
                for command in commands:
                    msg = "  - running `{}` in {}".format(command, dst)
                    util.print_info(msg)
                    cmd = util.build_sh_cmd(command, cwd=dst)
                    util.run_command(cmd, debug=debug)

def _setup(filename):
    if not os.path.exists(filename):
        msg = "Unable to find {}. Exiting.".format(filename)
        raise NotFoundError(msg)

    working_dirs = [config._get_lock_dir(), config._get_clone_dir()]
    for working_dir in working_dirs:
        if not os.path.exists(working_dir):
            os.makedirs(working_dir)

main.add_command(overlay)
<|endoftext|>


<commit_before>__version__ = '0.12.1'
<commit_msg>Bump patch version for minor change.<commit_after>__version__ = '0.12.2'
<|endoftext|>


<commit_before>from textwrap import dedent
import pytest
from jupytext.myst import myst_to_notebook, CODE_DIRECTIVE, MystMetadataParsingError

def test_bad_notebook_metadata():
    """Test exception raised if notebook metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            ---
            {{a
            ---
            """
            )
        )

def test_bad_code_metadata():
    """Test exception raised if cell metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            ```{{{0}}}
            ---
            {{a
            ---
            ```
            """
            ).format(CODE_DIRECTIVE)
        )

def test_bad_markdown_metadata():
    """Test exception raised if markdown metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            +++ {{a
            """
            )
        )

def test_bad_markdown_metadata2():
    """Test exception raised if markdown metadata is not a dict."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            +++ [1, 2]
            """
            )
        )
<commit_msg>fix python 3.5 tests<commit_after>from textwrap import dedent
import pytest
from jupytext.myst import myst_to_notebook, CODE_DIRECTIVE, MystMetadataParsingError
from .utils import requires_myst

@requires_myst
def test_bad_notebook_metadata():
    """Test exception raised if notebook metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            ---
            {{a
            ---
            """
            )
        )

@requires_myst
def test_bad_code_metadata():
    """Test exception raised if cell metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            ```{{{0}}}
            ---
            {{a
            ---
            ```
            """
            ).format(CODE_DIRECTIVE)
        )

@requires_myst
def test_bad_markdown_metadata():
    """Test exception raised if markdown metadata cannot be parsed."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            +++ {{a
            """
            )
        )

@requires_myst
def test_bad_markdown_metadata2():
    """Test exception raised if markdown metadata is not a dict."""
    with pytest.raises(MystMetadataParsingError):
        myst_to_notebook(
            dedent(
                """\
            +++ [1, 2]
            """
            )
        )
<|endoftext|>


<commit_before>#######################################################################
# This file is part of PyBlosxom.
#
# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Will Kahn-Greene
#
# PyBlosxom is distributed under the MIT license.  See the file
# LICENSE for distribution details.
#######################################################################

"""
Summary
=======

Walks through your blog root figuring out all the available years for
the archives list.  It stores the years with links to year summaries
in the variable ``$archivelinks``.  You should put this variable in either
your head or foot template.

Usage
=====

When the user clicks on one of the year links (i.e. http://base_url/2004/),
then yeararchives will display a summary page for that year.  The summary is
generated using the ``yearsummarystory.html`` template for each month in the
year.  Mine is::

   $title

   $body

I don't have anything configurable in ``config.py``--so you'll have to
edit the html stuff directly in the plugin.  If you dislike this, please
take some time to fix it and send me a diff and I'll make the adjustments.
"""
__author__ = "Will Kahn-Greene - willg at bluesock dot org"
__version__ = "2010-05-08"
__url__ = "http://pyblosxom.sourceforge.net/"
__description__ = "Year-based archives handler."

from Pyblosxom import tools, entries
import time, os

def verify_installation(request):
    return 1

class YearArchives:
    def __init__(self, request):
        self._request = request
        self._archives = None
        self._items = None

    def __str__(self):
        if self._archives == None:
            self.gen_linear_archive()
        return self._archives

    def gen_linear_archive(self):
        config = self._request.get_configuration()
        data = self._request.get_data()
        root = config["datadir"]
        baseurl = config.get("base_url", "")

        archives = {}
        archive_list = tools.walk(self._request, root)
        items = []

        flavour = data.get(
            "flavour", config.get("default_flavour", "html"))

        for mem in archive_list:
            timetuple = tools.filestat(self._request, mem)

            y = time.strftime("%Y", timetuple)
            m = time.strftime("%m", timetuple)
            d = time.strftime("%d", timetuple)
            l = "%s
" % (baseurl, y, flavour, y)

            if not archives.has_key(y):
                archives[y] = l
            items.append(["%s-%s" % (y, m), "%s-%s-%s" % (y, m, d),
                          time.mktime(timetuple), mem])

        arc_keys = archives.keys()
        arc_keys.sort()
        arc_keys.reverse()

        result = []
        for key in arc_keys:
            result.append(archives[key])
        self._archives = '\n'.join(result)
        self._items = items

def new_entry(request, yearmonth, body):
    """
    Takes a bunch of variables and generates an entry out of it.  It
    creates a timestamp so that conditionalhttp can handle it without
    getting all fussy.
    """
    entry = entries.base.EntryBase(request)

    entry['title'] = yearmonth
    entry['filename'] = yearmonth + "/summary"
    entry['file_path'] = yearmonth
    entry._id = yearmonth + "::summary"

    entry["template_name"] = "yearsummarystory"
    entry["nocomments"] = "yes"

    entry["absolute_path"] = ""
    entry["fn"] = ""

    entry.set_time(time.strptime(yearmonth, "%Y-%m"))
    entry.set_data(body)

    return entry

INIT_KEY = "yeararchives_initiated"

def cb_prepare(args):
    request = args["request"]
    data = request.get_data()
    data["archivelinks"] = YearArchives(request)

def cb_date_head(args):
    request = args["request"]
    data = request.get_data()

    if data.has_key(INIT_KEY):
        args["template"] = ""
    return args

def parse_path_info(path):
    """Returns None or (year, flav) tuple.

    Handles urls of this type:

    - /2003
    - /2003/
    - /2003/index
    - /2003/index.flav
    """
    path = path.split("/")
    path = [m for m in path if m]
    if not path:
        return

    year = path[0]
    if not year.isdigit() or not len(year) == 4:
        return

    if len(path) == 1:
        return (year, None)

    if len(path) == 2 and path[1].startswith("index"):
        flav = None
        if "." in path[1]:
            flav = path[1].split(".", 1)[1]
        return (year, flav)

    return

def cb_filelist(args):
    request = args["request"]
    pyhttp = request.get_http()
    data = request.get_data()
    config = request.get_configuration()
    baseurl = config.get("base_url", "")

    path = pyhttp["PATH_INFO"]

    ret = parse_path_info(path)
    if ret == None:
        return

    # note: returned flavour is None if there is no .flav appendix
    year, flavour = ret

    data[INIT_KEY] = 1

    # get all the entries
    wa = YearArchives(request)
    wa.gen_linear_archive()
    items = wa._items

    # peel off the items for this year
    items = [m for m in items if m[0].startswith(year)]

    items.sort()
    items.reverse()

    # Set and use current (or default) flavour for permalinks
    if not flavour:
        flavour = data.get(
            "flavour", config.get("default_flavour", "html"))

    data["flavour"] = flavour

    l = ("(%(path)s) %(title)s
")
    e = "
\n%s	\n%s
\n"
    d = ""
    m = ""

    day = []
    month = []
    entrylist = []

    for mem in items:
        if not m:
            m = mem[0]
        if not d:
            d = mem[1]

        if m != mem[0]:
            month.append(e % (d, "\n".join(day)))
            entrylist.append(new_entry(request, m, "\n".join(month)))
            m = mem[0]
            d = mem[1]
            day = []
            month = []

        elif d != mem[1]:
            month.append(e % (d, "\n".join(day)))
            d = mem[1]
            day = []
        entry = entries.fileentry.FileEntry(
            request, mem[3], config['datadir'])
        day.append(l % entry)

    if day:
        month.append(e % (d, "\n".join(day)))
    if month:
        entrylist.append(new_entry(request, m, "\n".join(month)))

    return entrylist
<commit_msg>Allow people to change links with archive_template config variable.<commit_after>#######################################################################
# This file is part of PyBlosxom.
#
# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Will Kahn-Greene
#
# PyBlosxom is distributed under the MIT license.  See the file
# LICENSE for distribution details.
#######################################################################

"""
Summary
=======

Walks through your blog root figuring out all the available years for
the archives list.  It stores the years with links to year summaries
in the variable ``$archivelinks``.  You should put this variable in either
your head or foot template.

Usage
=====

When the user clicks on one of the year links (i.e. http://base_url/2004/),
then yeararchives will display a summary page for that year.  The summary is
generated using the ``yearsummarystory.html`` template for each month in the
year.  Mine is::

   $title

   $body

The ``$(archivelinks)`` link can be configured with the
``archive_template`` config variable.

Example::

    py['archive_template'] = '%(Y)ss
'

The vars available with typical example values are::

    b      short month    ex: 'Jun'
    m      month number   ex: '6'
    Y      4-digit year   ex: '1978'
    y      2-digit year   ex: '78'
    f      the flavour    ex: 'html'

"""
__author__ = "Will Kahn-Greene - willg at bluesock dot org"
__version__ = "2010-05-08"
__url__ = "http://pyblosxom.sourceforge.net/"
__description__ = "Year-based archives handler."

from Pyblosxom import tools, entries
import time, os

def verify_installation(request):
    config = request.get_configuration()
    if not config.has_key("archive_template"):
        print "missing optional config property 'archive_template' which "
        print "allows you to specify how the archive links are created.  "
        print "refer to yeararchives plugin documentation for more details."
    return 1

class YearArchives:
    def __init__(self, request):
        self._request = request
        self._archives = None
        self._items = None

    def __str__(self):
        if self._archives == None:
            self.gen_linear_archive()
        return self._archives

    def gen_linear_archive(self):
        config = self._request.get_configuration()
        data = self._request.get_data()
        root = config["datadir"]
        baseurl = config.get("base_url", "")

        archives = {}
        archive_list = tools.walk(self._request, root)
        items = []

        fulldict = {}
        fulldict.update(config)
        fulldict.update(data)

        flavour = data.get(
            "flavour", config.get("default_flavour", "html"))

        template = config.get(
            'archive_template',
            '%(Y)s
')

        for mem in archive_list:
            timetuple = tools.filestat(self._request, mem)

            timedict = {}
            for x in ["B", "b", "m", "Y", "y", "d"]:
                timedict[x] = time.strftime("%" + x, timetuple)

            fulldict.update(timedict)
            fulldict["f"] = flavour
            year = fulldict["Y"]

            if not archives.has_key(year):
                archives[year] = template % fulldict
            items.append(
                ["%(Y)s-%(m)s" % fulldict,
                 "%(Y)s-%(m)s-%(d)s" % fulldict,
                 time.mktime(timetuple),
                 mem])

        arc_keys = archives.keys()
        arc_keys.sort()
        arc_keys.reverse()

        result = []
        for key in arc_keys:
            result.append(archives[key])
        self._archives = '\n'.join(result)
        self._items = items

def new_entry(request, yearmonth, body):
    """
    Takes a bunch of variables and generates an entry out of it.  It
    creates a timestamp so that conditionalhttp can handle it without
    getting all fussy.
    """
    entry = entries.base.EntryBase(request)

    entry['title'] = yearmonth
    entry['filename'] = yearmonth + "/summary"
    entry['file_path'] = yearmonth
    entry._id = yearmonth + "::summary"

    entry["template_name"] = "yearsummarystory"
    entry["nocomments"] = "yes"

    entry["absolute_path"] = ""
    entry["fn"] = ""

    entry.set_time(time.strptime(yearmonth, "%Y-%m"))
    entry.set_data(body)

    return entry

INIT_KEY = "yeararchives_initiated"

def cb_prepare(args):
    request = args["request"]
    data = request.get_data()
    data["archivelinks"] = YearArchives(request)

def cb_date_head(args):
    request = args["request"]
    data = request.get_data()

    if data.has_key(INIT_KEY):
        args["template"] = ""
    return args

def parse_path_info(path):
    """Returns None or (year, flav) tuple.

    Handles urls of this type:

    - /2003
    - /2003/
    - /2003/index
    - /2003/index.flav
    """
    path = path.split("/")
    path = [m for m in path if m]
    if not path:
        return

    year = path[0]
    if not year.isdigit() or not len(year) == 4:
        return

    if len(path) == 1:
        return (year, None)

    if len(path) == 2 and path[1].startswith("index"):
        flav = None
        if "." in path[1]:
            flav = path[1].split(".", 1)[1]
        return (year, flav)

    return

def cb_filelist(args):
    request = args["request"]
    pyhttp = request.get_http()
    data = request.get_data()
    config = request.get_configuration()
    baseurl = config.get("base_url", "")

    path = pyhttp["PATH_INFO"]

    ret = parse_path_info(path)
    if ret == None:
        return

    # note: returned flavour is None if there is no .flav appendix
    year, flavour = ret

    data[INIT_KEY] = 1

    # get all the entries
    wa = YearArchives(request)
    wa.gen_linear_archive()
    items = wa._items

    # peel off the items for this year
    items = [m for m in items if m[0].startswith(year)]

    items.sort()
    items.reverse()

    # Set and use current (or default) flavour for permalinks
    if not flavour:
        flavour = data.get(
            "flavour", config.get("default_flavour", "html"))

    data["flavour"] = flavour

    l = ("(%(path)s) %(title)s
")
    e = "
\n%s	\n%s
\n"
    d = ""
    m = ""

    day = []
    month = []
    entrylist = []

    for mem in items:
        if not m:
            m = mem[0]
        if not d:
            d = mem[1]

        if m != mem[0]:
            month.append(e % (d, "\n".join(day)))
            entrylist.append(new_entry(request, m, "\n".join(month)))
            m = mem[0]
            d = mem[1]
            day = []
            month = []

        elif d != mem[1]:
            month.append(e % (d, "\n".join(day)))
            d = mem[1]
            day = []
        entry = entries.fileentry.FileEntry(
            request, mem[3], config['datadir'])
        day.append(l % entry)

    if day:
        month.append(e % (d, "\n".join(day)))
    if month:
        entrylist.append(new_entry(request, m, "\n".join(month)))

    return entrylist
<|endoftext|>


<commit_before>#!/usr/local/bin/python3 -u
__author__    = 'Oliver Ratzesberger <https://github.com/fxstein>'
__copyright__ = 'Copyright (C) 2015 Oliver Ratzesberger'
__license__   = 'Apache License, Version 2.0'

# Make sure we have access to SentientHome commons
import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__))  + '/..')

# Sentient Home configuration
from common.shconfig import shConfig
from common.shutil import flatten_dict
from common.sheventhandler import shEventHandler

# Add path to submodule dependencies.ISYlib-python
sys.path.append(os.path.dirname(os.path.abspath(__file__))  + '/../dependencies/ISYlib-python')
from ISY.IsyEvent import ISYEvent

import logging as log

config = shConfig('~/.config/home/home.cfg', name='Universal Devices ISY994')
handler = shEventHandler(config)

# Realtime event feeder
def eventFeed(*arg):

    # Flatten dict and turned ebeded structure into dot notation
    data = flatten_dict(arg[0])

    event = [{
        'name': 'isy',
        'columns': list(data.keys()),
        'points': [ list(data.values()) ]
    }]

    log.debug('Event data: %s', event)

    handler.postEvent(event)

    # Reload config if modified - self limited to once every 10s+
    config.reloadModifiedConfig()

# Setup ISY socket listener
# Be aware: Even though we are able to update the config at runtime
# we do not take down the web socket subscription once established
server = ISYEvent()

retries = 0

while True:
    try:
        server.subscribe(addr=config.get('isy', 'isy_addr'),\
                         userl=config.get('isy', 'isy_user'),\
                         userp=config.get('isy', 'isy_pass'))
        break
    except Exception:
        retries += 1

        log.warn('Cannot connect to ISY. Attempt %n of %n',\
                        retries, config.retries)

        if retries >= config.retries:
            log.Error('Unable to connect to ISY. Exiting...')
            raise

        # Wait for the next poll intervall until we retry
        # also allows for configuration to get updated
        handler.sleep()
        continue

server.set_process_func(eventFeed, "")

try:
    print('Use Control-C to exit')
    server.events_loop()   #no return
except KeyboardInterrupt:
    log.info('Exiting...')
<commit_msg>Fix minor typo<commit_after>#!/usr/local/bin/python3 -u
__author__    = 'Oliver Ratzesberger <https://github.com/fxstein>'
__copyright__ = 'Copyright (C) 2015 Oliver Ratzesberger'
__license__   = 'Apache License, Version 2.0'

# Make sure we have access to SentientHome commons
import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__))  + '/..')

# Sentient Home configuration
from common.shconfig import shConfig
from common.shutil import flatten_dict
from common.sheventhandler import shEventHandler

# Add path to submodule dependencies.ISYlib-python
sys.path.append(os.path.dirname(os.path.abspath(__file__))  + '/../dependencies/ISYlib-python')
from ISY.IsyEvent import ISYEvent

import logging as log

config = shConfig('~/.config/home/home.cfg', name='Universal Devices ISY994')
handler = shEventHandler(config)

# Realtime event feeder
def eventFeed(*arg):

    # Flatten dict and turn embedded structure into dot notation
    data = flatten_dict(arg[0])

    event = [{
        'name': 'isy',
        'columns': list(data.keys()),
        'points': [ list(data.values()) ]
    }]

    log.debug('Event data: %s', event)

    handler.postEvent(event)

    # Reload config if modified - self limited to once every 10s+
    config.reloadModifiedConfig()

# Setup ISY socket listener
# Be aware: Even though we are able to update the config at runtime
# we do not take down the web socket subscription once established
server = ISYEvent()

retries = 0

while True:
    try:
        server.subscribe(addr=config.get('isy', 'isy_addr'),\
                         userl=config.get('isy', 'isy_user'),\
                         userp=config.get('isy', 'isy_pass'))
        break
    except Exception:
        retries += 1

        log.warn('Cannot connect to ISY. Attempt %n of %n',\
                        retries, config.retries)

        if retries >= config.retries:
            log.Error('Unable to connect to ISY. Exiting...')
            raise

        # Wait for the next poll intervall until we retry
        # also allows for configuration to get updated
        handler.sleep()
        continue

server.set_process_func(eventFeed, "")

try:
    print('Use Control-C to exit')
    server.events_loop()   #no return
except KeyboardInterrupt:
    log.info('Exiting...')
<|endoftext|>


<commit_before># Copyright 2014 Ahmed H. Ismail

#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at

#        http://www.apache.org/licenses/LICENSE-2.0

#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

class FileType(object):
    SOURCE = 1
    BINARY = 2
    ARCHIVE = 3
    OTHER = 4

class File(object):
    """Representation of SPDX file.
    Fields:
    name - File name, str mandatory one.
    comment - File comment str, Optional zero or one.
    type - one of FileType.SOURCE, FileType.BINARY, FileType.ARCHIVE
    and FileType.OTHER, optional zero or one.
    chk_sum - SHA1, Mandatory one.
    conc_lics - Mandatory one.
    licenses_in_file - list of licenses found in file, mandatory one or more.
    license_comment - Optional.
    copyright - Copyright text, Mandatory one. NoAssert or None or str.
    notice - optional One.
    contributers - List of strings.
    dependencies - list of file locations.
    artifact_of_project_name - list of project names
    """
    def __init__(self, name):
        super(File, self).__init__()
        self.name = name
        self.comment = None
        self.type = None
        self.chk_sum = None
        self.conc_lics = None
        self.licenses_in_file = []
        self.license_comment = None
        self.copyright = None
        self.notice = None
        self.contributers = []
        self.dependencies = []
        self.artifact_of_project_name = []
        self.artifact_of_project_home = []
        self.artifact_of_project_uri = []<commit_msg>Reformats file.py to conform to pep 8<commit_after># Copyright 2014 Ahmed H. Ismail

#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at

#        http://www.apache.org/licenses/LICENSE-2.0

#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

class FileType(object):
    SOURCE = 1
    BINARY = 2
    ARCHIVE = 3
    OTHER = 4

class File(object):

    """Representation of SPDX file.
    Fields:
    name - File name, str mandatory one.
    comment - File comment str, Optional zero or one.
    type - one of FileType.SOURCE, FileType.BINARY, FileType.ARCHIVE
    and FileType.OTHER, optional zero or one.
    chk_sum - SHA1, Mandatory one.
    conc_lics - Mandatory one.
    licenses_in_file - list of licenses found in file, mandatory one or more.
    license_comment - Optional.
    copyright - Copyright text, Mandatory one. NoAssert or None or str.
    notice - optional One.
    contributers - List of strings.
    dependencies - list of file locations.
    artifact_of_project_name - list of project names
    """

    def __init__(self, name):
        super(File, self).__init__()
        self.name = name
        self.comment = None
        self.type = None
        self.chk_sum = None
        self.conc_lics = None
        self.licenses_in_file = []
        self.license_comment = None
        self.copyright = None
        self.notice = None
        self.contributers = []
        self.dependencies = []
        self.artifact_of_project_name = []
        self.artifact_of_project_home = []
        self.artifact_of_project_uri = []
<|endoftext|>


<commit_before>import bokeh.core.enums as enums

def test_Enumeration_default():
    e = enums.Enumeration()
    assert e.__slots__ == ()

def test_enumeration_basic():
    e = enums.enumeration("foo", "bar", "baz")
    assert isinstance(e, enums.Enumeration)
    assert str(e) == "Enumeration(foo, bar, baz)"
    assert [x for x in e] == ["foo", "bar", "baz"]
    for x in ["foo", "bar", "baz"]:
        assert x in e
    assert "junk" not in e

def test_enumeration_case():
    e = enums.enumeration("foo", "bar", "baz", case_sensitive=False)
    assert isinstance(e, enums.Enumeration)
    assert str(e) == "Enumeration(foo, bar, baz)"
    assert [x for x in e] == ["foo", "bar", "baz"]
    for x in ["foo", "FOO", "bar", "bAr", "baz", "BAZ"]:
        assert x in e
    assert "junk" not in e

def test_enumeration_default():
    # this is private but used by properties
    e = enums.enumeration("foo", "bar", "baz")
    assert e._default == "foo"

# This can be removed when deprecation is complete
def test_accept_left_right_center():
    assert enums.accept_left_right_center("left_center") == "center_left"
    assert enums.accept_left_right_center("right_center") == "center_right"

# any changes to contents of enums.py easily trackable here
def test_enums_contents():
    assert [x for x in dir(enums) if x[0].isupper()] == [
        'Aggregation',
        'Anchor',
        'AngleUnits',
        'ButtonType',
        'DashPattern',
        'DateFormat',
        'DatetimeUnits',
        'DeprecatedAnchor',
        'DeprecatedLegendLocation',
        'Dimension',
        'Dimensions',
        'Direction',
        'Enumeration',
        'FontStyle',
        'HorizontalLocation',
        'JitterRandomDistribution',
        'LatLon',
        'LegendClickPolicy',
        'LegendLocation',
        'LineCap',
        'LineDash',
        'LineJoin',
        'Location',
        'MapType',
        'NamedColor',
        'NumeralLanguage',
        'Orientation',
        'PaddingUnits',
        'Palette',
        'RenderLevel',
        'RenderMode',
        'RoundingFunction',
        'SizingMode',
        'SliderCallbackPolicy',
        'SortDirection',
        'SpatialUnits',
        'StartEnd',
        'StepMode',
        'TextAlign',
        'TextBaseline',
        'TooltipFieldFormatter',
        'VerticalLocation',
    ]
<commit_msg>Fix enum test<commit_after>import bokeh.core.enums as enums

def test_Enumeration_default():
    e = enums.Enumeration()
    assert e.__slots__ == ()

def test_enumeration_basic():
    e = enums.enumeration("foo", "bar", "baz")
    assert isinstance(e, enums.Enumeration)
    assert str(e) == "Enumeration(foo, bar, baz)"
    assert [x for x in e] == ["foo", "bar", "baz"]
    for x in ["foo", "bar", "baz"]:
        assert x in e
    assert "junk" not in e

def test_enumeration_case():
    e = enums.enumeration("foo", "bar", "baz", case_sensitive=False)
    assert isinstance(e, enums.Enumeration)
    assert str(e) == "Enumeration(foo, bar, baz)"
    assert [x for x in e] == ["foo", "bar", "baz"]
    for x in ["foo", "FOO", "bar", "bAr", "baz", "BAZ"]:
        assert x in e
    assert "junk" not in e

def test_enumeration_default():
    # this is private but used by properties
    e = enums.enumeration("foo", "bar", "baz")
    assert e._default == "foo"

# This can be removed when deprecation is complete
def test_accept_left_right_center():
    assert enums.accept_left_right_center("left_center") == "center_left"
    assert enums.accept_left_right_center("right_center") == "center_right"

# any changes to contents of enums.py easily trackable here
def test_enums_contents():
    assert [x for x in dir(enums) if x[0].isupper()] == [
        'Aggregation',
        'Anchor',
        'AngleUnits',
        'ButtonType',
        'DashPattern',
        'DateFormat',
        'DatetimeUnits',
        'DeprecatedAnchor',
        'DeprecatedLegendLocation',
        'Dimension',
        'Dimensions',
        'Direction',
        'Enumeration',
        'FontStyle',
        'HorizontalLocation',
        'JitterRandomDistribution',
        'LatLon',
        'LegendClickPolicy',
        'LegendLocation',
        'LineCap',
        'LineDash',
        'LineJoin',
        'Location',
        'MapType',
        'NamedColor',
        'NumeralLanguage',
        'Orientation',
        'OutputBackend',
        'PaddingUnits',
        'Palette',
        'RenderLevel',
        'RenderMode',
        'RoundingFunction',
        'SizingMode',
        'SliderCallbackPolicy',
        'SortDirection',
        'SpatialUnits',
        'StartEnd',
        'StepMode',
        'TextAlign',
        'TextBaseline',
        'TooltipFieldFormatter',
        'VerticalLocation',
    ]
<|endoftext|>


<commit_before># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""Functional tests for the ``flocker-deploy`` command line tool."""
from subprocess import check_output, Popen, PIPE
import os
from unittest import skipIf

from twisted.trial.unittest import TestCase

from ... import __version__

# TODO This is basically from flocker-volume's tests, should be split out
def run(*args):
    """Run ``flocker-deploy`` with the given arguments.

    :param args: Additional command line arguments as ``bytes``.

    :return: The output of standard out.
    :raises: If exit code is not 0.
    """
    return check_output([b"flocker-deploy"] + list(args))

def run_expecting_error(*args):
    """Run ``flocker-deploy`` with the given arguments.

    :param args: Additional command line arguments as ``bytes``.

    :return: The output of standard error.
    :raises: If exit code is 0.
    """
    process = Popen([b"flocker-deploy"] + list(args), stderr=PIPE)
    result = process.stderr.read()
    exit_code = process.wait()
    if exit_code == 0:
        raise AssertionError("flocker-deploy exited with code 0.")
    return result

class FlockerDeployTests(TestCase):
    """Tests for ``flocker-deploy``."""

    if not os.getenv("FLOCKER_INSTALLED"):
        skip = "flocker-deploy not installed"

    def test_version(self):
        """``flocker-deploy --version`` returns the current version."""
        result = run(b"--version")
        self.assertEqual(result, b"%s\n" % (__version__,))
<commit_msg>Removed unused import<commit_after># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""Functional tests for the ``flocker-deploy`` command line tool."""
from subprocess import check_output, Popen, PIPE
import os

from twisted.trial.unittest import TestCase

from ... import __version__

# TODO This is basically from flocker-volume's tests, should be split out
def run(*args):
    """Run ``flocker-deploy`` with the given arguments.

    :param args: Additional command line arguments as ``bytes``.

    :return: The output of standard out.
    :raises: If exit code is not 0.
    """
    return check_output([b"flocker-deploy"] + list(args))

def run_expecting_error(*args):
    """Run ``flocker-deploy`` with the given arguments.

    :param args: Additional command line arguments as ``bytes``.

    :return: The output of standard error.
    :raises: If exit code is 0.
    """
    process = Popen([b"flocker-deploy"] + list(args), stderr=PIPE)
    result = process.stderr.read()
    exit_code = process.wait()
    if exit_code == 0:
        raise AssertionError("flocker-deploy exited with code 0.")
    return result

class FlockerDeployTests(TestCase):
    """Tests for ``flocker-deploy``."""

    if not os.getenv("FLOCKER_INSTALLED"):
        skip = "flocker-deploy not installed"

    def test_version(self):
        """``flocker-deploy --version`` returns the current version."""
        result = run(b"--version")
        self.assertEqual(result, b"%s\n" % (__version__,))
<|endoftext|>


<commit_before>
import functools

from girc.replycodes import replies

class UserDispatchMeta(type):
	"""Metaclass so that multiple Users with the same client and nick (and are active)
	instead return the same instance."""
	def __call__(self, client, nick):
		if nick not in client._users or not client._users[nick].active:
			return super(UserDispatchMeta, self).__call_(client, nick)
		return client._users[nick]

class User(object):
	__metaclass__ = UserDispatchMeta

	ident = None
	realname = None
	host = None

	server = None
	secure = False
	operator = False

	account = None
	metadata = {}

	active = True # whether this User object is up to date, ie. we're confident the nick is correct.

	def __init__(self, client, nick):
		self.client = client
		self.nick = nick
		self.client._users[nick] = self

	@property
	def channels(self):
		"""A map {channel: highest status mode} for channels the user is in"""
		results = {}
		for channel in self.client._channels.values():
			try:
				mode = channel.users.get_level(self.nick)
			except KeyError:
				pass
			else:
				results[channel] = mode
		return results

def register_handlers(client):
	"""Register handlers for given client to capture user info"""

	def command(name):
		"""Shortcut for client.handler(command=name)"""
		return client.handler(command=name)

	def with_user(fn):
		"""Helper decorator for handlers, takes first arg of msg and gets User() for that nick.
		Calls wrapped function with args fn(user, *params[1:])"""
		@functools.wraps(fn)
		def _with_user(client, msg):
			user = User(client, msg.params[0])
			return fn(user, *msg.params[1:])
		return _with_user

	@command(replies.WHOISUSER)
	@with_user
	def whois_user(user, ident, host, realname):
		user.ident = ident
		user.host = host
		user.realname = realname

	@command(replies.WHOISSERVER)
	@with_user
	def whois_server(user, server, server_info):
		user.server = server

	@command(replies.WHOISOPERATOR)
	@with_user
	def whois_oper(user, *junk):
		user.operator = True

	@command(replies.WHOISCHANNELS)
	@with_user
	def whois_channels(user, *channels):
		# channels is normally one space-seperated arg, but might be seperate args - normalize
		channels = ' '.join(channels).split(' ')
		all_prefixes = [prefix for mode, prefix in client.server_properties.prefixes]
		for name in channels:
			prefixes = ''
			while any(name.startswith(prefix) for prefix in all_prefixes if prefix):
				prefixes += name[0]
				name = name[1:]
			client.channel(name).users.recv_user_prefix(prefixes + user.nick)

	@command(replies.WHOISSECURE)
	@with_user
	def whois_secure(user, *junk):
		user.secure = True

	@command(replies.WHOISACCOUNT)
	@with_user
	def whois_account(user, account, *junk):
		user.account = account

	@command(replies.WHOISKEYVALUE)
	@with_user
	def whois_metadata(user, key, value):
		category, key = key.split('.', 1)
		user.setdefault('category', {})[key] = value

"""
info on whois responses
not all servers send all responses

311 WHOISUSER nick user host "*" realname
312 WHOISSERVER nick server server_description
313 WHOISOPERATOR nick ??
317 WHOISIDLE nick ... # DO NOT USE: ambiguous between server impls
318 ENDOFWHOIS nick # no more whois replies
319 WHOISCHANNELS nick (all one arg: space-seperated channels with optional prefix indicating user's rank in channel)
330 WHOISACCOUNT nick account _
671 WHOISSECURE nick (security type) [_]
760 WHOISKEYVALUE nick metadata_category.key value
"""
<commit_msg>users: Fix bug with bad num of args<commit_after>
import functools

from girc.replycodes import replies

class UserDispatchMeta(type):
	"""Metaclass so that multiple Users with the same client and nick (and are active)
	instead return the same instance."""
	def __call__(self, client, nick):
		if nick not in client._users or not client._users[nick].active:
			return super(UserDispatchMeta, self).__call_(client, nick)
		return client._users[nick]

class User(object):
	__metaclass__ = UserDispatchMeta

	ident = None
	realname = None
	host = None

	server = None
	secure = False
	operator = False

	account = None
	metadata = {}

	active = True # whether this User object is up to date, ie. we're confident the nick is correct.

	def __init__(self, client, nick):
		self.client = client
		self.nick = nick
		self.client._users[nick] = self

	@property
	def channels(self):
		"""A map {channel: highest status mode} for channels the user is in"""
		results = {}
		for channel in self.client._channels.values():
			try:
				mode = channel.users.get_level(self.nick)
			except KeyError:
				pass
			else:
				results[channel] = mode
		return results

def register_handlers(client):
	"""Register handlers for given client to capture user info"""

	def command(name):
		"""Shortcut for client.handler(command=name)"""
		return client.handler(command=name)

	def with_user(fn):
		"""Helper decorator for handlers, takes first arg of msg and gets User() for that nick.
		Calls wrapped function with args fn(user, *params[1:])"""
		@functools.wraps(fn)
		def _with_user(client, msg):
			user = User(client, msg.params[0])
			return fn(user, *msg.params[1:])
		return _with_user

	@command(replies.WHOISUSER)
	@with_user
	def whois_user(user, ident, host, _, realname):
		user.ident = ident
		user.host = host
		user.realname = realname

	@command(replies.WHOISSERVER)
	@with_user
	def whois_server(user, server, server_info):
		user.server = server

	@command(replies.WHOISOPERATOR)
	@with_user
	def whois_oper(user, *junk):
		user.operator = True

	@command(replies.WHOISCHANNELS)
	@with_user
	def whois_channels(user, *channels):
		# channels is normally one space-seperated arg, but might be seperate args - normalize
		channels = ' '.join(channels).split(' ')
		all_prefixes = [prefix for mode, prefix in client.server_properties.prefixes]
		for name in channels:
			prefixes = ''
			while any(name.startswith(prefix) for prefix in all_prefixes if prefix):
				prefixes += name[0]
				name = name[1:]
			client.channel(name).users.recv_user_prefix(prefixes + user.nick)

	@command(replies.WHOISSECURE)
	@with_user
	def whois_secure(user, *junk):
		user.secure = True

	@command(replies.WHOISACCOUNT)
	@with_user
	def whois_account(user, account, *junk):
		user.account = account

	@command(replies.WHOISKEYVALUE)
	@with_user
	def whois_metadata(user, key, value):
		category, key = key.split('.', 1)
		user.setdefault('category', {})[key] = value

"""
info on whois responses
not all servers send all responses

311 WHOISUSER nick user host "*" realname
312 WHOISSERVER nick server server_description
313 WHOISOPERATOR nick ??
317 WHOISIDLE nick ... # DO NOT USE: ambiguous between server impls
318 ENDOFWHOIS nick # no more whois replies
319 WHOISCHANNELS nick (all one arg: space-seperated channels with optional prefix indicating user's rank in channel)
330 WHOISACCOUNT nick account _
671 WHOISSECURE nick (security type) [_]
760 WHOISKEYVALUE nick metadata_category.key value
"""
<|endoftext|>


<commit_before>#/usr/bin/python2.6

import unittest
import sys

sys.path.insert(0, '../')

simpleList = [('', , ), ('', , )]
complexList = [('', , ), ('', , )]
equalPopularity = [('', , ), ('', , )]
checkAllSongs = [('', , ), ('', , )]

class zipfSongTestCase(unittest.TestCase):

    def setUp(self):
        self.simpleList = simpleList
        self.complexList = complexList
        self.equalPopularity = equalPopularity
        self.checkAllSongs = checkAllSongs

    def test_simpleList(self):
        from zipfSong import topSongs

    def test_complexList(self):

    def test_equalPopularity(self):

    def test_checkAllSongs(self):
<commit_msg>updated tests a bit<commit_after>#/usr/bin/python2.6

import unittest
import sys

sys.path.insert(0, '../')

simpleList = [('', , ), ('', , )]
complexList = [('', , ), ('', , )]
equalPopularity = [('', , ), ('', , )]
checkAllSongs = [('', , ), ('', , )]

class zipfSongTestCase(unittest.TestCase):

    def setUp(self):
        self.simpleList = simpleList
        self.complexList = complexList
        self.equalPopularity = equalPopularity
        self.checkAllSongs = checkAllSongs

    def test_simpleList(self):
        from zipfSong import topSongs
        topSongsInstance = topSongs()
        testSongExample = topSongs.sortSongs(self.simpleList)
        self.assertEqual(testSongExample, , 'Songs do not match')

    def test_complexList(self):
        from zipfSong import topSongs
        topSongsInstance = topSongs()
        testSongsExample = topSongs.sortSongs(self.complexList)
        self.assertEqual(testSongExample, , 'Songs do not match')

    def test_equalPopularity(self):
        from zipfSongs import topSongs
        topSongsInstance = topSongs()
        testSongsExample = topSongs.sortSongs(self.equalPopularity)
        self.assertEqual(testSongExample, , 'Songs do not match')

    def test_checkAllSongs(self):
        from zipfSongs import topSongs
        topSongsInstance = topSongs()
        testSongsExample = topSongs.sortSongs(self.checkAllSongs)
        self.assertEqual(testSongsExample, , 'Songs do not match')
<|endoftext|>


<commit_before>import collections

from eventlet import api
from eventlet import coros

class FanFailed(RuntimeError):
    pass

class SomeFailed(FanFailed):
    pass

class AllFailed(FanFailed):
    pass

# have to stick this in an exec so it works in 2.4
try:
    from contextlib import contextmanager
    exec('''
        @contextmanager
        def item_impl(self):
            """ Get an object out of the pool, for use with with statement.

            >>> from eventlet import pools
            >>> pool = pools.TokenPool(max_size=4)
            >>> with pool.item() as obj:
            ...     print "got token"
            ...
            got token
            >>> pool.free()
            4
            """
            obj = self.get()
            try:
                yield obj
            finally:
                self.put(obj)
            ''')
except ImportError:
    item_impl = None

class Pool(object):
    """
    When using the pool, if you do a get, you should **always** do a
    :meth:`put`.

    The pattern is::

     thing = self.pool.get()
     try:
         thing.method()
     finally:
         self.pool.put(thing)

    The maximum size of the pool can be modified at runtime via the
    :attr:`max_size` attribute.  Adjusting this number does not affect existing
    items checked out of the pool, nor on any waiters who are waiting for an
    item to free up.  Some indeterminate number of :meth:`get`/:meth:`put`
    cycles will be necessary before the new maximum size truly matches the
    actual operation of the pool.
    """
    def __init__(self, min_size=0, max_size=4, order_as_stack=False):
        """ Pre-populates the pool with *min_size* items.  Sets a hard limit to
        the size of the pool -- it cannot contain any more items than
        *max_size*, and if there are already *max_size* items 'checked out' of
        the pool, the pool will cause any getter to cooperatively yield until an
        item is put in.

        *order_as_stack* governs the ordering of the items in the free pool.
        If ``False`` (the default), the free items collection (of items that
        were created and were put back in the pool) acts as a round-robin,
        giving each item approximately equal utilization.  If ``True``, the
        free pool acts as a FILO stack, which preferentially re-uses items that
        have most recently been used.
        """
        self.min_size = min_size
        self.max_size = max_size
        self.order_as_stack = order_as_stack
        self.current_size = 0
        self.channel = coros.queue(0)
        self.free_items = collections.deque()
        for x in xrange(min_size):
            self.current_size += 1
            self.free_items.append(self.create())

    def get(self):
        """Return an item from the pool, when one is available
        """
        if self.free_items:
            return self.free_items.popleft()
        if self.current_size < self.max_size:
            created = self.create()
            self.current_size += 1
            return created
        return self.channel.wait()

    if item_impl is not None:
        item = item_impl

    def put(self, item):
        """Put an item back into the pool, when done
        """
        if self.current_size > self.max_size:
            self.current_size -= 1
            return

        if self.waiting():
            self.channel.send(item)
        else:
            if self.order_as_stack:
                self.free_items.appendleft(item)
            else:
                self.free_items.append(item)

    def resize(self, new_size):
        """Resize the pool
        """
        self.max_size = new_size

    def free(self):
        """Return the number of free items in the pool.
        """
        return len(self.free_items) + self.max_size - self.current_size

    def waiting(self):
        """Return the number of routines waiting for a pool item.
        """
        return self.channel.waiting()

    def create(self):
        """Generate a new pool item
        """
        raise NotImplementedError("Implement in subclass")

class Token(object):
    pass

class TokenPool(Pool):
    """A pool which gives out tokens, an object indicating that
    the person who holds the token has a right to consume some
    limited resource.
    """
    def create(self):
        return Token()

<commit_msg>Indentation problem caused >2.4 to break.<commit_after>import collections

from eventlet import api
from eventlet import coros

class FanFailed(RuntimeError):
    pass

class SomeFailed(FanFailed):
    pass

class AllFailed(FanFailed):
    pass

# have to stick this in an exec so it works in 2.4
try:
    from contextlib import contextmanager
    exec('''
@contextmanager
def item_impl(self):
    """ Get an object out of the pool, for use with with statement.

    >>> from eventlet import pools
    >>> pool = pools.TokenPool(max_size=4)
    >>> with pool.item() as obj:
    ...     print "got token"
    ...
    got token
    >>> pool.free()
    4
    """
    obj = self.get()
    try:
        yield obj
    finally:
        self.put(obj)
''')
except ImportError:
    item_impl = None

class Pool(object):
    """
    When using the pool, if you do a get, you should **always** do a
    :meth:`put`.

    The pattern is::

     thing = self.pool.get()
     try:
         thing.method()
     finally:
         self.pool.put(thing)

    The maximum size of the pool can be modified at runtime via the
    :attr:`max_size` attribute.  Adjusting this number does not affect existing
    items checked out of the pool, nor on any waiters who are waiting for an
    item to free up.  Some indeterminate number of :meth:`get`/:meth:`put`
    cycles will be necessary before the new maximum size truly matches the
    actual operation of the pool.
    """
    def __init__(self, min_size=0, max_size=4, order_as_stack=False):
        """ Pre-populates the pool with *min_size* items.  Sets a hard limit to
        the size of the pool -- it cannot contain any more items than
        *max_size*, and if there are already *max_size* items 'checked out' of
        the pool, the pool will cause any getter to cooperatively yield until an
        item is put in.

        *order_as_stack* governs the ordering of the items in the free pool.
        If ``False`` (the default), the free items collection (of items that
        were created and were put back in the pool) acts as a round-robin,
        giving each item approximately equal utilization.  If ``True``, the
        free pool acts as a FILO stack, which preferentially re-uses items that
        have most recently been used.
        """
        self.min_size = min_size
        self.max_size = max_size
        self.order_as_stack = order_as_stack
        self.current_size = 0
        self.channel = coros.queue(0)
        self.free_items = collections.deque()
        for x in xrange(min_size):
            self.current_size += 1
            self.free_items.append(self.create())

    def get(self):
        """Return an item from the pool, when one is available
        """
        if self.free_items:
            return self.free_items.popleft()
        if self.current_size < self.max_size:
            created = self.create()
            self.current_size += 1
            return created
        return self.channel.wait()

    if item_impl is not None:
        item = item_impl

    def put(self, item):
        """Put an item back into the pool, when done
        """
        if self.current_size > self.max_size:
            self.current_size -= 1
            return

        if self.waiting():
            self.channel.send(item)
        else:
            if self.order_as_stack:
                self.free_items.appendleft(item)
            else:
                self.free_items.append(item)

    def resize(self, new_size):
        """Resize the pool
        """
        self.max_size = new_size

    def free(self):
        """Return the number of free items in the pool.
        """
        return len(self.free_items) + self.max_size - self.current_size

    def waiting(self):
        """Return the number of routines waiting for a pool item.
        """
        return self.channel.waiting()

    def create(self):
        """Generate a new pool item
        """
        raise NotImplementedError("Implement in subclass")

class Token(object):
    pass

class TokenPool(Pool):
    """A pool which gives out tokens, an object indicating that
    the person who holds the token has a right to consume some
    limited resource.
    """
    def create(self):
        return Token()

<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

#
# Xibo - Digitial Signage - http://www.xibo.org.uk
# Copyright (C) 2009-14 Alex Harrington
#
# This file is part of Xibo.
#
# Xibo is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# Xibo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Xibo.  If not, see <http://www.gnu.org/licenses/>.
#

from XiboMedia import XiboMedia
from threading import Thread
import shutil
import math
import os
import codecs

class GetResourceBase(XiboMedia):
    def add(self):
        self.tmpPath = os.path.join(self.libraryDir,self.mediaId + "-cache.html")
        tmpXML = '<browser id="' + self.mediaNodeName + '" opacity="0" width="' + str(self.width) + '" height="' + str(self.height) + \
                '" />'
        self.p.enqueue('add',(tmpXML,self.regionNodeName))

        # Check updateInterval is set.
        # Early releases of the server missed this so catch those.
        try:
            tmpUI = int(self.options['updateInterval'])
        except KeyError:
            self.options['updateInterval'] = 10

        # Make sure we have fresh content from the CMS ahead of it needing to run
        # On a layout where the object is actually going to run, this should just return
        # since the pre-run layout check would have cached the content. The only exception
        # being tickers with 0 duration.
        self.download()

    def run(self):
        # Check if cached content is too old
        # Download new content if needed
        self.download()

        try:
            if int(self.options['durationIsPerItem']) == 1:
                # Media item is a ticker with duration per item
                # calculate the duration
                # HTML will contain a comment <!-- NUMITEMS=x -->
                # Find it and get the number or seconds, then
                # update the duration

                htmlFile = open(self.tmpPath, "r")

                for line in htmlFile:
                    if "<!-- NUMITEMS=" in line:
                        numItems = line.partition('=')[2]
                        numItems = numItems.partition('-')[0]
                        self.duration = int(numItems) * int(self.duration)

        except KeyError:
            pass

        # Display content
        self.p.enqueue('browserNavigate',(self.mediaNodeName,"file://" + os.path.abspath(self.tmpPath),None))
        self.p.enqueue('timer',(int(self.duration) * 1000,self.parent.next))
        self.startStats()
        self.p.enqueue('timer',(250,self.finishedRendering))

    def requiredFiles(self):
        return []

    def dispose(self):
        self.returnStats()
        self.p.enqueue('del',self.mediaNodeName)
        try:
            os.remove(self.tmpPath)
        except:
            self.log.log(0,"error","Unable to delete file %s" % (self.tmpPath))
        self.parent.tNext()

    def finishedRendering(self):
        bo = self.browserOptions()
        optionsTuple = (self.mediaNodeName,bo[0],bo[1])
        self.p.enqueue('browserOptions',optionsTuple)

        # Make the browser visible
        self.p.enqueue('setOpacity',(self.mediaNodeName,1))

    def browserOptions(self):
        scroll = False
        trans = True

        return (trans,scroll)

    def download(self):
        # Only process a download if we need it
        if not self.cacheIsExpired():
            return

        tries = 3
        i = 0
        flag = False

        while i < tries and flag == False:
            try:
                # print "******* Passing in L:%s R:%s M:%s" % (self.parent.parent.l.layoutID,self.parent.regionId,self.mediaId)
                s = self.parent.parent.parent.xmds.GetResource(self.parent.parent.l.layoutID,self.parent.regionId,self.mediaId)
                flag = True
            except:
                self.log.log(1,"error",_("Unable to load Resource from XMDS."))
            i += 1

        if flag:
            try:
                try:
                    f = open(os.path.join(self.libraryDir,self.mediaId) + '-cache.html','w')
                    f.write(s.encode("utf-8"))
                finally:
                    f.close()
            except:
                self.log.log(0,"error",_("Unable to write %s") % os.path.join(self.libraryDir,self.mediaId) + '-cache.html')

    def cacheIsExpired(self):
        # If libraryDir/self.mediaId-cache.xml exists then check if it's too old to use
        try:
    	    mtime = os.path.getmtime(os.path.join(self.libraryDir,self.mediaId + '-cache.html'))
            if time.time() < (mtime + (int(self.options['updateInterval']) * 60)):
                return False
        except:
            # File probably doesn't exist. Do nothing.
            pass

        return True

    def requiredFiles(self):
        return [self.mediaId + '-cache.html']
<commit_msg>[pyclient] Correct cache units to minutes not seconds.<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

#
# Xibo - Digitial Signage - http://www.xibo.org.uk
# Copyright (C) 2009-14 Alex Harrington
#
# This file is part of Xibo.
#
# Xibo is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# Xibo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Xibo.  If not, see <http://www.gnu.org/licenses/>.
#

from XiboMedia import XiboMedia
from threading import Thread
import shutil
import math
import os
import codecs

class GetResourceBase(XiboMedia):
    def add(self):
        self.tmpPath = os.path.join(self.libraryDir,self.mediaId + "-cache.html")
        tmpXML = '<browser id="' + self.mediaNodeName + '" opacity="0" width="' + str(self.width) + '" height="' + str(self.height) + \
                '" />'
        self.p.enqueue('add',(tmpXML,self.regionNodeName))

        # Check updateInterval is set.
        # Early releases of the server missed this so catch those.
        try:
            tmpUI = int(self.options['updateInterval'])
        except KeyError:
            self.options['updateInterval'] = 10

        # Make sure we have fresh content from the CMS ahead of it needing to run
        # On a layout where the object is actually going to run, this should just return
        # since the pre-run layout check would have cached the content. The only exception
        # being tickers with 0 duration.
        self.download()

    def run(self):
        # Check if cached content is too old
        # Download new content if needed
        self.download()

        try:
            if int(self.options['durationIsPerItem']) == 1:
                # Media item is a ticker with duration per item
                # calculate the duration
                # HTML will contain a comment <!-- NUMITEMS=x -->
                # Find it and get the number or seconds, then
                # update the duration

                htmlFile = open(self.tmpPath, "r")

                for line in htmlFile:
                    if "<!-- NUMITEMS=" in line:
                        numItems = line.partition('=')[2]
                        numItems = numItems.partition('-')[0]
                        self.duration = int(numItems) * int(self.duration)

        except KeyError:
            pass

        # Display content
        self.p.enqueue('browserNavigate',(self.mediaNodeName,"file://" + os.path.abspath(self.tmpPath),None))
        self.p.enqueue('timer',(int(self.duration) * 1000,self.parent.next))
        self.startStats()
        self.p.enqueue('timer',(250,self.finishedRendering))

    def requiredFiles(self):
        return []

    def dispose(self):
        self.returnStats()
        self.p.enqueue('del',self.mediaNodeName)
        try:
            os.remove(self.tmpPath)
        except:
            self.log.log(0,"error","Unable to delete file %s" % (self.tmpPath))
        self.parent.tNext()

    def finishedRendering(self):
        bo = self.browserOptions()
        optionsTuple = (self.mediaNodeName,bo[0],bo[1])
        self.p.enqueue('browserOptions',optionsTuple)

        # Make the browser visible
        self.p.enqueue('setOpacity',(self.mediaNodeName,1))

    def browserOptions(self):
        scroll = False
        trans = True

        return (trans,scroll)

    def download(self):
        # Only process a download if we need it
        if not self.cacheIsExpired():
            return

        tries = 3
        i = 0
        flag = False

        while i < tries and flag == False:
            try:
                # print "******* Passing in L:%s R:%s M:%s" % (self.parent.parent.l.layoutID,self.parent.regionId,self.mediaId)
                s = self.parent.parent.parent.xmds.GetResource(self.parent.parent.l.layoutID,self.parent.regionId,self.mediaId)
                flag = True
            except:
                self.log.log(1,"error",_("Unable to load Resource from XMDS."))
            i += 1

        if flag:
            try:
                try:
                    f = open(os.path.join(self.libraryDir,self.mediaId) + '-cache.html','w')
                    f.write(s.encode("utf-8"))
                finally:
                    f.close()
            except:
                self.log.log(0,"error",_("Unable to write %s") % os.path.join(self.libraryDir,self.mediaId) + '-cache.html')

    def cacheIsExpired(self):
        # If libraryDir/self.mediaId-cache.xml exists then check if it's too old to use
        try:
    	    mtime = os.path.getmtime(os.path.join(self.libraryDir,self.mediaId + '-cache.html'))
            if time.time() < (mtime + (int(self.options['updateInterval']) * 60 * 60)):
                return False
        except:
            # File probably doesn't exist. Do nothing.
            pass

        return True

    def requiredFiles(self):
        return [self.mediaId + '-cache.html']
<|endoftext|>


<commit_before>from pyramid.config import Configurator
from sqlalchemy import engine_from_config

from .models import (
    DBSession,
    Base,
    )

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    config = Configurator(settings=settings)
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('agora', '/')
    config.add_route('add_idea', '/add_idea')
    config.add_route('idea_view', '/ideas/{idea}')
    config.scan()
    return config.make_wsgi_app()
<commit_msg>added include statement for pyramid_chameleon, for Pyramid 1.5<commit_after>from pyramid.config import Configurator
from sqlalchemy import engine_from_config

from .models import (
    DBSession,
    Base,
    )

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    config = Configurator(settings=settings)
    config.include('pyramid_chameleon')
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('agora', '/')
    config.add_route('add_idea', '/add_idea')
    config.add_route('idea_view', '/ideas/{idea}')
    config.scan()
    return config.make_wsgi_app()
<|endoftext|>