<commit_before>import os

from spec import eq_, skip, Spec

from invoke import run
from invoke.parser import Parser, Context
from invoke.collection import Collection
from invoke.task import task

from _utils import support

class CLI(Spec):
    "Command-line interface"

    def setup(self):
        @task
        def mytask(mystring, s, boolean=False, b=False):
            pass
        @task
        def mytask2():
            pass
        @task
        def mytask3(mystring):
            pass
        c = Collection()
        c.add_task('mytask', mytask)
        c.add_task('mytask2', mytask2)
        c.add_task('mytask3', mytask3)
        self.c = c

    def _parser(self):
        return Parser(self.c.to_contexts())

    def _parse(self, argstr):
        return self._parser().parse_argv(argstr.split())

    def _compare(self, invoke, flagname, value):
        invoke = "mytask " + invoke
        result = self._parse(invoke)
        eq_(result.to_dict()['mytask'][flagname], value)

    # Yo dogfood, I heard you like invoking
    def basic_invocation(self):
        os.chdir(support)
        result = run("invoke -c integration print_foo")
        eq_(result.stdout, "foo\n")

    def implicit_task_module(self):
        # Contains tasks.py
        os.chdir(support + '/implicit/')
        # Doesn't specify --collection
        result = run("invoke foo")
        eq_(result.stdout, "Hm\n")

    def boolean_args(self):
        self._compare("--boolean", 'boolean', True)

    def flag_then_space_then_value(self):
        self._compare("--mystring foo", 'mystring', 'foo')

    def flag_then_equals_sign_then_value(self):
        self._compare("--mystring=foo", 'mystring', 'foo')

    def short_boolean_flag(self):
        self._compare("-b", 'b', True)

    def short_flag_then_space_then_value(self):
        self._compare("-s value", 's', 'value')

    def short_flag_then_equals_sign_then_value(self):
        self._compare("-s=value", 's', 'value')

    def short_flag_with_adjacent_value(self):
        "taskname -fvalue"
        skip()

    def _flag_value_task(self, value):
        r = self._parse("mytask -s %s mytask2" % value)
        eq_(len(r), 2)
        eq_(r[0].name, 'mytask')
        eq_(r[0].args.s.value, value)
        eq_(r[1].name, 'mytask2')

    def flag_value_then_task(self):
        self._flag_value_task('value')

    def flag_value_same_as_task_name(self):
        self._flag_value_task('mytask2')

    def three_tasks_with_args(self):
        r = self._parse("mytask --boolean mytask3 --mystring foo mytask2")
        eq_(len(r), 3)
        eq_([x.name for x in r], ['mytask', 'mytask3', 'mytask2'])
        eq_(r[0].args.boolean.value, True)
        eq_(r[1].args.mystring.value, 'foo')

    def tasks_with_duplicately_named_kwargs(self):
        r = self._parse("mytask --mystring foo mytask3 --mystring bar")
        eq_(r[0].name, 'mytask')
        eq_(r[0].args.mystring.value, 'foo')
        eq_(r[1].name, 'mytask3')
        eq_(r[1].args.mystring.value, 'bar')

    def multiple_short_flags_adjacent(self):
        "task1 -abc => equiv to task1 -a -b -c"
        skip()
<commit_msg>Add back useful task docstring-names<commit_after>import os

from spec import eq_, skip, Spec

from invoke import run
from invoke.parser import Parser, Context
from invoke.collection import Collection
from invoke.task import task

from _utils import support

class CLI(Spec):
    "Command-line interface"

    def setup(self):
        @task
        def mytask(mystring, s, boolean=False, b=False):
            pass
        @task
        def mytask2():
            pass
        @task
        def mytask3(mystring):
            pass
        c = Collection()
        c.add_task('mytask', mytask)
        c.add_task('mytask2', mytask2)
        c.add_task('mytask3', mytask3)
        self.c = c

    def _parser(self):
        return Parser(self.c.to_contexts())

    def _parse(self, argstr):
        return self._parser().parse_argv(argstr.split())

    def _compare(self, invoke, flagname, value):
        invoke = "mytask " + invoke
        result = self._parse(invoke)
        eq_(result.to_dict()['mytask'][flagname], value)

    # Yo dogfood, I heard you like invoking
    def basic_invocation(self):
        os.chdir(support)
        result = run("invoke -c integration print_foo")
        eq_(result.stdout, "foo\n")

    def implicit_task_module(self):
        # Contains tasks.py
        os.chdir(support + '/implicit/')
        # Doesn't specify --collection
        result = run("invoke foo")
        eq_(result.stdout, "Hm\n")

    def boolean_args(self):
        "mytask --boolean"
        self._compare("--boolean", 'boolean', True)

    def flag_then_space_then_value(self):
        "mytask --mystring foo"
        self._compare("--mystring foo", 'mystring', 'foo')

    def flag_then_equals_sign_then_value(self):
        "mytask --mystring=foo"
        self._compare("--mystring=foo", 'mystring', 'foo')

    def short_boolean_flag(self):
        "mytask -b"
        self._compare("-b", 'b', True)

    def short_flag_then_space_then_value(self):
        "mytask -s value"
        self._compare("-s value", 's', 'value')

    def short_flag_then_equals_sign_then_value(self):
        "mytask -s=value"
        self._compare("-s=value", 's', 'value')

    def short_flag_with_adjacent_value(self):
        "taskname -fvalue"
        skip()

    def _flag_value_task(self, value):
        r = self._parse("mytask -s %s mytask2" % value)
        eq_(len(r), 2)
        eq_(r[0].name, 'mytask')
        eq_(r[0].args.s.value, value)
        eq_(r[1].name, 'mytask2')

    def flag_value_then_task(self):
        "mytask -s value mytask2"
        self._flag_value_task('value')

    def flag_value_same_as_task_name(self):
        "mytask -s mytask2 mytask2"
        self._flag_value_task('mytask2')

    def three_tasks_with_args(self):
        "mytask --boolean mytask3 --mystring foo mytask2"
        r = self._parse("mytask --boolean mytask3 --mystring foo mytask2")
        eq_(len(r), 3)
        eq_([x.name for x in r], ['mytask', 'mytask3', 'mytask2'])
        eq_(r[0].args.boolean.value, True)
        eq_(r[1].args.mystring.value, 'foo')

    def tasks_with_duplicately_named_kwargs(self):
        "mytask --mystring foo mytask3 --mystring bar"
        r = self._parse("mytask --mystring foo mytask3 --mystring bar")
        eq_(r[0].name, 'mytask')
        eq_(r[0].args.mystring.value, 'foo')
        eq_(r[1].name, 'mytask3')
        eq_(r[1].args.mystring.value, 'bar')

    def multiple_short_flags_adjacent(self):
        "task1 -abc => equiv to task1 -a -b -c"
        skip()
<|endoftext|>


<commit_before>#
# Copyright (C) 2015 - 2018 Satoru SATOH <ssato at redhat.com>
# License: MIT
#
# pylint: disable=missing-docstring,invalid-name
"""Tests of anytempalte.cli
"""
from __future__ import absolute_import

import os.path
import os
import subprocess
import unittest

import anytemplate.cli as TT
import tests.common

from anytemplate.engine import find_by_name

_CWD = os.path.abspath(os.path.join(tests.common.selfdir(), ".."))
_RUN_CLI = "PYTHONPATH=. python ./anytemplate/cli.py"

def run_and_check_exit_code(args=None, code=0):
    """
    Run main() and check its exit code.
    """
    try:
        TT.main(["dummy"] + ([] if args is None else args))
    except SystemExit as exc:
        return exc.code == code

    return True

class Test00(unittest.TestCase):

    def run_and_check_exit_code(self, args=None, code=0, _not=False):
        if args is None:
            args = []
        if _not:
            self.assertFalse(run_and_check_exit_code(args, code))
        else:
            self.assertTrue(run_and_check_exit_code(args, code))

    def test_10_main__wo_args(self):
        self.run_and_check_exit_code(code=1)

    def test_12__show_usage(self):
        self.run_and_check_exit_code(["--help"])

    def test_14__wrong_option(self):
        self.run_and_check_exit_code(["--wrong-option-xyz"], _not=True)

    def test_20_main__wo_args(self):
        self.assertRaises(SystemExit, TT.main, [])

    def test_22_main__show_usage(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--help"])

    def test_24_main__show_usage(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--wrong-option"])

    def test_26_main__list_engines(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--list-engines"])

class Test10(tests.common.TestsWithWorkdir):

    def run_and_check_exit_code(self, args=None, code=0, _not=False):
        if args is None:
            args = []
        if _not:
            self.assertFalse(run_and_check_exit_code(args, code))
        else:
            self.assertTrue(run_and_check_exit_code(args, code))

    def test_10_main__strtemplate(self):
        tmpl = os.path.join(self.workdir, "test.tmpl")
        ctx = os.path.join(self.workdir, "ctx.yml")
        output = os.path.join(self.workdir, "output.txt")
        open(tmpl, 'w').write("$a\n")
        open(ctx, 'w').write("a: aaa\n")

        self.run_and_check_exit_code(["-E", "string.Template", "-C", ctx,
                                      "-o", output, tmpl])
        self.assertEqual(open(output).read(), "aaa\n")

    def test_20_main__jinja2(self):
        if find_by_name("jinja2"):
            tmpl = os.path.join(self.workdir, "test.j2")
            output = os.path.join(self.workdir, "output.txt")
            open(tmpl, 'w').write("{{ hello|default('hello') }}")

            self.run_and_check_exit_code(["-o", output, tmpl])
            self.assertEqual(open(output).read(), "hello")

class Test20(tests.common.TestsWithWorkdir):

    def test_10_strtemplate_read_ctx_from_stdin(self):
        tmpl = os.path.join(self.workdir, "test.tmpl")
        open(tmpl, 'w').write("$a\n")

        out = subprocess.check_output("echo 'a: aaa' | "
                                      "%s -E string.Template -C yaml:- "
                                      "-o - %s" % (_RUN_CLI, tmpl),
                                      cwd=_CWD, shell=True)
        self.assertEqual(out.rstrip(), tests.common.to_bytes("aaa"))

    def test_20_strtemplate_read_tmpl_from_stdin(self):
        ctx = os.path.join(self.workdir, "ctx.yml")
        open(ctx, 'w').write("a: aaa\n")

        out = subprocess.check_output("echo '$a' | "
                                      "%s -E string.Template -C yaml:%s "
                                      "-o - -" % (_RUN_CLI, ctx),
                                      cwd=_CWD, shell=True)
        self.assertEqual(out.rstrip(), tests.common.to_bytes("aaa"))

# vim:sw=4:ts=4:et:
<commit_msg>fix: tweak search paths of the CLI script<commit_after>#
# Copyright (C) 2015 - 2018 Satoru SATOH <ssato at redhat.com>
# License: MIT
#
# pylint: disable=missing-docstring,invalid-name
"""Tests of anytempalte.cli
"""
from __future__ import absolute_import

import os.path
import os
import subprocess
import unittest

import anytemplate.cli as TT
import tests.common

from anytemplate.engine import find_by_name

_CWD = os.path.abspath(os.path.join(tests.common.selfdir(), ".."))
_RUN_CLI = "PYTHONPATH=./src/ python ./src/anytemplate/cli.py"

def run_and_check_exit_code(args=None, code=0):
    """
    Run main() and check its exit code.
    """
    try:
        TT.main(["dummy"] + ([] if args is None else args))
    except SystemExit as exc:
        return exc.code == code

    return True

class Test00(unittest.TestCase):

    def run_and_check_exit_code(self, args=None, code=0, _not=False):
        if args is None:
            args = []
        if _not:
            self.assertFalse(run_and_check_exit_code(args, code))
        else:
            self.assertTrue(run_and_check_exit_code(args, code))

    def test_10_main__wo_args(self):
        self.run_and_check_exit_code(code=1)

    def test_12__show_usage(self):
        self.run_and_check_exit_code(["--help"])

    def test_14__wrong_option(self):
        self.run_and_check_exit_code(["--wrong-option-xyz"], _not=True)

    def test_20_main__wo_args(self):
        self.assertRaises(SystemExit, TT.main, [])

    def test_22_main__show_usage(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--help"])

    def test_24_main__show_usage(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--wrong-option"])

    def test_26_main__list_engines(self):
        self.assertRaises(SystemExit, TT.main, ["dummy", "--list-engines"])

class Test10(tests.common.TestsWithWorkdir):

    def run_and_check_exit_code(self, args=None, code=0, _not=False):
        if args is None:
            args = []
        if _not:
            self.assertFalse(run_and_check_exit_code(args, code))
        else:
            self.assertTrue(run_and_check_exit_code(args, code))

    def test_10_main__strtemplate(self):
        tmpl = os.path.join(self.workdir, "test.tmpl")
        ctx = os.path.join(self.workdir, "ctx.yml")
        output = os.path.join(self.workdir, "output.txt")
        open(tmpl, 'w').write("$a\n")
        open(ctx, 'w').write("a: aaa\n")

        self.run_and_check_exit_code(["-E", "string.Template", "-C", ctx,
                                      "-o", output, tmpl])
        self.assertEqual(open(output).read(), "aaa\n")

    def test_20_main__jinja2(self):
        if find_by_name("jinja2"):
            tmpl = os.path.join(self.workdir, "test.j2")
            output = os.path.join(self.workdir, "output.txt")
            open(tmpl, 'w').write("{{ hello|default('hello') }}")

            self.run_and_check_exit_code(["-o", output, tmpl])
            self.assertEqual(open(output).read(), "hello")

class Test20(tests.common.TestsWithWorkdir):

    def test_10_strtemplate_read_ctx_from_stdin(self):
        tmpl = os.path.join(self.workdir, "test.tmpl")
        open(tmpl, 'w').write("$a\n")

        out = subprocess.check_output("echo 'a: aaa' | "
                                      "%s -E string.Template -C yaml:- "
                                      "-o - %s" % (_RUN_CLI, tmpl),
                                      cwd=_CWD, shell=True)
        self.assertEqual(out.rstrip(), tests.common.to_bytes("aaa"))

    def test_20_strtemplate_read_tmpl_from_stdin(self):
        ctx = os.path.join(self.workdir, "ctx.yml")
        open(ctx, 'w').write("a: aaa\n")

        out = subprocess.check_output("echo '$a' | "
                                      "%s -E string.Template -C yaml:%s "
                                      "-o - -" % (_RUN_CLI, ctx),
                                      cwd=_CWD, shell=True)
        self.assertEqual(out.rstrip(), tests.common.to_bytes("aaa"))

# vim:sw=4:ts=4:et:
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- mode: python -*-
#
# Copyright (c) 2004-2009 rPath, Inc.
#

import sys
import unittest
from jobslave_test import bootstrap
from testrunner import pathManager

EXCLUDED_PATHS = ['dist/', '/build/', 'test', 'setup.py', 'trovebucket.py',
        'gencslist.py', 'scripts', 'pylint']

def setup():
    pathManager.addExecPath('MCP_PATH')
    pathManager.addExecPath('PYOVF_PATH')
    pathManager.addExecPath('RESTLIB_PATH')
    pathManager.addExecPath('CONARY_PATH')
    pathManager.addExecPath('BOTO_PATH')
    pathManager.addExecPath('XOBJ_PATH')

    conaryTestPath = pathManager.addExecPath('CONARY_TEST_PATH')
    jsPath = pathManager.addExecPath('JOB_SLAVE_PATH', isTestRoot=True)
    pathManager.addResourcePath('JOB_SLAVE_ARCHIVE_PATH',
            path=jsPath + '/jobslave_test/archive')
    pathManager.addResourcePath('CONARY_ARCHIVE_PATH',
            path=conaryTestPath + '/archive')

    from conary.lib import util
    sys.excepthook = util.genExcepthook(True)

    # if we're running with COVERAGE_DIR, we'll start covering now
    from conary.lib import coveragehook

    # import tools normally expected in findTrove.
    from testrunner.testhelp import context, TestCase, findPorts, SkipTestException
    sys.modules[__name__].context = context
    sys.modules[__name__].TestCase = TestCase
    sys.modules[__name__].findPorts = findPorts
    sys.modules[__name__].SkipTestException = SkipTestException

    # MCP specific tweaks
    from jobslave.generators import bootable_image
    bootable_image.BootableImage._orig_status = \
            bootable_image.BootableImage.status
    bootable_image.BootableImage.status = \
            lambda *args, **kwargs: None
    #end MCP specific tweaks

    from conary.lib import util
    sys.excepthook = util.genExcepthook(True, catchSIGUSR1=False)

def main(argv=None):
    from testrunner import testhelp, pathManager
    class rBuilderTestSuiteHandler(testhelp.TestSuiteHandler):
        suiteClass = testhelp.ConaryTestSuite

        def getCoverageDirs(self, environ):
            return pathManager.getPath('JOB_SLAVE_PATH')

        def getCoverageExclusions(self, environ):
            return EXCLUDED_PATHS

    global _handler
    if argv is None:
        argv = list(sys.argv)

    _handler = rBuilderTestSuiteHandler(individual=False)
    results = _handler.main(argv)
    return results.getExitCode()

_individual = False

if __name__ == '__main__':
    setup()
    sys.exit(main(sys.argv))
<commit_msg>mcp and boto aren't required anymore<commit_after>#!/usr/bin/python
# -*- mode: python -*-
#
# Copyright (c) 2004-2009 rPath, Inc.
#

import sys
import unittest
from jobslave_test import bootstrap
from testrunner import pathManager

EXCLUDED_PATHS = ['dist/', '/build/', 'test', 'setup.py', 'trovebucket.py',
        'gencslist.py', 'scripts', 'pylint']

def setup():
    pathManager.addExecPath('PYOVF_PATH')
    pathManager.addExecPath('RESTLIB_PATH')
    pathManager.addExecPath('CONARY_PATH')
    pathManager.addExecPath('XOBJ_PATH')

    conaryTestPath = pathManager.addExecPath('CONARY_TEST_PATH')
    jsPath = pathManager.addExecPath('JOB_SLAVE_PATH', isTestRoot=True)
    pathManager.addResourcePath('JOB_SLAVE_ARCHIVE_PATH',
            path=jsPath + '/jobslave_test/archive')
    pathManager.addResourcePath('CONARY_ARCHIVE_PATH',
            path=conaryTestPath + '/archive')

    from conary.lib import util
    sys.excepthook = util.genExcepthook(True)

    # if we're running with COVERAGE_DIR, we'll start covering now
    from conary.lib import coveragehook

    # import tools normally expected in findTrove.
    from testrunner.testhelp import context, TestCase, findPorts, SkipTestException
    sys.modules[__name__].context = context
    sys.modules[__name__].TestCase = TestCase
    sys.modules[__name__].findPorts = findPorts
    sys.modules[__name__].SkipTestException = SkipTestException

    # MCP specific tweaks
    from jobslave.generators import bootable_image
    bootable_image.BootableImage._orig_status = \
            bootable_image.BootableImage.status
    bootable_image.BootableImage.status = \
            lambda *args, **kwargs: None
    #end MCP specific tweaks

    from conary.lib import util
    sys.excepthook = util.genExcepthook(True, catchSIGUSR1=False)

def main(argv=None):
    from testrunner import testhelp, pathManager
    class rBuilderTestSuiteHandler(testhelp.TestSuiteHandler):
        suiteClass = testhelp.ConaryTestSuite

        def getCoverageDirs(self, environ):
            return pathManager.getPath('JOB_SLAVE_PATH')

        def getCoverageExclusions(self, environ):
            return EXCLUDED_PATHS

    global _handler
    if argv is None:
        argv = list(sys.argv)

    _handler = rBuilderTestSuiteHandler(individual=False)
    results = _handler.main(argv)
    return results.getExitCode()

_individual = False

if __name__ == '__main__':
    setup()
    sys.exit(main(sys.argv))
<|endoftext|>


<commit_before>from django.views.generic import TemplateView, ListView
from django.db.models import Count, Sum
from django.utils.translation import ugettext_lazy as _

from dashboard.components import DashboardAppMixin
from ophasebase.models import Ophase
from staff.models import TutorGroup
from students.models import Student, Newsletter

class StudentsAppMixin(DashboardAppMixin):
    app_name_verbose = _("Ersties")
    app_name = 'students'
    permissions = ['students.add_student', 'exam.add_assignment']

    @property
    def sidebar_links(self):
        return [
            (_('Übersicht'), self.prefix_reverse_lazy('index')),
            (_('Zertifikate erstellen'), self.prefix_reverse_lazy('certificate')),
            (_('Newsletter'), self.prefix_reverse_lazy('newsletter'))
        ]

class StudentStatsView(StudentsAppMixin, TemplateView):
    template_name = "students/dashboard/view_stats.html"

    def get_context_data(self):
        context = super().get_context_data()

        current_ophase = Ophase.current()
        context['ophase_title'] = 'Ophase'
        if current_ophase is not None:
            context['ophase_title'] = str(current_ophase)

            students = Student.get_current()

            context['count_student'] = students.count()
            context['count_exam'] = students.filter(want_exam=True).count()

            tutor_groups = TutorGroup.objects\
                                            .annotate(
                                                num=Count('student'),
                                                num_exam=Sum('student__want_exam'))\
                                            .order_by('group_category', 'name')

            # With some DB Backends Sum returns True instead of 1
            # int() fixes it.
            # see https://github.com/d120/pyophase/issues/47
            for group in tutor_groups:
                if group.num_exam != None:
                    group.num_exam = int(group.num_exam)

            context['tutor_groups'] = tutor_groups
        return context

class ExportCertificateView(StudentsAppMixin, ListView):
    model = Student
    template_name = "students/dashboard/view_certificate.html"

    def get_queryset(self):
        return Student.get_current(want_exam=True).order_by('tutor_group__name', 'name', 'prename')

class NewsletterOverviewView(StudentsAppMixin, ListView):
    model = Newsletter
    template_name = "students/dashboard/view_newsletter_overview.html"

    def get_queryset(self):
        return Newsletter.objects.annotate(num=Count('student'))

class ExportNewsletterSubscriptionView(StudentsAppMixin, ListView):
    model = Student
    template_name = "students/dashboard/view_export_newsletter.html"

    def get_queryset(self):
        return Student.get_current(newsletters__id=self.kwargs['newsletter_id'])

    def add_context_data(self, context):
        context = super().add_context_data(context)
        context['newsletter_name'] = Newsletter.objects.get(pk=self.kwargs['newsletter_id']).name
        return context
<commit_msg>Code refactor: QuerySets are lazy.<commit_after>from django.views.generic import TemplateView, ListView
from django.db.models import Count, Sum
from django.utils.translation import ugettext_lazy as _

from dashboard.components import DashboardAppMixin
from ophasebase.models import Ophase
from staff.models import TutorGroup
from students.models import Student, Newsletter

class StudentsAppMixin(DashboardAppMixin):
    app_name_verbose = _("Ersties")
    app_name = 'students'
    permissions = ['students.add_student', 'exam.add_assignment']

    @property
    def sidebar_links(self):
        return [
            (_('Übersicht'), self.prefix_reverse_lazy('index')),
            (_('Zertifikate erstellen'), self.prefix_reverse_lazy('certificate')),
            (_('Newsletter'), self.prefix_reverse_lazy('newsletter'))
        ]

class StudentStatsView(StudentsAppMixin, TemplateView):
    template_name = "students/dashboard/view_stats.html"

    def get_context_data(self):
        context = super().get_context_data()

        current_ophase = Ophase.current()
        context['ophase_title'] = 'Ophase'
        if current_ophase is not None:
            context['ophase_title'] = str(current_ophase)

            students = Student.get_current()

            context['count_student'] = students.count()
            context['count_exam'] = students.filter(want_exam=True).count()

            t_groups = TutorGroup.objects
            t_groups = t_groups.annotate(num=Count('student'))
            t_groups = t_groups.annotate(num_exam=Sum('student__want_exam'))
            t_groups = t_groups.order_by('group_category', 'name')

            # With some DB Backends Sum returns True instead of 1
            # int() fixes it.
            # see https://github.com/d120/pyophase/issues/47
            for group in t_groups:
                if group.num_exam != None:
                    group.num_exam = int(group.num_exam)

            context['tutor_groups'] = t_groups
        return context

class ExportCertificateView(StudentsAppMixin, ListView):
    model = Student
    template_name = "students/dashboard/view_certificate.html"

    def get_queryset(self):
        return Student.get_current(want_exam=True).order_by('tutor_group__name', 'name', 'prename')

class NewsletterOverviewView(StudentsAppMixin, ListView):
    model = Newsletter
    template_name = "students/dashboard/view_newsletter_overview.html"

    def get_queryset(self):
        return Newsletter.objects.annotate(num=Count('student'))

class ExportNewsletterSubscriptionView(StudentsAppMixin, ListView):
    model = Student
    template_name = "students/dashboard/view_export_newsletter.html"

    def get_queryset(self):
        return Student.get_current(newsletters__id=self.kwargs['newsletter_id'])

    def add_context_data(self, context):
        context = super().add_context_data(context)
        context['newsletter_name'] = Newsletter.objects.get(pk=self.kwargs['newsletter_id']).name
        return context
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# django-ldapdb
# Copyright (c) 2009-2010, Bolloré telecom
# All rights reserved.
#
# See AUTHORS file for a full list of contributors.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
#     1. Redistributions of source code must retain the above copyright notice,
#        this list of conditions and the following disclaimer.
#
#     2. Redistributions in binary form must reproduce the above copyright
#        notice, this list of conditions and the following disclaimer in the
#        documentation and/or other materials provided with the distribution.
#
#     3. Neither the name of Bolloré telecom nor the names of its contributors
#        may be used to endorse or promote products derived from this software
#        without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

import ldap
import logging

import django.db.models
from django.db.models import signals

import ldapdb
from ldapdb.models.query import QuerySet

class ModelBase(django.db.models.base.ModelBase):
    """
    Metaclass for all LDAP models.
    """
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__
        new_class = super_new(cls, name, bases, attrs)

        # patch manager to use our own QuerySet class
        if not new_class._meta.abstract:
            def get_query_set():
                return QuerySet(new_class)
            new_class.objects.get_query_set = get_query_set
            new_class._default_manager.get_query_set = get_query_set

        return new_class

class Model(django.db.models.base.Model):
    """
    Base class for all LDAP models.
    """
    __metaclass__ = ModelBase

    dn = django.db.models.fields.CharField(max_length=200)

    # meta-data
    base_dn = None
    search_scope = ldap.SCOPE_SUBTREE
    object_classes = ['top']

    def __init__(self, *args, **kwargs):
        super(Model, self).__init__(*args, **kwargs)
        self.saved_pk = self.pk

    def _collect_sub_objects(self, seen_objs, parent=None, nullable=False):
        """
        This private API seems to be called by the admin interface in django 1.2
        """
        pk_val = self._get_pk_val()
        seen_objs.add(self.__class__, pk_val, self,
                      type(parent), parent, nullable)

    def build_rdn(self):
        """
        Build the Relative Distinguished Name for this entry.
        """
        bits = []
        for field in self._meta.fields:
            if field.db_column and field.primary_key:
                bits.append("%s=%s" % (field.db_column, getattr(self, field.name)))
        if not len(bits):
            raise Exception("Could not build Distinguished Name")
        return '+'.join(bits)

    def build_dn(self):
        """
        Build the Distinguished Name for this entry.
        """
        return "%s,%s" % (self.build_rdn(), self.base_dn)
        raise Exception("Could not build Distinguished Name")

    def delete(self):
        """
        Delete this entry.
        """
        using = using or router.db_for_write(self.__class__, instance=self)
        connection = connections[using]
        logging.debug("Deleting LDAP entry %s" % self.dn)
        connection.delete_s(self.dn)
        signals.post_delete.send(sender=self.__class__, instance=self)

    def save(self, using=None):
        """
        Saves the current instance.
        """
        using = using or router.db_for_write(self.__class__, instance=self)
        connection = connections[using]
        if not self.dn:
            # create a new entry
            record_exists = False
            entry = [('objectClass', self.object_classes)]
            new_dn = self.build_dn()

            for field in self._meta.fields:
                if not field.db_column:
                    continue
                value = getattr(self, field.name)
                if value:
                    entry.append((field.db_column, field.get_db_prep_save(value, connection=connection)))

            logging.debug("Creating new LDAP entry %s" % new_dn)
            connection.add_s(new_dn, entry)

            # update object
            self.dn = new_dn

        else:
            # update an existing entry
            record_exists = True
            modlist = []
            orig = self.__class__.objects.get(pk=self.saved_pk)
            for field in self._meta.fields:
                if not field.db_column:
                    continue
                old_value = getattr(orig, field.name, None)
                new_value = getattr(self, field.name, None)
                if old_value != new_value:
                    if new_value:
                        modlist.append((ldap.MOD_REPLACE, field.db_column, field.get_db_prep_save(new_value, connection=connection)))
                    elif old_value:
                        modlist.append((ldap.MOD_DELETE, field.db_column, None))

            if len(modlist):
                # handle renaming
                new_dn = self.build_dn()
                if new_dn != self.dn:
                    logging.debug("Renaming LDAP entry %s to %s" % (self.dn, new_dn))
                    connection.rename_s(self.dn, self.build_rdn())
                    self.dn = new_dn

                logging.debug("Modifying existing LDAP entry %s" % self.dn)
                connection.modify_s(self.dn, modlist)
            else:
                logging.debug("No changes to be saved to LDAP entry %s" % self.dn)

        # done
        self.saved_pk = self.pk
        signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists))

    @classmethod
    def scoped(base_class, base_dn):
        """
        Returns a copy of the current class with a different base_dn.
        """
        import new
        import re
        suffix = re.sub('[=,]', '_', base_dn)
        name = "%s_%s" % (base_class.__name__, str(suffix))
        new_class = new.classobj(name, (base_class,), {'base_dn': base_dn, '__module__': base_class.__module__})
        return new_class

<commit_msg>add missing imports<commit_after># -*- coding: utf-8 -*-
#
# django-ldapdb
# Copyright (c) 2009-2010, Bolloré telecom
# All rights reserved.
#
# See AUTHORS file for a full list of contributors.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
#     1. Redistributions of source code must retain the above copyright notice,
#        this list of conditions and the following disclaimer.
#
#     2. Redistributions in binary form must reproduce the above copyright
#        notice, this list of conditions and the following disclaimer in the
#        documentation and/or other materials provided with the distribution.
#
#     3. Neither the name of Bolloré telecom nor the names of its contributors
#        may be used to endorse or promote products derived from this software
#        without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

import ldap
import logging

import django.db.models
from django.db import connections, router
from django.db.models import signals

import ldapdb
from ldapdb.models.query import QuerySet

class ModelBase(django.db.models.base.ModelBase):
    """
    Metaclass for all LDAP models.
    """
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__
        new_class = super_new(cls, name, bases, attrs)

        # patch manager to use our own QuerySet class
        if not new_class._meta.abstract:
            def get_query_set():
                return QuerySet(new_class)
            new_class.objects.get_query_set = get_query_set
            new_class._default_manager.get_query_set = get_query_set

        return new_class

class Model(django.db.models.base.Model):
    """
    Base class for all LDAP models.
    """
    __metaclass__ = ModelBase

    dn = django.db.models.fields.CharField(max_length=200)

    # meta-data
    base_dn = None
    search_scope = ldap.SCOPE_SUBTREE
    object_classes = ['top']

    def __init__(self, *args, **kwargs):
        super(Model, self).__init__(*args, **kwargs)
        self.saved_pk = self.pk

    def _collect_sub_objects(self, seen_objs, parent=None, nullable=False):
        """
        This private API seems to be called by the admin interface in django 1.2
        """
        pk_val = self._get_pk_val()
        seen_objs.add(self.__class__, pk_val, self,
                      type(parent), parent, nullable)

    def build_rdn(self):
        """
        Build the Relative Distinguished Name for this entry.
        """
        bits = []
        for field in self._meta.fields:
            if field.db_column and field.primary_key:
                bits.append("%s=%s" % (field.db_column, getattr(self, field.name)))
        if not len(bits):
            raise Exception("Could not build Distinguished Name")
        return '+'.join(bits)

    def build_dn(self):
        """
        Build the Distinguished Name for this entry.
        """
        return "%s,%s" % (self.build_rdn(), self.base_dn)
        raise Exception("Could not build Distinguished Name")

    def delete(self, using=None):
        """
        Delete this entry.
        """
        using = using or router.db_for_write(self.__class__, instance=self)
        connection = connections[using]
        logging.debug("Deleting LDAP entry %s" % self.dn)
        connection.delete_s(self.dn)
        signals.post_delete.send(sender=self.__class__, instance=self)

    def save(self, using=None):
        """
        Saves the current instance.
        """
        using = using or router.db_for_write(self.__class__, instance=self)
        connection = connections[using]
        if not self.dn:
            # create a new entry
            record_exists = False
            entry = [('objectClass', self.object_classes)]
            new_dn = self.build_dn()

            for field in self._meta.fields:
                if not field.db_column:
                    continue
                value = getattr(self, field.name)
                if value:
                    entry.append((field.db_column, field.get_db_prep_save(value, connection=connection)))

            logging.debug("Creating new LDAP entry %s" % new_dn)
            connection.add_s(new_dn, entry)

            # update object
            self.dn = new_dn

        else:
            # update an existing entry
            record_exists = True
            modlist = []
            orig = self.__class__.objects.get(pk=self.saved_pk)
            for field in self._meta.fields:
                if not field.db_column:
                    continue
                old_value = getattr(orig, field.name, None)
                new_value = getattr(self, field.name, None)
                if old_value != new_value:
                    if new_value:
                        modlist.append((ldap.MOD_REPLACE, field.db_column, field.get_db_prep_save(new_value, connection=connection)))
                    elif old_value:
                        modlist.append((ldap.MOD_DELETE, field.db_column, None))

            if len(modlist):
                # handle renaming
                new_dn = self.build_dn()
                if new_dn != self.dn:
                    logging.debug("Renaming LDAP entry %s to %s" % (self.dn, new_dn))
                    connection.rename_s(self.dn, self.build_rdn())
                    self.dn = new_dn

                logging.debug("Modifying existing LDAP entry %s" % self.dn)
                connection.modify_s(self.dn, modlist)
            else:
                logging.debug("No changes to be saved to LDAP entry %s" % self.dn)

        # done
        self.saved_pk = self.pk
        signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists))

    @classmethod
    def scoped(base_class, base_dn):
        """
        Returns a copy of the current class with a different base_dn.
        """
        import new
        import re
        suffix = re.sub('[=,]', '_', base_dn)
        name = "%s_%s" % (base_class.__name__, str(suffix))
        new_class = new.classobj(name, (base_class,), {'base_dn': base_dn, '__module__': base_class.__module__})
        return new_class

<|endoftext|>


<commit_before>"""Simple AppSetup helper class"""
import os
import logging
from pylons.i18n import ugettext
from genshi.filters import Translator

from pylons import config
from beaker.middleware import SessionMiddleware, CacheMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons.middleware import ErrorHandler, StatusCodeRedirect
from tg import TGApp
from routes import Mapper
from routes.middleware import RoutesMiddleware

from tw.api import make_middleware as tw_middleware

log = logging.getLogger(__name__)

class Bunch(dict):
    """A dictionary that provides attribute-style access."""

    def __getitem__(self, key):
        return  dict.__getitem__(self, key)

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    __setattr__ = dict.__setitem__

    def __delattr__(self, name):
        try:
            del self[name]
        except KeyError:
            raise AttributeError(name)

class AppConfig(Bunch):
    """Class to store application configuration

    This class should have configuration/setup information
    that is NECESSARY for proper application function.
    Deployment specific configuration information should go in
    the config files (eg: development.ini or production.ini)"
    """

    def __init__(self):
        self.stand_alone = True
        self.default_renderer = 'genshi'
        self.auth_backend = None
        self.serve_static = True
        self.paths = Bunch()

    def setup_paths(self):
        root = os.path.dirname(os.path.abspath(self.package.__file__))
        # The default paths:
        paths = dict(root=root,
                     controllers=os.path.join(root, 'controllers'),
                     static_files=os.path.join(root, 'public'),
                     templates=[os.path.join(root, 'templates')])
        # If the user defined custom paths, then use them instead of the
        # default ones:
        paths.update(self.paths)
        self.paths = paths

    def init_config(self, global_conf, app_conf):
        # Initialize config with the basic options
        config.init_app(global_conf, app_conf,
                        package=self.package.__name__,
                        paths=self.paths)
        config.update(self)

    def setup_routes(self):
        """Setup the default TG2 routes

        Overide this and setup your own routes maps if you want to use routes.
        """
        map = Mapper(directory=config['pylons.paths']['controllers'],
                    always_scan=config['debug'])

        # Setup a default route for the error controller:
        map.connect('error/:action/:id', controller='error')
        # Setup a default route for the root of object dispatch
        map.connect('*url', controller='root', action='routes_placeholder')

        config['routes.map'] = map

    def setup_helpers_and_globals(self):
        config['pylons.app_globals'] = self.package.lib.app_globals.Globals()
        config['pylons.h'] = self.package.lib.helpers

    def setup_sa_auth_backend(self):
        defaults = {'users_table':'tg_user',
                    'groups_table':'tg_group',
                    'permissions_table':'tg_permission',
                    'password_encryption_method':'sha1',
                    'form_plugin': None
                   }
        # The developer must have defined a 'sa_auth' section, because
        # values such as the User, Group or Permission classes must be
        # explicitly defined.
        config['sa_auth'] = defaults.update(config['sa_auth'])

    def setup_mako_renderer(self):
        # Create the Mako TemplateLookup, with the default auto-escaping
        from mako.lookup import TemplateLookup
        from tg.render import render_mako

        config['pylons.app_globals'].mako_lookup = TemplateLookup(
            directories=self.paths['templates'],
            module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
            input_encoding='utf-8', output_encoding='utf-8',
            imports=['from webhelpers.html import escape'],
            default_filters=['escape'])
        config['pylons.app_globals'].renderer_functions = render_mako

    def setup_genshi_renderer(self):
        # Create the Genshi TemplateLoader
        from genshi.template import TemplateLoader
        from tg.render import render_genshi

        def template_loaded(template):
            "Plug-in our i18n function to Genshi."
            genshi.template.filters.insert(0, Translator(ugettext))

        config['pylons.app_globals'].genshi_loader = TemplateLoader(
            self.paths['templates'], auto_reload=True)

        config['pylons.app_globals'].renderer_functions = render_genshi

    def setup_jinja_renderer(self):
        # Create the Jinja Environment
        from jinja import ChoiceLoader, Environment, FileSystemLoader
        from tg.render import render_jinja

        config['pylons.app_globals'].jinja_env = Environment(loader=ChoiceLoader(
                [FileSystemLoader(path) for path in self.paths['templates']]))
        # Jinja's unable to request c's attributes without strict_c
        config['pylons.strict_c'] = True

        config['pylons.app_globals'].renderer_functionsloa = render_jinja

    def setup_default_renderer(self):
        #This is specific to buffet, will not be needed later
        config['buffet.template_engines'].pop()
        template_location = '%s.templates' %self.package.__name__
        config.add_template_engine(self.default_renderer,
                                   template_location,  {})

    def setup_sqlalchemy(self):
        # Setup SQLAlchemy database engine
        from sqlalchemy import engine_from_config
        engine = engine_from_config(config, 'sqlalchemy.')
        config['pylons.app_globals'].sa_engine = engine
        # Pass the engine to initmodel, to be able to introspect tables
        self.package.model.init_model(engine)

    def make_load_environment(self):
        """Returns a load_environment function

        The returned load_environment function can be called to configure the
        TurboGears runtime environment for this particular application.  You
        can do this dynamically with multiple nested TG applications if
        nessisary."""

        def load_environment(global_conf, app_conf):
            """Configure the Pylons environment via the ``pylons.config``
            object
            """

            self.setup_paths()
            self.init_config(global_conf, app_conf)
            self.setup_routes()
            self.setup_helpers_and_globals()
            if self.auth_backend == "sqlalchemy":
                self.setup_sa_auth_backend()

            if 'mako' in self.renderers:
                self.setup_mako_renderer()

            if 'genshi' in self.renderers:
                self.setup_genshi_renderer()

            if 'jinja' in self.renderers:
                self.setup_jinja_renderer()

            self.setup_default_renderer()

            if self.use_sqlalchemy:
                self.setup_sqlalchemy()

        return load_environment

    def add_error_middleware(self, global_conf, app):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app)
        else:
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
        return app

    def add_auth_middleware(self, app):
        # configure identity Middleware
        from tg.ext.repoze.who.middleware import make_who_middleware

        auth = self.sa_auth

        app = make_who_middleware(app, config, auth.user_class,
                                  auth.user_criterion,
                                  auth.user_id_column,
                                  auth.dbsession,
                                  )
        return app

    def add_core_middleware(self, app):
        app = RoutesMiddleware(app, config['routes.map'])
        app = SessionMiddleware(app, config)
        app = CacheMiddleware(app, config)
        return app

    def add_tosca_middleware(self, app):
        app = tw_middleware(app, {
            'toscawidgets.framework.default_view':
            self.default_renderer,
            'toscawidgets.middleware.inject_resources': True,
            })
        return app

    def add_static_file_middleware(self, app):
        static_app = StaticURLParser(config['pylons.paths']['static_files'])
        app = Cascade([static_app, app])
        return app

    def commit_veto(self, environ, status, headers):
        """
        This hook is called by repoze.tm in case we want to veto a commit
        for some reason. Return True to force a rollback.

        By default we veto if the response's status code is an error code.
        Override this method, or monkey patch the instancemethod, to fine
        tune this behaviour.
        """
        return not (200 <= int(status.split()[0]) < 400)

    def add_tm_middleware(self, app):
        from repoze.tm import make_tm
        return make_tm(app, self.commit_veto)

    def add_dbsession_remover_middleware(self, app):
        def remover(environ, start_response):
            try:
                return app(environ, start_response)
            finally:
                log.debug("Removing DBSession from current thread")
                self.DBSession.remove()
        return remover

    def setup_tg_wsgi_app(self, load_environment):
        """Create a base TG app, with all the standard middleware

        ``load_environment``
            A required callable, which sets up the basic application
            evironment.
        ``setup_vars``
            A dictionary any special values nessisary for setting up
            the base wsgi app.
        """

        def make_base_app(global_conf, wrap_app=None, full_stack=True, **app_conf):
            """Create a tg WSGI application and return it

            ``global_conf``
                The inherited configuration for this application. Normally from
                the [DEFAULT] section of the Paste ini file.

            ``full_stack``
                Whether or not this application provides a full WSGI stack (by
                default, meaning it handles its own exceptions and errors).
                Disable full_stack when this application is "managed" by
                another WSGI middleware.

            ``app_conf``
                The application's local configuration. Normally specified in the
                [app:<name>] section of the Paste ini file (where <name>
                defaults to main).
            """
            # Configure the Pylons environment
            load_environment(global_conf, app_conf)
            app = TGApp()
            if wrap_app:
                wrap_app(app)
            app = self.add_core_middleware(app)
            app = self.add_tosca_middleware(app)

            if self.auth_backend == "sqlalchemy":
                app = self.add_auth_middleware(app)

            app = self.add_tm_middleware(app)
            if self.use_sqlalchemy:
                if not hasattr(self, 'DBSession'):
                    # If the user hasn't specified a scoped_session, assume
                    # he/she uses the default DBSession in model
                    self.DBSession = self.model.DBSession
                app = self.add_dbsession_remover_middleware(app)

            if asbool(full_stack):
                # This should nevery be true for internal nested apps
                app = self.add_error_middleware(global_conf, app)

            # Establish the Registry for this application
            app = RegistryManager(app)

            # Static files (If running in production, and Apache or another
            # web server is serving static files)
            if self.serve_static:
                app = self.add_static_file_middleware(app)
            return app

        return make_base_app
<commit_msg>Fixes issue with AppConfig.setup_mako_renderer() still using app_conf to find template path instead of self.paths<commit_after>"""Simple AppSetup helper class"""
import os
import logging
from pylons.i18n import ugettext
from genshi.filters import Translator

from pylons import config
from beaker.middleware import SessionMiddleware, CacheMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons.middleware import ErrorHandler, StatusCodeRedirect
from tg import TGApp
from routes import Mapper
from routes.middleware import RoutesMiddleware

from tw.api import make_middleware as tw_middleware

log = logging.getLogger(__name__)

class Bunch(dict):
    """A dictionary that provides attribute-style access."""

    def __getitem__(self, key):
        return  dict.__getitem__(self, key)

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    __setattr__ = dict.__setitem__

    def __delattr__(self, name):
        try:
            del self[name]
        except KeyError:
            raise AttributeError(name)

class AppConfig(Bunch):
    """Class to store application configuration

    This class should have configuration/setup information
    that is NECESSARY for proper application function.
    Deployment specific configuration information should go in
    the config files (eg: development.ini or production.ini)"
    """

    def __init__(self):
        self.stand_alone = True
        self.default_renderer = 'genshi'
        self.auth_backend = None
        self.serve_static = True
        self.paths = Bunch()

    def setup_paths(self):
        root = os.path.dirname(os.path.abspath(self.package.__file__))
        # The default paths:
        paths = dict(root=root,
                     controllers=os.path.join(root, 'controllers'),
                     static_files=os.path.join(root, 'public'),
                     templates=[os.path.join(root, 'templates')])
        # If the user defined custom paths, then use them instead of the
        # default ones:
        paths.update(self.paths)
        self.paths = paths

    def init_config(self, global_conf, app_conf):
        # Initialize config with the basic options
        config.init_app(global_conf, app_conf,
                        package=self.package.__name__,
                        paths=self.paths)
        config.update(self)

    def setup_routes(self):
        """Setup the default TG2 routes

        Overide this and setup your own routes maps if you want to use routes.
        """
        map = Mapper(directory=config['pylons.paths']['controllers'],
                    always_scan=config['debug'])

        # Setup a default route for the error controller:
        map.connect('error/:action/:id', controller='error')
        # Setup a default route for the root of object dispatch
        map.connect('*url', controller='root', action='routes_placeholder')

        config['routes.map'] = map

    def setup_helpers_and_globals(self):
        config['pylons.app_globals'] = self.package.lib.app_globals.Globals()
        config['pylons.h'] = self.package.lib.helpers

    def setup_sa_auth_backend(self):
        defaults = {'users_table':'tg_user',
                    'groups_table':'tg_group',
                    'permissions_table':'tg_permission',
                    'password_encryption_method':'sha1',
                    'form_plugin': None
                   }
        # The developer must have defined a 'sa_auth' section, because
        # values such as the User, Group or Permission classes must be
        # explicitly defined.
        config['sa_auth'] = defaults.update(config['sa_auth'])

    def setup_mako_renderer(self):
        # Create the Mako TemplateLookup, with the default auto-escaping
        from mako.lookup import TemplateLookup
        from tg.render import render_mako

        config['pylons.app_globals'].mako_lookup = TemplateLookup(
            directories=self.paths['templates'],
            module_directory=self.paths['templates'],
            input_encoding='utf-8', output_encoding='utf-8',
            imports=['from webhelpers.html import escape'],
            default_filters=['escape'])
        config['pylons.app_globals'].renderer_functions = render_mako

    def setup_genshi_renderer(self):
        # Create the Genshi TemplateLoader
        from genshi.template import TemplateLoader
        from tg.render import render_genshi

        def template_loaded(template):
            "Plug-in our i18n function to Genshi."
            genshi.template.filters.insert(0, Translator(ugettext))

        config['pylons.app_globals'].genshi_loader = TemplateLoader(
            self.paths['templates'], auto_reload=True)

        config['pylons.app_globals'].renderer_functions = render_genshi

    def setup_jinja_renderer(self):
        # Create the Jinja Environment
        from jinja import ChoiceLoader, Environment, FileSystemLoader
        from tg.render import render_jinja

        config['pylons.app_globals'].jinja_env = Environment(loader=ChoiceLoader(
                [FileSystemLoader(path) for path in self.paths['templates']]))
        # Jinja's unable to request c's attributes without strict_c
        config['pylons.strict_c'] = True

        config['pylons.app_globals'].renderer_functionsloa = render_jinja

    def setup_default_renderer(self):
        #This is specific to buffet, will not be needed later
        config['buffet.template_engines'].pop()
        template_location = '%s.templates' %self.package.__name__
        config.add_template_engine(self.default_renderer,
                                   template_location,  {})

    def setup_sqlalchemy(self):
        # Setup SQLAlchemy database engine
        from sqlalchemy import engine_from_config
        engine = engine_from_config(config, 'sqlalchemy.')
        config['pylons.app_globals'].sa_engine = engine
        # Pass the engine to initmodel, to be able to introspect tables
        self.package.model.init_model(engine)

    def make_load_environment(self):
        """Returns a load_environment function

        The returned load_environment function can be called to configure the
        TurboGears runtime environment for this particular application.  You
        can do this dynamically with multiple nested TG applications if
        nessisary."""

        def load_environment(global_conf, app_conf):
            """Configure the Pylons environment via the ``pylons.config``
            object
            """

            self.setup_paths()
            self.init_config(global_conf, app_conf)
            self.setup_routes()
            self.setup_helpers_and_globals()
            if self.auth_backend == "sqlalchemy":
                self.setup_sa_auth_backend()

            if 'mako' in self.renderers:
                self.setup_mako_renderer()

            if 'genshi' in self.renderers:
                self.setup_genshi_renderer()

            if 'jinja' in self.renderers:
                self.setup_jinja_renderer()

            self.setup_default_renderer()

            if self.use_sqlalchemy:
                self.setup_sqlalchemy()

        return load_environment

    def add_error_middleware(self, global_conf, app):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app)
        else:
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
        return app

    def add_auth_middleware(self, app):
        # configure identity Middleware
        from tg.ext.repoze.who.middleware import make_who_middleware

        auth = self.sa_auth

        app = make_who_middleware(app, config, auth.user_class,
                                  auth.user_criterion,
                                  auth.user_id_column,
                                  auth.dbsession,
                                  )
        return app

    def add_core_middleware(self, app):
        app = RoutesMiddleware(app, config['routes.map'])
        app = SessionMiddleware(app, config)
        app = CacheMiddleware(app, config)
        return app

    def add_tosca_middleware(self, app):
        app = tw_middleware(app, {
            'toscawidgets.framework.default_view':
            self.default_renderer,
            'toscawidgets.middleware.inject_resources': True,
            })
        return app

    def add_static_file_middleware(self, app):
        static_app = StaticURLParser(config['pylons.paths']['static_files'])
        app = Cascade([static_app, app])
        return app

    def commit_veto(self, environ, status, headers):
        """
        This hook is called by repoze.tm in case we want to veto a commit
        for some reason. Return True to force a rollback.

        By default we veto if the response's status code is an error code.
        Override this method, or monkey patch the instancemethod, to fine
        tune this behaviour.
        """
        return not (200 <= int(status.split()[0]) < 400)

    def add_tm_middleware(self, app):
        from repoze.tm import make_tm
        return make_tm(app, self.commit_veto)

    def add_dbsession_remover_middleware(self, app):
        def remover(environ, start_response):
            try:
                return app(environ, start_response)
            finally:
                log.debug("Removing DBSession from current thread")
                self.DBSession.remove()
        return remover

    def setup_tg_wsgi_app(self, load_environment):
        """Create a base TG app, with all the standard middleware

        ``load_environment``
            A required callable, which sets up the basic application
            evironment.
        ``setup_vars``
            A dictionary any special values nessisary for setting up
            the base wsgi app.
        """

        def make_base_app(global_conf, wrap_app=None, full_stack=True, **app_conf):
            """Create a tg WSGI application and return it

            ``global_conf``
                The inherited configuration for this application. Normally from
                the [DEFAULT] section of the Paste ini file.

            ``full_stack``
                Whether or not this application provides a full WSGI stack (by
                default, meaning it handles its own exceptions and errors).
                Disable full_stack when this application is "managed" by
                another WSGI middleware.

            ``app_conf``
                The application's local configuration. Normally specified in the
                [app:<name>] section of the Paste ini file (where <name>
                defaults to main).
            """
            # Configure the Pylons environment
            load_environment(global_conf, app_conf)
            app = TGApp()
            if wrap_app:
                wrap_app(app)
            app = self.add_core_middleware(app)
            app = self.add_tosca_middleware(app)

            if self.auth_backend == "sqlalchemy":
                app = self.add_auth_middleware(app)

            app = self.add_tm_middleware(app)
            if self.use_sqlalchemy:
                if not hasattr(self, 'DBSession'):
                    # If the user hasn't specified a scoped_session, assume
                    # he/she uses the default DBSession in model
                    self.DBSession = self.model.DBSession
                app = self.add_dbsession_remover_middleware(app)

            if asbool(full_stack):
                # This should nevery be true for internal nested apps
                app = self.add_error_middleware(global_conf, app)

            # Establish the Registry for this application
            app = RegistryManager(app)

            # Static files (If running in production, and Apache or another
            # web server is serving static files)
            if self.serve_static:
                app = self.add_static_file_middleware(app)
            return app

        return make_base_app
<|endoftext|>


<commit_before>from functools import reduce
# -*- coding: utf-8 -*-
# Copyright (c) 2015 The Pycroft Authors. See the AUTHORS file.
# This file is part of the Pycroft project and licensed under the terms of
# the Apache License, Version 2.0. See the LICENSE file for details.
member_props = {"network_access": True,
                "semester_fee": True,
                "late_fee": True,
                "registration_fee": True,
                "mail": True}

org_props = {"user_show": True,
             "user_change": True,
             "user_mac_change": True,
             "finance_show": True,
             "infrastructure_show": True,
             "facilities_show": True,
             "groups_show": True,
             "groups_change_membership": True,
             "groups_traffic_show": True}

finance_admin_props = {"finance_change": True}

group_admin_props = {"groups_show": True,
                     "groups_change_membership": True,
                     "groups_change": True,
                     "groups_traffic_show": True,
                     "groups_traffic_change": True}

infra_admin_props = {"infrastructure_show": True,
                     "infrastructure_change": True,
                     "facilities_show": True,
                     "facilities_change": True}

group_props = {
    "caretaker": ("Hausmeister", {"network_access": True}),

    "external": ("Extern", {'network_access': True}),

    "member": ("Mitglied", member_props),

    "org": ("Org", org_props),

    "finance_admin": ("Finanzer", finance_admin_props),

    "suspended": ("Gesperrt", {"network_access": False}),

    "violator": ("Verstoß gegen Netzordnung", {"network_access": False,
                                              "violation": True}),

    # nutzer ∈ member \ away = normales mitglied, mailmitgliedschaft, semesterbeitrag
    #        ∈ away ∩ member = temporär ausgezogen, mailmitgliedschaft, reduzierter semesterbeitrag
    #        ∈ away \ member = permanent ausgezogen, mailmitgliedschaft, reduzierter semesterbeitrag
    #        ∉ away ∪ member = permanent ausgezogen, keine mailmitgliedschaft, kein semesterbeitrag
    "away": ("Ausgezogen", {"network_access": False,
                            "late_fee": False,
                            "semester_fee": True,
                            "reduced_semester_fee": True,
                            "mail": True}),

    "moved_from_division": ("Umzug aus anderer Sektion", {"registration_fee": False}),

    "already_paid": ("Semesterbeitrag in anderer Sektion entrichtet", {"semester_fee": False}),

    "root": ("Root", reduce(lambda d1,d2: dict(d1, **d2), [org_props,
                                                           finance_admin_props,
                                                           group_admin_props,
                                                           infra_admin_props,
                                                           {'mail': True}
                                                           ]))
}

# Memberships being added due to the current status
status_groups_map = {
    1: ("member", "usertraffic"),  # bezahlt, ok
    2: ("member", "usertraffic"),  # angemeldet, aber nicht bezahlt
    3: ("away",),    # nicht bezahlt, hat nur Mail
    4: ("member", "usertraffic"),  # angemeldet, nicht bezahlt, 2. Warnung
    5: ("member", "suspended", "usertraffic"),  # angemeldet, nicht bezahlt, gesperrt
    6: ("away",),  # angemeldet, gesperrt (ruhend)
    7: ("member", "violator"),  # angemeldet, gesperrt (Verstoss gegen Netzordnung)
    8: (),  # ausgezogen, gesperrt
    9: (),  # Ex-Aktiver
    10: ("away",), # E-Mail, ehemals IP
    11: (),  # uebrig in Wu die in Renovierung
    12: ("member", "usertraffic")  # gesperrt wegen Trafficueberschreitung
}

site_name_map = {
    0: u"Wundtstraße/Zellescher Weg",
    1: u"Borsbergstraße",
    2: u"Zeunerstraße",
    3: u"Budapester Straße",
    4: "Fritz-Löffler-Straße",
    5: "Gret-Palucca-Straße",
}

building_site_map = {
    # building_id: site_id
    1: 0,  # Wu5
    2: 0,  # Wu7
    3: 0,  # Wu9
    4: 0,  # Wu11
    5: 0,  # Wu1
    6: 0,  # Wu3
    7: 0,  # ZW41
    8: 0,  # ZW41A
    9: 0,  # ZW41B
    10: 0,  # ZW41C
    11: 0,  # ZW41D
    12: 1,  # Bor34
    13: 2,  # Zeu1f
    14: 3,  # Bu22
    15: 3,  # Bu24
    16: 4,  # FL16
    17: 5,  # GPS11
}

building_subnets_map = {
    # building_id: subnet_id
    1: [6],  # Wu5
    2: [3],  # Wu7
    3: [8],  # Wu9
    4: [7],  # Wu11
    5: [1],  # Wu1
    6: [2],  # Wu3
    7: [4],  # ZW41
    8: [4],  # ZW41A
    9: [4],  # ZW41B
    10: [4],  # ZW41C
    11: [4],  # ZW41D
    12: [10],  # Bor34
    13: [11, 12],  # Zeu1f
    14: [13],  # Bu22
    15: [14],  # Bu24
    16: [15],  # FL16
    17: [16],  # GPS11
}

vlan_name_vid_map = {
    # Vlan_name: VLAN ID (on the switches)
    'Wu1': 11,
    'Wu3': 13,
    'Wu5': 15,
    'Wu7': 17,
    'Wu9': 19,
    'Wu11': 5,
    'ZW41': 41,
    'Bor34': 34,
    'Servernetz': 22,
    'UNEP': 348,
    'Zeu1f': 234,
    'Bu22': 18,
    'Bu24': 29,
    'FL16': 35,
    'GPS11': 32,
}
<commit_msg>Rename `Ausgezogen` group on import<commit_after>from functools import reduce
# -*- coding: utf-8 -*-
# Copyright (c) 2015 The Pycroft Authors. See the AUTHORS file.
# This file is part of the Pycroft project and licensed under the terms of
# the Apache License, Version 2.0. See the LICENSE file for details.
member_props = {"network_access": True,
                "semester_fee": True,
                "late_fee": True,
                "registration_fee": True,
                "mail": True}

org_props = {"user_show": True,
             "user_change": True,
             "user_mac_change": True,
             "finance_show": True,
             "infrastructure_show": True,
             "facilities_show": True,
             "groups_show": True,
             "groups_change_membership": True,
             "groups_traffic_show": True}

finance_admin_props = {"finance_change": True}

group_admin_props = {"groups_show": True,
                     "groups_change_membership": True,
                     "groups_change": True,
                     "groups_traffic_show": True,
                     "groups_traffic_change": True}

infra_admin_props = {"infrastructure_show": True,
                     "infrastructure_change": True,
                     "facilities_show": True,
                     "facilities_change": True}

group_props = {
    "caretaker": ("Hausmeister", {"network_access": True}),

    "external": ("Extern", {'network_access': True}),

    "member": ("Mitglied", member_props),

    "org": ("Org", org_props),

    "finance_admin": ("Finanzer", finance_admin_props),

    "suspended": ("Gesperrt", {"network_access": False}),

    "violator": ("Verstoß gegen Netzordnung", {"network_access": False,
                                              "violation": True}),

    # nutzer ∈ member \ away = normales mitglied, mailmitgliedschaft, semesterbeitrag
    #        ∈ away ∩ member = temporär ausgezogen, mailmitgliedschaft, reduzierter semesterbeitrag
    #        ∈ away \ member = permanent ausgezogen, mailmitgliedschaft, reduzierter semesterbeitrag
    #        ∉ away ∪ member = permanent ausgezogen, keine mailmitgliedschaft, kein semesterbeitrag
    "away": ("Ausgezogen (obsolet, ehem. „mail“)", {"network_access": False,
                            "late_fee": False,
                            "semester_fee": True,
                            "reduced_semester_fee": True,
                            "mail": True}),

    "moved_from_division": ("Umzug aus anderer Sektion", {"registration_fee": False}),

    "already_paid": ("Semesterbeitrag in anderer Sektion entrichtet", {"semester_fee": False}),

    "root": ("Root", reduce(lambda d1,d2: dict(d1, **d2), [org_props,
                                                           finance_admin_props,
                                                           group_admin_props,
                                                           infra_admin_props,
                                                           {'mail': True}
                                                           ]))
}

# Memberships being added due to the current status
status_groups_map = {
    1: ("member", "usertraffic"),  # bezahlt, ok
    2: ("member", "usertraffic"),  # angemeldet, aber nicht bezahlt
    3: ("away",),    # nicht bezahlt, hat nur Mail
    4: ("member", "usertraffic"),  # angemeldet, nicht bezahlt, 2. Warnung
    5: ("member", "suspended", "usertraffic"),  # angemeldet, nicht bezahlt, gesperrt
    6: ("away",),  # angemeldet, gesperrt (ruhend)
    7: ("member", "violator"),  # angemeldet, gesperrt (Verstoss gegen Netzordnung)
    8: (),  # ausgezogen, gesperrt
    9: (),  # Ex-Aktiver
    10: ("away",), # E-Mail, ehemals IP
    11: (),  # uebrig in Wu die in Renovierung
    12: ("member", "usertraffic")  # gesperrt wegen Trafficueberschreitung
}

site_name_map = {
    0: u"Wundtstraße/Zellescher Weg",
    1: u"Borsbergstraße",
    2: u"Zeunerstraße",
    3: u"Budapester Straße",
    4: "Fritz-Löffler-Straße",
    5: "Gret-Palucca-Straße",
}

building_site_map = {
    # building_id: site_id
    1: 0,  # Wu5
    2: 0,  # Wu7
    3: 0,  # Wu9
    4: 0,  # Wu11
    5: 0,  # Wu1
    6: 0,  # Wu3
    7: 0,  # ZW41
    8: 0,  # ZW41A
    9: 0,  # ZW41B
    10: 0,  # ZW41C
    11: 0,  # ZW41D
    12: 1,  # Bor34
    13: 2,  # Zeu1f
    14: 3,  # Bu22
    15: 3,  # Bu24
    16: 4,  # FL16
    17: 5,  # GPS11
}

building_subnets_map = {
    # building_id: subnet_id
    1: [6],  # Wu5
    2: [3],  # Wu7
    3: [8],  # Wu9
    4: [7],  # Wu11
    5: [1],  # Wu1
    6: [2],  # Wu3
    7: [4],  # ZW41
    8: [4],  # ZW41A
    9: [4],  # ZW41B
    10: [4],  # ZW41C
    11: [4],  # ZW41D
    12: [10],  # Bor34
    13: [11, 12],  # Zeu1f
    14: [13],  # Bu22
    15: [14],  # Bu24
    16: [15],  # FL16
    17: [16],  # GPS11
}

vlan_name_vid_map = {
    # Vlan_name: VLAN ID (on the switches)
    'Wu1': 11,
    'Wu3': 13,
    'Wu5': 15,
    'Wu7': 17,
    'Wu9': 19,
    'Wu11': 5,
    'ZW41': 41,
    'Bor34': 34,
    'Servernetz': 22,
    'UNEP': 348,
    'Zeu1f': 234,
    'Bu22': 18,
    'Bu24': 29,
    'FL16': 35,
    'GPS11': 32,
}
<|endoftext|>


<commit_before>import scipy as sp
import matplotlib.pyplot as plt

""" Some useful formulae:

-Beam propagation:
Rayleigh range = pi * w_0**2 / lambda
Radius of the beam w(z)= w_0 * sqrt(1+ (z/zR)**2)

-Beam transformation (for thin lenses):
--Location and size of the beam waist in the output
denom=((d_in/f-1)**2 +(zR/f)**2)
d_out= f * (1+ (d_in/f -1)/denom)
w_0out= w_0in/sqrt(denom)

--Magnification:   M= w_0out/w_0in = 1/sqrt(denom)
--Maximum magnification: f/z_c
--Size at the focus: w(d_out==f)= f*w_0in/zR_in     (only the waist if d_in=f)

-Gaussian Beam telescope:
Pair of focusing elements separated by ther focal distances

w_0out= w_0in * f2/f1    (wavelength independent)

d_out= f2/f2 *(f1+f2-d_in* f2/f1) """

import scipy as sp
import matplotlib.pyplot as plt

def RayleighR(self):
    return sp.pi*self.w0**2/self.lambd

class BeamSection:
    """ Section of the beam characterized by a waist, a wavelength and the position of the waist.
    """

    def __init__(self, wavelength, waist,position):
        """ Initialize the values of position, waist and wavelength.
        It also creates the Rayleigh range zR

        """
        self.z0 = position
        self.w0 = waist
        self.lambd = wavelength
        self.zR = sp.pi * waist**2 / wavelength

    def waist(self, z):
        """ Outputs the waist of the gaussian beam at a position z.  The position can be an array """
        return self.w0* sp.sqrt(1 + (z-self.z0)**2 /self.zR**2)

    def divergence(self):
        """ Calculates the divergence of the beam.  The full angular spread is twice this number """
        return self.lambd/(sp.pi * self.w0)

    def transformByLens(self, f, z):
        """ Transforms the Gaussian beam to one "after" the lens with focal f placed at z"""
        d_in = z - self.z0
        #denom is the common denominator of the changes in z0 and w0
        denom = (d_in/f-1)**2 + (self.zR/f)**2
        d_out = f * (1+(d_in/f - 1) / denom)
        #Change the parameters of the Gaussian
        z0 = z + d_out
        w0 = self.w0/sp.sqrt(denom)
        return BeamSection(self.lambd,w0,z0)

    def report(self):
        """ Print some parameters"""
        print "##############################"
        print "Waist= {0:e}".format(self.w0)
        print "Position= {0:e}".format(self.z0)
        print "Rayleigh Range = {0:e}".format(self.zR)
        print "##############################"

    def parameters(self):
        return (self.lambd, self.w0, self.z0)

class BeamPropagation():
    """ Collection of Gaussian beams with lenses. """

    ####################
    #  Definition
    ####################

    def __init__(self,originalBeamParams,lenses):
        """ Creates a collection of beam+lenses to be used by the object.

        -OriginalBeamParams is a vector that we can pass a BeamSection object as
        BeamSection(*OriginalBeamParams) to create the initial beam.

        -lenses is a matrix of (2xN) elements where the second index cycles through
        the elements, lenses[1,:] are the positions and lenses[0,:] are the focals.

        """
        # In future implementations, "lenses" can be "transformations", as a collection
        # of objects with certain parameters that are passed to the initial beam to create
        # different sections. The BeamSection, therefore, should admit a method __transform__
        # that takes one of these objects and creates another BeamSection object.
        distancesList=lenses[1,:]
        focalsList=lenses[0,:]

        #The parameters of the lenses are stored and sorted according to the distances
        self.lensPositions = distancesList[distancesList.argsort()]
        self.lensFocals = focalsList[distancesList.argsort()]
        self.z0 = originalBeamParams[2]
        self.w0 = originalBeamParams[1]
        self.amountElements = len(self.lensPositions)
        self.amountSections = self.amountElements + 1

        #Obtain the intervals of application for each of the beam sections
        beamsLimits= sp.zeros((2,self.amountSections))
        beamsLimits[0,0]=-sp.inf
        beamsLimits[0,1:]=self.lensPositions
        beamsLimits[1,:-1]=self.lensPositions
        beamsLimits[1,-1]=sp.inf
        self.beamsLimits = beamsLimits

        #CHANGE: make sure that the waist is between lenses. Now, only make sure that the
        #position of the waist is smaller than the rest
        if self.z0 > self.lensPositions.all():
            raise Exception('The position of the initial waist is not smaller than the positions of the lenses')
        else:
            #Create a list of beam parameters
            beamParams=sp.zeros((3,self.amountSections))
            beamParams[:,0]=originalBeamParams
            parms=originalBeamParams
            for ii in range(0,self.amountElements):
                oldBeam=BeamSection(*parms)
                newBeam=oldBeam.transformByLens(self.lensFocals[ii], self.lensPositions[ii])
                beamParams[:,ii+1]=newBeam.parameters()
                parms=beamParams[:,ii+1]
                oldBeam=newBeam
            self.beamParams=beamParams

    def waist(self,z):
        """ Obtain the waist of the beam at a point z.
        Not suitable for arrays

        """
        #The beamsLimits is a matrix with the upper and lower limits
        #of the intervales for each section. If we compare the matrix
        #to the z value we are interested in and sum them, only the
        #right section will obtain a "1" (the value will only be greater
        #than the lower limit)
        index=sp.arange(0,self.amountSections)[sum(z>=prop.beamsLimits)==1]
        #Then, we obtain the waist from the appropriate BeamSection
        return BeamSection(*self.beamParams[:,index]).waist(z)

    ####################
    # Report methods
    ####################

    def reportLenses(self):
        print " Position    Focal   "
        print "---------------------"
        for ii in range(self.amountElements):
            print "{0:10.2e} {1:10.2e}".format(self.lensPositions[ii], self.lensFocals[ii])
        print "====================="
    def reportParameters(self):
        print " Lambd         w0         z0   "
        print "-------------------------------"
        for ii in range(self.amountSections):
            print "{0:10.2e} {1:10.2e} {2:10.2e}".format(self.beamParams[0,ii], self.beamParams[1,ii], self.beamParams[2,ii])
        print "====================="

    ####################
    # Plotting methods
    ####################

    def plotFull(self,xmin,xmax):
        NUMBER_OF_STEPS=300
        #xmax=(self.lensPositions[-1] + self.lensFocals[-1])
        #xmin=self.z0

        zmin=self.z0
        zmax= self.lensPositions[-1] + self.lensFocals[-1]
        z=sp.arange(zmin,zmax,(zmax-zmin)/NUMBER_OF_STEPS)
        beamWidth=sp.zeros(len(z))

        plt.figure()

        #index=sp.arange(0,self.amountSections)[sum(z>prop.beamsLimits)==1]
        #BeamSection(*self.beamParams[:,index]).waiplst(z)
        for ii in range(self.amountSections):
            localIndices=((z>self.beamsLimits[0,ii]) &(z<=self.beamsLimits[1,ii]))
            zlocal= z[localIndices]
            beamWidth[localIndices]=BeamSection(*self.beamParams[:,ii]).waist(zlocal)
        plt.plot(z,beamWidth)
        plt.xlabel('z (m)')
        plt.ylabel('Width (m)')

        for ii in range(self.amountElements):
            plt.axvline(x=self.lensPositions[ii])

#--Location and size of the beam waist in the output
#denom=((d_in/f-1)**2 +(zR/f)**2)
#d_out= f * (1+ (d_in/f -1)/denom)
#w_0out= w_0in/sqrt(denom)

def denominator(d_in,f,zR):
    return (d_in/f -1)**2 +(zR/f)**2

def propagated_waist(w_0,z,zR,sz):
    return w_0*sp.sqrt(1+((z-sz)/zR)**2)

def rayleigh_range(waist,lambd):
    return sp.pi*waist**2/lambd

lambd=780.24e-9
pi=sp.pi

#We look for a Rayleigh range (which will be bigger than the waist in our wavelength) of less than 5 um
zR0=5e-6

#Therefore, the waist we are looking for is
w_0=sp.sqrt(zR0*lambd/pi)

#The maximum magnification we can get from a lens of focal f of a beam with rayleigh range zR is
f=32e-3
Mmax=1/sp.sqrt(denominator(f,f,zR0))
#if the waist is located at a distance d_in=f from the lens.
#That corresponds to a waist
w_1=w_0*Mmax
zR1=rayleigh_range(w_1,lambd)
#If we propagate that beam a length L forwards, the beam waist will be
L=50e-2
w_1prop=propagated_waist(w_1,L,zR1,0)

print 'Rayleigh Range: ',zR
print 'Final waist: ',w_0
print 'Maximum magnification for a lens with focal {0:.2e}: {1:.2e}. This, in turn, will give an initial waist of {2:.3e}'.format(f,Mmax,w_1)
print 'If that waist is located at a distance {0:.2e} from the minimum waist, the *new* waist will be {1:.3e}.'.format(L,w_1prop)

##############################
#Try object

myBeam=BeamSection(780.24e-9,1.1e-6,0)
myBeam2=myBeam.transformByLens(32e-3,32e-3)
myBeam3=myBeam2.transformByLens(32e-3,96e-3)
myBeam.report()
myBeam2.report()
myBeam3.report()
#print myBeam.z0, myBeam.lambd, myBeam.w0, myBeam.zR
#print myBeam3.z0, myBeam3.lambd, myBeam3.w0, myBeam3.zR

z=sp.arange(-10e-6,150e-3,1e-4)
#z=sp.arange(-10e-6,100e-6,1e-6)
plt.plot(z,myBeam.waist(z),label='first')
plt.plot(z,myBeam2.waist(z),label='second')
plt.plot(z,myBeam3.waist(z),label='third')

plt.legend()
plt.show()
<commit_msg>Now, it works<commit_after>import scipy as sp
import matplotlib.pyplot as plt

""" Some useful formulae:

-Beam propagation:
Rayleigh range = pi * w_0**2 / lambda
Radius of the beam w(z)= w_0 * sqrt(1+ (z/zR)**2)

-Beam transformation (for thin lenses):
--Location and size of the beam waist in the output
denom=((d_in/f-1)**2 +(zR/f)**2)
d_out= f * (1+ (d_in/f -1)/denom)
w_0out= w_0in/sqrt(denom)

--Magnification:   M= w_0out/w_0in = 1/sqrt(denom)
--Maximum magnification: f/z_c
--Size at the focus: w(d_out==f)= f*w_0in/zR_in     (only the waist if d_in=f)

-Gaussian Beam telescope:
Pair of focusing elements separated by ther focal distances

w_0out= w_0in * f2/f1    (wavelength independent)

d_out= f2/f2 *(f1+f2-d_in* f2/f1) """

import scipy as sp
import matplotlib.pyplot as plt

def RayleighR(self):
    return sp.pi*self.w0**2/self.lambd

class BeamSection:
    """ Section of the beam characterized by a waist, a wavelength and the position of the waist.
    """

    def __init__(self, wavelength, waist,position):
        """ Initialize the values of position, waist and wavelength.
        It also creates the Rayleigh range zR

        """
        self.z0 = position
        self.w0 = waist
        self.lambd = wavelength
        self.zR = sp.pi * waist**2 / wavelength

    def waist(self, z):
        """ Outputs the waist of the gaussian beam at a position z.  The position can be an array """
        return self.w0* sp.sqrt(1 + (z-self.z0)**2 /self.zR**2)

    def divergence(self):
        """ Calculates the divergence of the beam.  The full angular spread is twice this number """
        return self.lambd/(sp.pi * self.w0)

    def transformByLens(self, f, z):
        """ Transforms the Gaussian beam to one "after" the lens with focal f placed at z"""
        d_in = z - self.z0
        #denom is the common denominator of the changes in z0 and w0
        denom = (d_in/f-1)**2 + (self.zR/f)**2
        d_out = f * (1+(d_in/f - 1) / denom)
        #Change the parameters of the Gaussian
        z0 = z + d_out
        w0 = self.w0/sp.sqrt(denom)
        return BeamSection(self.lambd,w0,z0)

    def report(self):
        """ Print some parameters"""
        print "##############################"
        print "Waist= {0:e}".format(self.w0)
        print "Position= {0:e}".format(self.z0)
        print "Rayleigh Range = {0:e}".format(self.zR)
        print "##############################"

    def parameters(self):
        return (self.lambd, self.w0, self.z0)

class BeamPropagation():
    """ Collection of Gaussian beams with lenses. """

    ####################
    #  Definition
    ####################

    def __init__(self,originalBeamParams,lenses):
        """ Creates a collection of beam+lenses to be used by the object.

        -OriginalBeamParams is a vector that we can pass a BeamSection object as
        BeamSection(*OriginalBeamParams) to create the initial beam.

        -lenses is a matrix of (2xN) elements where the second index cycles through
        the elements, lenses[1,:] are the positions and lenses[0,:] are the focals.

        """
        # In future implementations, "lenses" can be "transformations", as a collection
        # of objects with certain parameters that are passed to the initial beam to create
        # different sections. The BeamSection, therefore, should admit a method __transform__
        # that takes one of these objects and creates another BeamSection object.
        distancesList=lenses[1,:]
        focalsList=lenses[0,:]

        #The parameters of the lenses are stored and sorted according to the distances
        self.lensPositions = distancesList[distancesList.argsort()]
        self.lensFocals = focalsList[distancesList.argsort()]
        self.z0 = originalBeamParams[2]
        self.w0 = originalBeamParams[1]
        self.amountElements = len(self.lensPositions)
        self.amountSections = self.amountElements + 1

        #Obtain the intervals of application for each of the beam sections
        beamsLimits= sp.zeros((2,self.amountSections))
        beamsLimits[0,0]=-sp.inf
        beamsLimits[0,1:]=self.lensPositions
        beamsLimits[1,:-1]=self.lensPositions
        beamsLimits[1,-1]=sp.inf
        self.beamsLimits = beamsLimits

        #CHANGE: make sure that the waist is between lenses. Now, only make sure that the
        #position of the waist is smaller than the rest
        if self.z0 > self.lensPositions.all():
            raise Exception('The position of the initial waist is not smaller than the positions of the lenses')
        else:
            #Create a list of beam parameters
            beamParams=sp.zeros((3,self.amountSections))
            beamParams[:,0]=originalBeamParams
            parms=originalBeamParams
            for ii in range(0,self.amountElements):
                oldBeam=BeamSection(*parms)
                newBeam=oldBeam.transformByLens(self.lensFocals[ii], self.lensPositions[ii])
                beamParams[:,ii+1]=newBeam.parameters()
                parms=beamParams[:,ii+1]
                oldBeam=newBeam
            self.beamParams=beamParams

    def waist(self,z):
        """ Obtain the waist of the beam at a point z.
        Not suitable for arrays

        """
        #The beamsLimits is a matrix with the upper and lower limits
        #of the intervales for each section. If we compare the matrix
        #to the z value we are interested in and sum them, only the
        #right section will obtain a "1" (the value will only be greater
        #than the lower limit)
        index=sp.arange(0,self.amountSections)[sum(z>=prop.beamsLimits)==1]
        #Then, we obtain the waist from the appropriate BeamSection
        return BeamSection(*self.beamParams[:,index]).waist(z)

    ####################
    # Report methods
    ####################

    def reportLenses(self):
        print " Position    Focal   "
        print "---------------------"
        for ii in range(self.amountElements):
            print "{0:10.2e} {1:10.2e}".format(self.lensPositions[ii], self.lensFocals[ii])
        print "====================="
    def reportParameters(self):
        print " Lambd         w0         z0   "
        print "-------------------------------"
        for ii in range(self.amountSections):
            print "{0:10.2e} {1:10.2e} {2:10.2e}".format(self.beamParams[0,ii], self.beamParams[1,ii], self.beamParams[2,ii])
        print "====================="

    ####################
    # Plotting methods
    ####################

    def plotFull(self,zmin,zmax):
        NUMBER_OF_STEPS=300
        #xmax=(self.lensPositions[-1] + self.lensFocals[-1])
        #xmin=self.z0

        #zmin=self.z0
        #zmax= self.lensPositions[-1] + self.lensFocals[-1]
        z=sp.arange(zmin,zmax,(zmax-zmin)/NUMBER_OF_STEPS)
        beamWidth=sp.zeros(len(z))

        plt.figure()
        #Will use the same trick as in the
        #index=sp.arange(0,self.amountSections)[sum(z>prop.beamsLimits)==1]
        #BeamSection(*self.beamParams[:,index]).waiplst(z)
        for ii in range(self.amountSections):
            localIndices=((z>self.beamsLimits[0,ii]) &(z<=self.beamsLimits[1,ii]))
            zlocal= z[localIndices]
            if zlocal is not None:
                beamWidth[localIndices]=BeamSection(*self.beamParams[:,ii]).waist(zlocal)
        plt.plot(z,beamWidth)
        plt.xlabel('z (m)')
        plt.ylabel('Width (m)')

        for ii in range(self.amountElements):
            plt.axvline(x=self.lensPositions[ii])

#--Location and size of the beam waist in the output
#denom=((d_in/f-1)**2 +(zR/f)**2)
#d_out= f * (1+ (d_in/f -1)/denom)
#w_0out= w_0in/sqrt(denom)

def denominator(d_in,f,zR):
    return (d_in/f -1)**2 +(zR/f)**2

def propagated_waist(w_0,z,zR,sz):
    return w_0*sp.sqrt(1+((z-sz)/zR)**2)

def rayleigh_range(waist,lambd):
    return sp.pi*waist**2/lambd

lambd=780.24e-9
pi=sp.pi

#We look for a Rayleigh range (which will be bigger than the waist in our wavelength) of less than 5 um
zR0=5e-6

#Therefore, the waist we are looking for is
w_0=sp.sqrt(zR0*lambd/pi)

#The maximum magnification we can get from a lens of focal f of a beam with rayleigh range zR is
f=32e-3
Mmax=1/sp.sqrt(denominator(f,f,zR0))
#if the waist is located at a distance d_in=f from the lens.
#That corresponds to a waist
w_1=w_0*Mmax
zR1=rayleigh_range(w_1,lambd)
#If we propagate that beam a length L forwards, the beam waist will be
L=50e-2
w_1prop=propagated_waist(w_1,L,zR1,0)

print 'Rayleigh Range: ',zR
print 'Final waist: ',w_0
print 'Maximum magnification for a lens with focal {0:.2e}: {1:.2e}. This, in turn, will give an initial waist of {2:.3e}'.format(f,Mmax,w_1)
print 'If that waist is located at a distance {0:.2e} from the minimum waist, the *new* waist will be {1:.3e}.'.format(L,w_1prop)

##############################
#Try object

myBeam=BeamSection(780.24e-9,1.1e-6,0)
myBeam2=myBeam.transformByLens(32e-3,32e-3)
myBeam3=myBeam2.transformByLens(32e-3,96e-3)
myBeam.report()
myBeam2.report()
myBeam3.report()
#print myBeam.z0, myBeam.lambd, myBeam.w0, myBeam.zR
#print myBeam3.z0, myBeam3.lambd, myBeam3.w0, myBeam3.zR

z=sp.arange(-10e-6,150e-3,1e-4)
#z=sp.arange(-10e-6,100e-6,1e-6)
plt.plot(z,myBeam.waist(z),label='first')
plt.plot(z,myBeam2.waist(z),label='second')
plt.plot(z,myBeam3.waist(z),label='third')

plt.legend()
plt.show()
<|endoftext|>


<commit_before>"""
Sources: Tess Snyder, https://docs.python.org/2/tutorial/datastructures.html

"""
from ggame import App, Color, LineStyle, Sprite, RectangleAsset, CircleAsset, EllipseAsset, PolygonAsset
import random

black = Color(0x000000, 1.0)
white = Color(0xffffff, 1.0)
clear = Color(0xffffff, 0.0)
red = Color(0xff0000, 1.0)
blue = Color(0x0000ff, 1.0)
thinline = LineStyle(1, black)
thickline = LineStyle(5, black)
oline = LineStyle(8, blue)
xline = LineStyle(8, red)

vline = RectangleAsset(10, 310, thinline, black)
hline = RectangleAsset(310, 10, thinline, black)
oshape = CircleAsset(30, oline, clear)
xshape = PolygonAsset([(5,5),(35,35),(65,5),(5,65),(35,35),(65,65)], xline, red)

w = PolygonAsset([(5,5),(15,30),(25,15),(35,30),(45,5),(35,30),(25,15),(15,30)], thickline, clear)
i = PolygonAsset([(5,0),(5,30)], thickline, clear)
n = PolygonAsset([(5,30),(5,5),(25,25),(25,0),(25,25),(5,5),(5,30)], thickline, clear)
Sprite(w, (400, 160))
Sprite(i, (455, 165))
Sprite(n, (470, 165))

Sprite(vline, (140, 40))
Sprite(vline, (240, 40))
Sprite(hline, (40, 140))
Sprite(hline, (40, 240))
osprites = [ ]
xsprites = [ ]

for x in [95, 195, 295]:
    for y in [95, 195, 295]:
        so = Sprite(oshape, (x,y))
        so.visible = False
        osprites.append(so)

for x in [60, 160, 260]:
    for y in [60, 160, 260]:
        sx = Sprite(xshape, (x,y))
        sx.visible = False
        xsprites.append(sx)

choice = input("Would you like to be X's or O's? ")
player = 0

while player==0:
    if choice=="x":
        player = xsprites
        comp = osprites

    elif choice=="o":
        player = osprites
        comp = xsprites

    else:
        choice = input("Invalid input. Try again. Would you like to be X's or O's? ")

class Ttt(App):

    def __init__(self):
        super().__init__()
        self.listenMouseEvent( 'click', self.click)

    def click(self, event):
        x = event.x
        y = event.y
        for s in player:
            if abs(x - s.x) <= 40 and abs(y - s.y) <= 40:
                s.visible = True
                player.remove(s)

                for sprite in comp:
                    if abs(sprite.x - s.x) <= 40 and abs(sprite.y - s.y) <= 40:
                        comp.remove(sprite)

                xorandom = random.choice(comp)
                xorandom.visible = True

                comp.remove(xorandom)
                for spr in player:
                    if abs(spr.x - xorandom.x) <= 40 and abs(xorandom.y - spr.y) <= 40:
                        player.remove(spr)

myapp = Ttt()
myapp.run()
<commit_msg>Updated from Brython Server: 4/26/2016 2:45:24 PM<commit_after>"""
Sources: Tess Snyder, https://docs.python.org/2/tutorial/datastructures.html

"""
from ggame import App, Color, LineStyle, Sprite, RectangleAsset, CircleAsset, EllipseAsset, PolygonAsset
import random

black = Color(0x000000, 1.0)
white = Color(0xffffff, 1.0)
clear = Color(0xffffff, 0.0)
red = Color(0xff0000, 1.0)
blue = Color(0x0000ff, 1.0)
thinline = LineStyle(1, black)
thickline = LineStyle(5, black)
oline = LineStyle(8, blue)
xline = LineStyle(8, red)

vline = RectangleAsset(10, 310, thinline, black)
hline = RectangleAsset(310, 10, thinline, black)
oshape = CircleAsset(30, oline, clear)
xshape = PolygonAsset([(5,5),(35,35),(65,5),(5,65),(35,35),(65,65)], xline, red)

w = PolygonAsset([(5,5),(15,30),(25,15),(35,30),(45,5),(35,30),(25,15),(15,30)], thickline, clear)
i = PolygonAsset([(5,0),(5,30)], thickline, clear)
n = PolygonAsset([(5,30),(5,5),(25,25),(25,0),(25,25),(5,5),(5,30)], thickline, clear)
s = CircleAsset(7.5, thickline, clear)

Sprite(w, (400, 160))
Sprite(i, (455, 165))
Sprite(n, (470, 165))
Sprite(s, (520, 165))
Sprite(s, (520, 195))

Sprite(vline, (140, 40))
Sprite(vline, (240, 40))
Sprite(hline, (40, 140))
Sprite(hline, (40, 240))
osprites = [ ]
xsprites = [ ]

for x in [95, 195, 295]:
    for y in [95, 195, 295]:
        so = Sprite(oshape, (x,y))
        so.visible = False
        osprites.append(so)

for x in [60, 160, 260]:
    for y in [60, 160, 260]:
        sx = Sprite(xshape, (x,y))
        sx.visible = False
        xsprites.append(sx)

choice = input("Would you like to be X's or O's? ")
player = 0

while player==0:
    if choice=="x":
        player = xsprites
        comp = osprites

    elif choice=="o":
        player = osprites
        comp = xsprites

    else:
        choice = input("Invalid input. Try again. Would you like to be X's or O's? ")

class Ttt(App):

    def __init__(self):
        super().__init__()
        self.listenMouseEvent( 'click', self.click)

    def click(self, event):
        x = event.x
        y = event.y
        for s in player:
            if abs(x - s.x) <= 40 and abs(y - s.y) <= 40:
                s.visible = True
                player.remove(s)

                for sprite in comp:
                    if abs(sprite.x - s.x) <= 40 and abs(sprite.y - s.y) <= 40:
                        comp.remove(sprite)

                xorandom = random.choice(comp)
                xorandom.visible = True

                comp.remove(xorandom)
                for spr in player:
                    if abs(spr.x - xorandom.x) <= 40 and abs(xorandom.y - spr.y) <= 40:
                        player.remove(spr)

myapp = Ttt()
myapp.run()
<|endoftext|>