<commit_before># -*- coding: utf-8 -*-
"""
==============================================================================
Base class for structure data atoms (:mod:`sknano.core.atoms._atoms`)
==============================================================================

.. currentmodule:: sknano.core.atoms._atoms

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
from builtins import str
__docformat__ = 'restructuredtext en'

from operator import attrgetter

import numpy as np

from sknano.core import UserList
from sknano.core.math import convert_condition_str
from ._atom import Atom

__all__ = ['Atoms']

class Atoms(UserList):
    """Base class for collection of `Atom` objects.

    Parameters
    ----------
    atoms : {None, sequence, `Atoms`}, optional
        if not `None`, then a list of `Atom` instance objects or an
        existing `Atoms` instance object.

    """
    def __init__(self, atoms=None):
        if atoms is not None and isinstance(atoms, str):
            atoms = [atoms]
        if not isinstance(atoms, type(self)) and isinstance(atoms, list):
            atoms = atoms[:]
            for i, atom in enumerate(atoms):
                try:
                    atoms[i] = self.__atom_class__(**atom.todict())
                except AttributeError:
                    atoms[i] = self.__atom_class__(atom)
        super().__init__(initlist=atoms)
        self.fmtstr = "{atoms!r}"
        self.kwargs = {}

    @property
    def __atom_class__(self):
        return Atom

    def __repr__(self):
        """Return canonical string representation of `Atoms`."""
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    def sort(self, key=attrgetter('element', 'Z', 'mass'), reverse=False):
        super().sort(key=key, reverse=reverse)

    def __getitem__(self, index):
        data = super().__getitem__(index)
        if isinstance(data, list):
            return self.__class__(data)
        return data

    def __setitem__(self, index, value):
        if not isinstance(value, (self.__class__, self.__atom_class__)):
            if isinstance(index, slice):
                value = self.__class__(value)
            else:
                value = self.__atom_class__(value)
        super().__setitem__(index, value)

    @property
    def fmtstr(self):
        return self._fmtstr

    @fmtstr.setter
    def fmtstr(self, value):
        self._fmtstr = value

    @property
    def Natoms(self):
        """Number of atoms in `Atoms`."""
        return len(self)

    @property
    def M(self):
        """Total mass of `Atoms`."""
        # return math.fsum(self.masses)
        return self.masses.sum()

    @property
    def elements(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.element`\ s \
            in `Atoms`."""
        return np.asarray([atom.element for atom in self])

    @property
    def masses(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.mass`\ s \
            in `Atoms`."""
        return np.asarray([atom.mass for atom in self])

    @property
    def symbols(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.symbol`\ s \
            in `Atoms`."""
        return np.asarray([atom.symbol for atom in self])

    def filter(self, condition, invert=False):
        """Filter `Atoms` by `condition`.

        .. versionchanged:: 0.3.11

           Filters the list of `Atoms` **in-place**. Use
           :meth:`~Atoms.filtered` to generate a new filtered list
           of `Atoms`.

        Parameters
        ----------
        condition : :class:`~python:str` or boolean array
            Boolean index array having same shape as the initial dimensions
            of the list of `Atoms` being indexed.
        invert : bool, optional
            If `True`, the boolean array `condition` is inverted element-wise.

        """
        if isinstance(condition, str):
            condition = convert_condition_str(self, condition)
        if invert:
            condition = ~condition
        self.data = np.asarray(self)[condition].tolist()

    def filtered(self, condition, invert=False):
        """Return new list of `Atoms` filtered by `condition`.

        .. versionadded:: 0.3.11

        Parameters
        ----------
        condition : array_like, bool
            Boolean index array having same shape as the initial dimensions
            of the list of `Atoms` being indexed.
        invert : bool, optional
            If `True`, the boolean array `condition` is inverted element-wise.

        Returns
        -------
        filtered_atoms : `Atoms`
            If `invert` is `False`, return the elements where `condition`
            is `True`.

            If `invert` is `True`, return the elements where `~condition`
            (i.e., numpy.invert(condition)) is `True`.

        Examples
        --------
        An example using the structure data of a 10 nm `(10, 0)`
        `SWCNT`:

        >>> from sknano.generators import SWNTGenerator
        >>> swnt = SWNTGenerator(10, 0, Lz=10, fix_Lz=True).atoms
        >>> # select 'left', 'middle', 'right' atoms
        >>> latoms = swnt.filtered(swnt.z <= 25)
        >>> matoms = swnt.filtered((swnt.z < 75) & (swnt.z > 25))
        >>> ratoms = swnt.filtered(swnt.z >= 75)
        >>> from pprint import pprint
        >>> pprint([getattr(atoms, 'bounds') for atoms in
        ...         (latoms, matoms, ratoms)])
        [Cuboid(pmin=Point([-3.914435, -3.914435, 0.0]), \
                pmax=Point([3.914435, 3.914435, 24.85])),
         Cuboid(pmin=Point([-3.914435, -3.914435, 25.56]), \
                pmax=Point([3.914435, 3.914435, 74.55])),
         Cuboid(pmin=Point([-3.914435, -3.914435, 75.97]), \
                pmax=Point([3.914435, 3.914435, 100.11]))]
        >>> latoms.Natoms + matoms.Natoms + ratoms.Natoms == swnt.Natoms
        True

        """
        if isinstance(condition, str):
            condition = convert_condition_str(self, condition)
        if invert:
            condition = ~condition
        return self.__class__(atoms=np.asarray(self)[condition].tolist(),
                              **self.kwargs)

    def get_atoms(self, asarray=False):
        """Return list of `Atoms`.

        Parameters
        ----------
        asarray : bool, optional

        Returns
        -------
        sequence or ndarray

        """
        if asarray:
            return np.asarray(self.data)
        else:
            return self.data

    def getatomattr(self, attr):
        """Get :class:`~numpy:numpy.ndarray` of atom attributes `attr`.

        Parameters
        ----------
        attr : str
            Name of attribute to pass to `getattr` from each `XAtom` in
            `XAtoms`.

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        try:
            return np.asarray([getattr(atom, attr) for atom in self])
        except AttributeError:
            return None

    def mapatomattr(self, attr, from_attr, attrmap):
        """Set/update atom attribute from another atom attribute with dict.

        Parameters
        ----------
        attr, from_attr : :class:`python:str`
        attrmap : :class:`python:dict`

        Examples
        --------
        Suppose you have an `XAtoms` instance named ``atoms`` that has
        `XAtom` instances of two atom types `1` and `2` and we want to set
        all `XAtom`\ s with `type=1` to Nitrogen and all `XAtom`\ s with
        `type=2` to Argon.

        We'd call this method like so::

        >>> atoms.mapatomattr('element', 'type', {1: 'N', 2: 'Ar'})

        """
        [setattr(atom, attr, attrmap[getattr(atom, from_attr)])
         for atom in self if getattr(atom, from_attr) is not None]

    def rotate(self, **kwargs):
        assert not hasattr(super(), 'rotate')

    def translate(self, *args, **kwargs):
        assert not hasattr(super(), 'translate')

    def todict(self):
        return dict(atoms=self.data)
<commit_msg>Bug fix in `Atoms` class.<commit_after># -*- coding: utf-8 -*-
"""
==============================================================================
Base class for structure data atoms (:mod:`sknano.core.atoms._atoms`)
==============================================================================

.. currentmodule:: sknano.core.atoms._atoms

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
from builtins import str
__docformat__ = 'restructuredtext en'

from operator import attrgetter

import numpy as np

from sknano.core import UserList
from sknano.core.math import convert_condition_str
from ._atom import Atom

__all__ = ['Atoms']

class Atoms(UserList):
    """Base class for collection of `Atom` objects.

    Parameters
    ----------
    atoms : {None, sequence, `Atoms`}, optional
        if not `None`, then a list of `Atom` instance objects or an
        existing `Atoms` instance object.

    """
    def __init__(self, atoms=None):
        if atoms is not None and (isinstance(atoms, str) or
                                  isinstance(atoms, Atom)):
            atoms = [atoms]
        if not isinstance(atoms, type(self)) and isinstance(atoms, list):
            atoms = atoms[:]
            for i, atom in enumerate(atoms):
                try:
                    atoms[i] = self.__atom_class__(**atom.todict())
                except AttributeError:
                    atoms[i] = self.__atom_class__(atom)
        super().__init__(initlist=atoms)
        self.fmtstr = "{atoms!r}"
        self.kwargs = {}

    @property
    def __atom_class__(self):
        return Atom

    def __repr__(self):
        """Return canonical string representation of `Atoms`."""
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    def sort(self, key=attrgetter('element', 'Z', 'mass'), reverse=False):
        super().sort(key=key, reverse=reverse)

    def __getitem__(self, index):
        data = super().__getitem__(index)
        if isinstance(data, list):
            return self.__class__(data)
        return data

    def __setitem__(self, index, value):
        if not isinstance(value, (self.__class__, self.__atom_class__)):
            if isinstance(index, slice):
                value = self.__class__(value)
            else:
                value = self.__atom_class__(value)
        super().__setitem__(index, value)

    @property
    def fmtstr(self):
        return self._fmtstr

    @fmtstr.setter
    def fmtstr(self, value):
        self._fmtstr = value

    @property
    def Natoms(self):
        """Number of atoms in `Atoms`."""
        return len(self)

    @property
    def M(self):
        """Total mass of `Atoms`."""
        # return math.fsum(self.masses)
        return self.masses.sum()

    @property
    def elements(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.element`\ s \
            in `Atoms`."""
        return np.asarray([atom.element for atom in self])

    @property
    def masses(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.mass`\ s \
            in `Atoms`."""
        return np.asarray([atom.mass for atom in self])

    @property
    def symbols(self):
        """:class:`~numpy:numpy.ndarray` of :attr:`Atom.symbol`\ s \
            in `Atoms`."""
        return np.asarray([atom.symbol for atom in self])

    def filter(self, condition, invert=False):
        """Filter `Atoms` by `condition`.

        .. versionchanged:: 0.3.11

           Filters the list of `Atoms` **in-place**. Use
           :meth:`~Atoms.filtered` to generate a new filtered list
           of `Atoms`.

        Parameters
        ----------
        condition : :class:`~python:str` or boolean array
            Boolean index array having same shape as the initial dimensions
            of the list of `Atoms` being indexed.
        invert : bool, optional
            If `True`, the boolean array `condition` is inverted element-wise.

        """
        if isinstance(condition, str):
            condition = convert_condition_str(self, condition)
        if invert:
            condition = ~condition
        try:
            self.data = np.asarray(self)[condition].tolist()
        except AttributeError:
            self.data = np.asarray(self)[condition]

    def filtered(self, condition, invert=False):
        """Return new list of `Atoms` filtered by `condition`.

        .. versionadded:: 0.3.11

        Parameters
        ----------
        condition : array_like, bool
            Boolean index array having same shape as the initial dimensions
            of the list of `Atoms` being indexed.
        invert : bool, optional
            If `True`, the boolean array `condition` is inverted element-wise.

        Returns
        -------
        filtered_atoms : `Atoms`
            If `invert` is `False`, return the elements where `condition`
            is `True`.

            If `invert` is `True`, return the elements where `~condition`
            (i.e., numpy.invert(condition)) is `True`.

        Examples
        --------
        An example using the structure data of a 10 nm `(10, 0)`
        `SWCNT`:

        >>> from sknano.generators import SWNTGenerator
        >>> swnt = SWNTGenerator(10, 0, Lz=10, fix_Lz=True).atoms
        >>> # select 'left', 'middle', 'right' atoms
        >>> latoms = swnt.filtered(swnt.z <= 25)
        >>> matoms = swnt.filtered((swnt.z < 75) & (swnt.z > 25))
        >>> ratoms = swnt.filtered(swnt.z >= 75)
        >>> from pprint import pprint
        >>> pprint([getattr(atoms, 'bounds') for atoms in
        ...         (latoms, matoms, ratoms)])
        [Cuboid(pmin=Point([-3.914435, -3.914435, 0.0]), \
                pmax=Point([3.914435, 3.914435, 24.85])),
         Cuboid(pmin=Point([-3.914435, -3.914435, 25.56]), \
                pmax=Point([3.914435, 3.914435, 74.55])),
         Cuboid(pmin=Point([-3.914435, -3.914435, 75.97]), \
                pmax=Point([3.914435, 3.914435, 100.11]))]
        >>> latoms.Natoms + matoms.Natoms + ratoms.Natoms == swnt.Natoms
        True

        """
        if isinstance(condition, str):
            condition = convert_condition_str(self, condition)
        if invert:
            condition = ~condition
        try:
            return self.__class__(atoms=np.asarray(self)[condition].tolist(),
                                  **self.kwargs)
        except AttributeError:
            return self.__class__(atoms=np.asarray(self)[condition],
                                  **self.kwargs)

    def get_atoms(self, asarray=False):
        """Return list of `Atoms`.

        Parameters
        ----------
        asarray : bool, optional

        Returns
        -------
        sequence or ndarray

        """
        if asarray:
            return np.asarray(self.data)
        else:
            return self.data

    def getatomattr(self, attr):
        """Get :class:`~numpy:numpy.ndarray` of atom attributes `attr`.

        Parameters
        ----------
        attr : str
            Name of attribute to pass to `getattr` from each `XAtom` in
            `XAtoms`.

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        try:
            return np.asarray([getattr(atom, attr) for atom in self])
        except AttributeError:
            return None

    def mapatomattr(self, attr, from_attr, attrmap):
        """Set/update atom attribute from another atom attribute with dict.

        Parameters
        ----------
        attr, from_attr : :class:`python:str`
        attrmap : :class:`python:dict`

        Examples
        --------
        Suppose you have an `XAtoms` instance named ``atoms`` that has
        `XAtom` instances of two atom types `1` and `2` and we want to set
        all `XAtom`\ s with `type=1` to Nitrogen and all `XAtom`\ s with
        `type=2` to Argon.

        We'd call this method like so::

        >>> atoms.mapatomattr('element', 'type', {1: 'N', 2: 'Ar'})

        """
        [setattr(atom, attr, attrmap[getattr(atom, from_attr)])
         for atom in self if getattr(atom, from_attr) is not None]

    def rotate(self, **kwargs):
        assert not hasattr(super(), 'rotate')

    def translate(self, *args, **kwargs):
        assert not hasattr(super(), 'translate')

    def todict(self):
        return dict(atoms=self.data)
<|endoftext|>


<commit_before>import pytest
import datetime
import os
import sys
import json
from .utils import git_repo

from wandb import wandb_run
from wandb import env
from wandb.apis import InternalApi

def get_last_val(history, key):
    val = None
    for val in history.column(key):
        pass
    return val

def test_wandb_run_args(git_repo):
    os.environ[env.ARGS] = json.dumps(["foo", "bar"])
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.args == ["foo", "bar"]
    del os.environ[env.ARGS]

def test_url_escape(git_repo):
    os.environ[env.ENTITY] = "†est"
    os.environ[env.API_KEY] = "abcdefghijabcdefghijabcdefghijabcdefghij"
    run = wandb_run.Run.from_environment_or_defaults(
        {env.RUN_ID: "my wild run"})
    api = InternalApi({"project": "wild projo"}, load_settings=False)
    assert run.get_url(
        api) == "https://app.wandb.ai/%E2%80%A0est/wild+projo/runs/my+wild+run"
    del os.environ[env.ENTITY]
    del os.environ[env.API_KEY]

def test_wandb_run_args_sys(git_repo):
    sys.argv = ["rad", "cool"]
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.args == ["cool"]

def test_name_and_desc_only_name(git_repo):
    os.environ[env.DESCRIPTION] = "myrunid"
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.name == "myrunid"
    assert run.description == ""
    del os.environ[env.DESCRIPTION]

def test_name_and_desc(git_repo):
    os.environ[env.DESCRIPTION] = "myrunid\nmydesc"
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.name == "myrunid"
    assert run.description == "mydesc"
    del os.environ[env.DESCRIPTION]

def test_name_and_desc_setters(git_repo):
    run = wandb_run.Run.from_environment_or_defaults()
    run.name = "123"
    run.description = "so much desc\nthis is fun"
    assert run.name == "123"
    assert run.description == "so much desc\nthis is fun"
    my_env = {}
    run.set_environment(my_env)
    assert my_env[env.DESCRIPTION] == "123\nso much desc\nthis is fun"

def test_history_updates_keys_until_summary_writes(git_repo):
    run = wandb_run.Run()

    run.history.add({'a': 5, 'b': 9})
    assert get_last_val(run.history, 'a') == 5
    assert get_last_val(run.history, 'b') == 9
    assert run.summary['a'] == 5
    assert run.summary['b'] == 9

    run.history.add({'a': 6, 'b': 10})
    assert get_last_val(run.history, 'a') == 6
    assert get_last_val(run.history, 'b') == 10
    assert run.summary['a'] == 6
    assert run.summary['b'] == 10

    run.summary['a'] = 112491
    assert run.summary['a'] == 112491

    run.history.add({'a': 1, 'b': 3})
    assert get_last_val(run.history, 'a') == 1
    assert get_last_val(run.history, 'b') == 3
    assert run.summary['a'] == 112491
    assert run.summary['b'] == 3

    run.history.add({'a': -40, 'b': -49})
    assert get_last_val(run.history, 'a') == -40
    assert get_last_val(run.history, 'b') == -49
    assert run.summary['a'] == 112491
    # most recent history key is logged
    assert run.summary['b'] == -49

    run.summary['c'] = 100
    assert run.summary['c'] == 100
    run.history.add({'c': 200, 'd': 300})
    assert run.summary['c'] == 100
    assert run.summary['d'] == 300

    run.history.add({'a': 1000, 'b': 2000, 'c': 200, 'd': 300})
    assert get_last_val(run.history, 'a') == 1000
    assert get_last_val(run.history, 'b') == 2000
    assert get_last_val(run.history, 'c') == 200
    assert get_last_val(run.history, 'd') == 300
    assert run.summary['a'] == 112491
    assert run.summary['b'] == 2000
    assert run.summary['c'] == 100
    assert run.summary['d'] == 300
<commit_msg>Fix encoding<commit_after># This Python file uses the following encoding: utf-8
import pytest
import datetime
import os
import sys
import json
from .utils import git_repo

from wandb import wandb_run
from wandb import env
from wandb.apis import InternalApi

def get_last_val(history, key):
    val = None
    for val in history.column(key):
        pass
    return val

def test_wandb_run_args(git_repo):
    os.environ[env.ARGS] = json.dumps(["foo", "bar"])
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.args == ["foo", "bar"]
    del os.environ[env.ARGS]

def test_url_escape(git_repo):
    os.environ[env.ENTITY] = "†est"
    os.environ[env.API_KEY] = "abcdefghijabcdefghijabcdefghijabcdefghij"
    run = wandb_run.Run.from_environment_or_defaults(
        {env.RUN_ID: "my wild run"})
    api = InternalApi({"project": "wild projo"}, load_settings=False)
    assert run.get_url(
        api) == "https://app.wandb.ai/%E2%80%A0est/wild+projo/runs/my+wild+run"
    del os.environ[env.ENTITY]
    del os.environ[env.API_KEY]

def test_wandb_run_args_sys(git_repo):
    sys.argv = ["rad", "cool"]
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.args == ["cool"]

def test_name_and_desc_only_name(git_repo):
    os.environ[env.DESCRIPTION] = "myrunid"
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.name == "myrunid"
    assert run.description == ""
    del os.environ[env.DESCRIPTION]

def test_name_and_desc(git_repo):
    os.environ[env.DESCRIPTION] = "myrunid\nmydesc"
    run = wandb_run.Run.from_environment_or_defaults()
    assert run.name == "myrunid"
    assert run.description == "mydesc"
    del os.environ[env.DESCRIPTION]

def test_name_and_desc_setters(git_repo):
    run = wandb_run.Run.from_environment_or_defaults()
    run.name = "123"
    run.description = "so much desc\nthis is fun"
    assert run.name == "123"
    assert run.description == "so much desc\nthis is fun"
    my_env = {}
    run.set_environment(my_env)
    assert my_env[env.DESCRIPTION] == "123\nso much desc\nthis is fun"

def test_history_updates_keys_until_summary_writes(git_repo):
    run = wandb_run.Run()

    run.history.add({'a': 5, 'b': 9})
    assert get_last_val(run.history, 'a') == 5
    assert get_last_val(run.history, 'b') == 9
    assert run.summary['a'] == 5
    assert run.summary['b'] == 9

    run.history.add({'a': 6, 'b': 10})
    assert get_last_val(run.history, 'a') == 6
    assert get_last_val(run.history, 'b') == 10
    assert run.summary['a'] == 6
    assert run.summary['b'] == 10

    run.summary['a'] = 112491
    assert run.summary['a'] == 112491

    run.history.add({'a': 1, 'b': 3})
    assert get_last_val(run.history, 'a') == 1
    assert get_last_val(run.history, 'b') == 3
    assert run.summary['a'] == 112491
    assert run.summary['b'] == 3

    run.history.add({'a': -40, 'b': -49})
    assert get_last_val(run.history, 'a') == -40
    assert get_last_val(run.history, 'b') == -49
    assert run.summary['a'] == 112491
    # most recent history key is logged
    assert run.summary['b'] == -49

    run.summary['c'] = 100
    assert run.summary['c'] == 100
    run.history.add({'c': 200, 'd': 300})
    assert run.summary['c'] == 100
    assert run.summary['d'] == 300

    run.history.add({'a': 1000, 'b': 2000, 'c': 200, 'd': 300})
    assert get_last_val(run.history, 'a') == 1000
    assert get_last_val(run.history, 'b') == 2000
    assert get_last_val(run.history, 'c') == 200
    assert get_last_val(run.history, 'd') == 300
    assert run.summary['a'] == 112491
    assert run.summary['b'] == 2000
    assert run.summary['c'] == 100
    assert run.summary['d'] == 300
<|endoftext|>


<commit_before>'''
FeatherDuster - A wizard-like interface to cryptanalib
Author: Daniel Crowley

FeatherDuster is a tool for brushing away magical crypto fairy dust.
'''

import sys
import readline
import completer
from ishell.console import Console
from ishell.command import Command

import feathermodules

feathermodules.samples = []
feathermodules.results = False
feathermodules.selected_attack_name = ''
feathermodules.current_options = {}

from feathermodules.stream import *
from feathermodules.block import *
from feathermodules.classical import *
from feathermodules.auxiliary import *
from feathermodules.custom import *
from feathermodules.pubkey import *

import cryptanalib as ca

# import
class ImportMultiFileCommand(Command):
   def run(self, line):
      ishellCompleter = readline.get_completer()
      readline.set_completer_delims(' \t\n;')
      readline.parse_and_bind("tab: complete")
      readline.set_completer(completer.complete)

      sample_file = raw_input('Please enter the filename you want to open: ')
      try:
         sample_fh = open(sample_file,'r')
         feathermodules.samples.extend([sample.strip() for sample in sample_fh.readlines()])
         sample_fh.close()
         feathermodules.samples = filter(lambda x: x != '' and x != None, feathermodules.samples)
      except:
         print 'Something went wrong. Sorry! Please try again.'
      finally:
         readline.set_completer(ishellCompleter)

class ImportSingleFileCommand(Command):
   def run(self, line):
      ishellCompleter = readline.get_completer()
      readline.set_completer_delims(' \t\n;')
      readline.parse_and_bind("tab: complete")
      readline.set_completer(completer.complete)

      sample_file = raw_input('Please enter the filename you want to open: ')
      try:
         sample_fh = open(sample_file,'r')
         feathermodules.samples.append(sample_fh.read())
         sample_fh.close()
      except:
         print 'Something went wrong. Sorry! Please try again.'
      finally:
         readline.set_completer(ishellCompleter)

class ImportManualEntryCommand(Command):
   def run(self, line):
      feathermodules.samples.append(raw_input('Please enter your sample: ').strip())

class ImportResultsCommand(Command):
   def run(self, line):
      if not feathermodules.results:
         print 'Last module failed to produce results.'
      elif feathermodules.results == True:
         print 'Last module succeeded, but did not return results.'
      else:
         print 'Last results (long values may be truncated):'
         print '-'*80
         for i in range(len(feathermodules.results)):
            print '{0:d}: {1:60s}'.format(i, repr(feathermodules.results[i]))

      selection = raw_input('\nPlease enter your selection by number, or \'all\' for all: ')
      try:
         if selection == 'all':
            feathermodules.samples.extend(feathermodules.results)
         elif int(selection) < len(feathermodules.results):
            feathermodules.samples.append(feathermodules.results[int(selection)])
         else:
            print 'Invalid entry, please try again.'
      except ValueError:
         print 'Invalid entry, please try again.'

class ImportClearCommand(Command):
   def run(self, line):
      feathermodules.samples = []

class ImportCommand(Command):
   def args(self):
      return ['multifile', 'singlefile', 'manualentry', 'results', 'clear']

import_sample = ImportCommand('import', help='Import samples for analysis', dynamic_args=True)

import_multifile = ImportMultiFileCommand(
   'multifile',
   help='Import multiple newline-separated samples from one file',
   dynamic_args=True)
import_singlefile = ImportSingleFileCommand(
   'singlefile',
   help='Import a single file as a raw sample',
   dynamic_args=True)
import_manualentry = ImportManualEntryCommand(
   'manualentry',
   help='Manually enter a single sample',
   dynamic_args=True)
import_results = ImportResultsCommand(
   'results',
   help='Import last module\'s results as samples',
   dynamic_args=True)
import_clear = ImportClearCommand(
   'clear',
   help='Clear current sample set',
   dynamic_args=True)

import_sample.addChild(import_multifile)
import_sample.addChild(import_singlefile)
import_sample.addChild(import_manualentry)
import_sample.addChild(import_results)
import_sample.addChild(import_clear)

# use
class UseCommand(Command):
   def args(self):
      return feathermodules.module_list.keys()
   def run(self, line):
      if line.split()[-1] not in feathermodules.module_list.keys():
         print 'Invalid module selection. Please try again.'
      else:
         feathermodules.selected_attack = feathermodules.module_list[ line.split()[-1] ]
         feathermodules.selected_attack_name = line.split()[-1]
         feathermodules.current_options = feathermodules.selected_attack['options']

use = UseCommand('use', help='Select the module to use', dynamic_args=True)

# analyze
class AnalyzeCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      print '[+] Analyzing samples...'
      analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True)
      if analysis_results['decoded_ciphertexts'] != feathermodules.samples:
         feathermodules.samples = analysis_results['decoded_ciphertexts']
      print ''
      print '[+] Suggested modules:'
      for attack in feathermodules.module_list.keys():
         if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0:
            print '   {0:<20} - {1:<57}'.format(attack, feathermodules.module_list[attack]['description'])

analyze = AnalyzeCommand('analyze', help='Analyze/decode samples', dynamic_args=True)

# autopwn
class AutopwnCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      print '[+] Analyzing samples...'
      analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True)
      if analysis_results['decoded_ciphertexts'] != feathermodules.samples:
         feathermodules.samples = analysis_results['decoded_ciphertexts']
      for attack in feathermodules.module_list.keys():
         if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0:
            print 'Running module: %s' % attack
            feathermodules.current_options = feathermodules.module_list[attack]['options']
            print feathermodules.module_list[attack]['attack_function'](feathermodules.samples)

autopwn = AutopwnCommand('autopwn', help='Analyze samples and run all attacks', dynamic_args=True)

# search
class SearchCommand(Command):
   def run(self, line):
      matching_modules = []
      search_param = line.split()[-1].lower()
      for attack in feathermodules.module_list.keys():
         if attack.lower().find(search_param) != -1:
            matching_modules.append(attack)
         elif feathermodules.module_list[attack]['description'].lower().find(search_param) != -1:
            matching_modules.append(attack)
         elif search_param in feathermodules.module_list[attack]['keywords']:
            matching_modules.append(attack)
      for module in matching_modules:
         print "%s - %s" % (module, feathermodules.module_list[module]['description'])

search = SearchCommand('search', help='Search module names and descriptions by keyword')

# samples
class SamplesCommand(Command):
   def run(self, line):
      print '-' * 60
      for sample in feathermodules.samples:
         print repr(sample)
      print '-' * 60

samples = SamplesCommand('samples', help='Show samples')

# modules
class ModulesCommand(Command):
   def run(self, line):
      for attack in feathermodules.module_list.keys():
         print "%s - %s" % (attack, feathermodules.module_list[attack]['description'])

modules = ModulesCommand('modules', help='Show all available modules')

# run
class RunCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      elif feathermodules.selected_attack_name not in feathermodules.module_list.keys():
         print 'Invalid module selection. Please use the \'use\' command.'
         return False
      feathermodules.results = feathermodules.selected_attack['attack_function'](feathermodules.samples)

run = RunCommand('run', help='Run the currently selected module')

# options
class OptionsCommand(Command):
   def run(self, line):
      if feathermodules.selected_attack_name not in feathermodules.module_list.keys():
         print 'Please select a valid module first.'
         return False
      else:
         print ''
         print '{0:^60}'.format('Currently selected module: ' + feathermodules.selected_attack_name)
         print '-' * 60
         if len(feathermodules.selected_attack['options'].items()) == 0:
            print 'No options to configure.'
         else:
            for option, default in feathermodules.selected_attack['options'].items():
               try:
                  print '{0:<20}{1:>40}'.format(option, feathermodules.current_options[option])
               except:
                  print '{0:<20}{1:>40}'.format(option, default)

# set
class SetCommand(Command):
   def run(self, line):
      line_split = line.split()
      # set option_name value
      if not (len(line_split) == 2 and '=' in line_split[1]):
         print 'Usage: set <option>=<value>'
         return False
      option = line_split[1].split('=')[0]
      value = line_split[1].split('=')[1]
      feathermodules.current_options[option] = value
   def args(self):
      return feathermodules.selected_attack['options'].keys()

# unset
class UnsetCommand(Command):
   def run(self, line):
      line_split = line.split()
      # unset option_name
      if len(line_split) != 2:
         print 'Usage: unset <option>'
         return False
      option = line_split[1]
      feathermodules.current_options[option] = feathermodules.selected_attack['options'][option]
   def args(self):
      return feathermodules.selected_attack['options'].keys()

# results
class ResultsCommand(Command):
   def run(self, line):
      if not feathermodules.results:
         print 'Last module failed to produce results.'
      elif feathermodules.results == True:
         print 'Last module succeeded, but did not return results.'
      else:
         print 'Last results (long values may be truncated):'
         print '-'*80
         for i in range(len(feathermodules.results)):
            print '{0:d}: {1:60s}'.format(i, repr(feathermodules.results[i]))

set_command = SetCommand('set', help='Set an option (i.e., "set num_answers=3"', dynamic_args=True)
unset = UnsetCommand('unset', help='Revert an option to its default value', dynamic_args=True)
options = OptionsCommand('options', help='Show the current option values', dynamic_args=True)
results = ResultsCommand('results', help='Show the results from the last module run')

# Build the console
fd_console = Console(prompt='\nFeatherDuster', prompt_delim='>')

fd_console.addChild(import_sample)
fd_console.addChild(use)
fd_console.addChild(analyze)
fd_console.addChild(autopwn)
fd_console.addChild(search)
fd_console.addChild(samples)
fd_console.addChild(modules)
fd_console.addChild(run)
fd_console.addChild(options)
fd_console.addChild(set_command)
fd_console.addChild(unset)
fd_console.addChild(results)

#--------
# Main menu
#

for filename in sys.argv[1:]:
   if filename in ['-h', '--help']:
      print 'Usage: python featherduster.py [ciphertext file 1] ... [ciphertext file n]'
      exit()
   try:
      sample_fh = open(filename,'r')
      feathermodules.samples.append(sample_fh.read())
      sample_fh.close()
   except:
      continue

print """Welcome to FeatherDuster!

To get started, use 'import' to load samples.
Then, use 'analyze' to analyze/decode samples and get attack recommendations.
Next, run the 'use' command to select an attack module.
Finally, use 'run' to run the attack and see its output.

For a command reference, press Enter on a blank line.
"""

fd_console.loop()

print '\nThank you for using FeatherDuster!'
<commit_msg>Added: Interactive mode<commit_after>'''
FeatherDuster - A wizard-like interface to cryptanalib
Author: Daniel Crowley

FeatherDuster is a tool for brushing away magical crypto fairy dust.
'''

import sys
import readline
import completer
from ishell.console import Console
from ishell.command import Command

try:
   from IPython import embed
except ImportError:
   import code

   def embed():
      vars = globals()
      vars.update(locals())
      shell = code.InteractiveConsole(vars)
      shell.interact()

import feathermodules

feathermodules.samples = []
feathermodules.results = False
feathermodules.selected_attack_name = ''
feathermodules.current_options = {}

from feathermodules.stream import *
from feathermodules.block import *
from feathermodules.classical import *
from feathermodules.auxiliary import *
from feathermodules.custom import *
from feathermodules.pubkey import *

import cryptanalib as ca

# import
class ImportMultiFileCommand(Command):
   def run(self, line):
      ishellCompleter = readline.get_completer()
      readline.set_completer_delims(' \t\n;')
      readline.parse_and_bind("tab: complete")
      readline.set_completer(completer.complete)

      sample_file = raw_input('Please enter the filename you want to open: ')
      try:
         sample_fh = open(sample_file,'r')
         feathermodules.samples.extend([sample.strip() for sample in sample_fh.readlines()])
         sample_fh.close()
         feathermodules.samples = filter(lambda x: x != '' and x != None, feathermodules.samples)
      except:
         print 'Something went wrong. Sorry! Please try again.'
      finally:
         readline.set_completer(ishellCompleter)

class ImportSingleFileCommand(Command):
   def run(self, line):
      ishellCompleter = readline.get_completer()
      readline.set_completer_delims(' \t\n;')
      readline.parse_and_bind("tab: complete")
      readline.set_completer(completer.complete)

      sample_file = raw_input('Please enter the filename you want to open: ')
      try:
         sample_fh = open(sample_file,'r')
         feathermodules.samples.append(sample_fh.read())
         sample_fh.close()
      except:
         print 'Something went wrong. Sorry! Please try again.'
      finally:
         readline.set_completer(ishellCompleter)

class ImportManualEntryCommand(Command):
   def run(self, line):
      feathermodules.samples.append(raw_input('Please enter your sample: ').strip())

class ImportResultsCommand(Command):
   def run(self, line):
      if not feathermodules.results:
         print 'Last module failed to produce results.'
      elif feathermodules.results == True:
         print 'Last module succeeded, but did not return results.'
      else:
         print 'Last results (long values may be truncated):'
         print '-'*80
         for i in range(len(feathermodules.results)):
            print '{0:d}: {1:60s}'.format(i, repr(feathermodules.results[i]))

      selection = raw_input('\nPlease enter your selection by number, or \'all\' for all: ')
      try:
         if selection == 'all':
            feathermodules.samples.extend(feathermodules.results)
         elif int(selection) < len(feathermodules.results):
            feathermodules.samples.append(feathermodules.results[int(selection)])
         else:
            print 'Invalid entry, please try again.'
      except ValueError:
         print 'Invalid entry, please try again.'

class ImportClearCommand(Command):
   def run(self, line):
      feathermodules.samples = []

class ImportCommand(Command):
   def args(self):
      return ['multifile', 'singlefile', 'manualentry', 'results', 'clear']

import_sample = ImportCommand('import', help='Import samples for analysis', dynamic_args=True)

import_multifile = ImportMultiFileCommand(
   'multifile',
   help='Import multiple newline-separated samples from one file',
   dynamic_args=True)
import_singlefile = ImportSingleFileCommand(
   'singlefile',
   help='Import a single file as a raw sample',
   dynamic_args=True)
import_manualentry = ImportManualEntryCommand(
   'manualentry',
   help='Manually enter a single sample',
   dynamic_args=True)
import_results = ImportResultsCommand(
   'results',
   help='Import last module\'s results as samples',
   dynamic_args=True)
import_clear = ImportClearCommand(
   'clear',
   help='Clear current sample set',
   dynamic_args=True)

import_sample.addChild(import_multifile)
import_sample.addChild(import_singlefile)
import_sample.addChild(import_manualentry)
import_sample.addChild(import_results)
import_sample.addChild(import_clear)

# console
class ConsoleCommand(Command):
   def run(self, line):
      ishellCompleter = readline.get_completer()
      embed()
      readline.set_completer(ishellCompleter)

console = ConsoleCommand('console', help='Opens an interactive prompt', dynamic_args=True)

# use
class UseCommand(Command):
   def args(self):
      return feathermodules.module_list.keys()
   def run(self, line):
      if line.split()[-1] not in feathermodules.module_list.keys():
         print 'Invalid module selection. Please try again.'
      else:
         feathermodules.selected_attack = feathermodules.module_list[ line.split()[-1] ]
         feathermodules.selected_attack_name = line.split()[-1]
         feathermodules.current_options = feathermodules.selected_attack['options']

use = UseCommand('use', help='Select the module to use', dynamic_args=True)

# analyze
class AnalyzeCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      print '[+] Analyzing samples...'
      analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True)
      if analysis_results['decoded_ciphertexts'] != feathermodules.samples:
         feathermodules.samples = analysis_results['decoded_ciphertexts']
      print ''
      print '[+] Suggested modules:'
      for attack in feathermodules.module_list.keys():
         if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0:
            print '   {0:<20} - {1:<57}'.format(attack, feathermodules.module_list[attack]['description'])

analyze = AnalyzeCommand('analyze', help='Analyze/decode samples', dynamic_args=True)

# autopwn
class AutopwnCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      print '[+] Analyzing samples...'
      analysis_results = ca.analyze_ciphertext(feathermodules.samples, verbose=True)
      if analysis_results['decoded_ciphertexts'] != feathermodules.samples:
         feathermodules.samples = analysis_results['decoded_ciphertexts']
      for attack in feathermodules.module_list.keys():
         if len(set(feathermodules.module_list[attack]['keywords']) & set(analysis_results['keywords'])) > 0:
            print 'Running module: %s' % attack
            feathermodules.current_options = feathermodules.module_list[attack]['options']
            print feathermodules.module_list[attack]['attack_function'](feathermodules.samples)

autopwn = AutopwnCommand('autopwn', help='Analyze samples and run all attacks', dynamic_args=True)

# search
class SearchCommand(Command):
   def run(self, line):
      matching_modules = []
      search_param = line.split()[-1].lower()
      for attack in feathermodules.module_list.keys():
         if attack.lower().find(search_param) != -1:
            matching_modules.append(attack)
         elif feathermodules.module_list[attack]['description'].lower().find(search_param) != -1:
            matching_modules.append(attack)
         elif search_param in feathermodules.module_list[attack]['keywords']:
            matching_modules.append(attack)
      for module in matching_modules:
         print "%s - %s" % (module, feathermodules.module_list[module]['description'])

search = SearchCommand('search', help='Search module names and descriptions by keyword')

# samples
class SamplesCommand(Command):
   def run(self, line):
      print '-' * 60
      for sample in feathermodules.samples:
         print repr(sample)
      print '-' * 60

samples = SamplesCommand('samples', help='Show samples')

# modules
class ModulesCommand(Command):
   def run(self, line):
      for attack in feathermodules.module_list.keys():
         print "%s - %s" % (attack, feathermodules.module_list[attack]['description'])

modules = ModulesCommand('modules', help='Show all available modules')

# run
class RunCommand(Command):
   def run(self, line):
      if len(feathermodules.samples) == 0:
         print 'No loaded samples. Please use the \'import\' command.'
         return False
      elif feathermodules.selected_attack_name not in feathermodules.module_list.keys():
         print 'Invalid module selection. Please use the \'use\' command.'
         return False
      feathermodules.results = feathermodules.selected_attack['attack_function'](feathermodules.samples)

run = RunCommand('run', help='Run the currently selected module')

# options
class OptionsCommand(Command):
   def run(self, line):
      if feathermodules.selected_attack_name not in feathermodules.module_list.keys():
         print 'Please select a valid module first.'
         return False
      else:
         print ''
         print '{0:^60}'.format('Currently selected module: ' + feathermodules.selected_attack_name)
         print '-' * 60
         if len(feathermodules.selected_attack['options'].items()) == 0:
            print 'No options to configure.'
         else:
            for option, default in feathermodules.selected_attack['options'].items():
               try:
                  print '{0:<20}{1:>40}'.format(option, feathermodules.current_options[option])
               except:
                  print '{0:<20}{1:>40}'.format(option, default)

# set
class SetCommand(Command):
   def run(self, line):
      line_split = line.split()
      # set option_name value
      if not (len(line_split) == 2 and '=' in line_split[1]):
         print 'Usage: set <option>=<value>'
         return False
      option = line_split[1].split('=')[0]
      value = line_split[1].split('=')[1]
      feathermodules.current_options[option] = value
   def args(self):
      return feathermodules.selected_attack['options'].keys()

# unset
class UnsetCommand(Command):
   def run(self, line):
      line_split = line.split()
      # unset option_name
      if len(line_split) != 2:
         print 'Usage: unset <option>'
         return False
      option = line_split[1]
      feathermodules.current_options[option] = feathermodules.selected_attack['options'][option]
   def args(self):
      return feathermodules.selected_attack['options'].keys()

# results
class ResultsCommand(Command):
   def run(self, line):
      if not feathermodules.results:
         print 'Last module failed to produce results.'
      elif feathermodules.results == True:
         print 'Last module succeeded, but did not return results.'
      else:
         print 'Last results (long values may be truncated):'
         print '-'*80
         for i in range(len(feathermodules.results)):
            print '{0:d}: {1:60s}'.format(i, repr(feathermodules.results[i]))

set_command = SetCommand('set', help='Set an option (i.e., "set num_answers=3"', dynamic_args=True)
unset = UnsetCommand('unset', help='Revert an option to its default value', dynamic_args=True)
options = OptionsCommand('options', help='Show the current option values', dynamic_args=True)
results = ResultsCommand('results', help='Show the results from the last module run')

# Build the console
fd_console = Console(prompt='\nFeatherDuster', prompt_delim='>')

fd_console.addChild(import_sample)
fd_console.addChild(console)
fd_console.addChild(use)
fd_console.addChild(analyze)
fd_console.addChild(autopwn)
fd_console.addChild(search)
fd_console.addChild(samples)
fd_console.addChild(modules)
fd_console.addChild(run)
fd_console.addChild(options)
fd_console.addChild(set_command)
fd_console.addChild(unset)
fd_console.addChild(results)

#--------
# Main menu
#

for filename in sys.argv[1:]:
   if filename in ['-h', '--help']:
      print 'Usage: python featherduster.py [ciphertext file 1] ... [ciphertext file n]'
      exit()
   try:
      sample_fh = open(filename,'r')
      feathermodules.samples.append(sample_fh.read())
      sample_fh.close()
   except:
      continue

print """Welcome to FeatherDuster!

To get started, use 'import' to load samples.
Then, use 'analyze' to analyze/decode samples and get attack recommendations.
Next, run the 'use' command to select an attack module.
Finally, use 'run' to run the attack and see its output.

For a command reference, press Enter on a blank line.
"""

fd_console.loop()

print '\nThank you for using FeatherDuster!'
<|endoftext|>


<commit_before>import time
import math
import numpy
import platform, sys, select

from ctrl.client import Controller
import ctrl.block as block
import ctrl.block.logger as logger

# initialize controller
HOST, PORT = "192.168.10.102", 9999
controller = Controller(host = HOST, port = PORT)
controller.add_sink('logger',
                    logger.Logger(),
                    ['clock','encoder1','encoder2'])
controller.add_sink('printer', block.Printer(endln = '\r'),
                    ['clock','motor1', 'encoder1','motor2', 'encoder2'])

print(controller.info('all'))

# define tests

def test(k, args, query_msg, failed_msg, test_function):
    print('\n> TEST #{}'.format(k))
    passed, retval = test_function(args)
    if not passed:
        print("> Failed test #{}: {}".format(k, retval))
        sys.exit(2)
    time.sleep(.1)
    if query_msg:
        answer = input('\n< ' + query_msg + ' [Y/n]').lower()
        if 'n' in answer:
            print("> Failed test #{}: {}".format(k, failed_msg))
            sys.exit(2)
    return retval

def test_motor_forward(args):

    motor, encoder = args[0], args[1]
    with controller:
        position1 = controller.get_signal(encoder)
        controller.set_signal(motor,100)
        time.sleep(2)
        position2 = controller.get_signal(encoder)
        controller.set_signal(motor,0)
    return True, (position1, position2)

def test_encoder(args):

    position1, position2 = args[0], args[1]
    if position2 == position1:
        return False, 'encoder1 not working'
    elif position2 < position1:
        return False, 'encoder1 reading reversed'
    return True, []

def test_reset_clock(args):

    t1 = controller.get_signal('clock')
    controller.set_source('clock', reset = True)
    controller.set_signal('motor1',0)
    with controller:
        time.sleep(.1)
    t2 = controller.get_signal('clock')
    if t2 > t1:
        return False, 'clock did not reset ({} > {})'.format(t2,t1)
    return True, []

def test_motor_backward(args):

    with controller:
        controller.set_source('clock', reset = True)
        position1 = controller.get_signal('encoder1')
        controller.set_signal('motor1',-100)
        time.sleep(2)
        position2 = controller.get_signal('encoder1')
        controller.set_signal(motor,0)
    return True, (position1, position2)

def test_motor_speeds(args):

    with controller:
        controller.set_source('clock', reset = True)
        controller.set_signal('motor1',100)
        time.sleep(1)
        controller.set_signal('motor1',50)
        time.sleep(1)
        controller.set_signal(motor,0)
    return True, []

def test_reset_encoder(args):

    with controller:
        controller.set_signal('motor1',0)
        time.sleep(.1) # sleep to make sure it is stoped
        position1 = controller.get_signal('encoder1')
        controller.set_source('encoder1', reset = True)
        time.sleep(.1) # sleep to make sure it did not move
        position2 = controller.get_signal('encoder1')

    if position2 != 0:
        return False, 'could not reset encoder1 ({} != 0)'.format(position2)
    return True, [position1, position2]

def test_potentiometer(args):

    # Calibrate potentiometer
    KMAX = 600
    TOL = 2
    #controller.get_source('pot1', ['full_scale', 'invert'])
    controller.set_source('pot1', full_scale = 1, invert = False)
    inverted = False
    full_scale = 100
    print("> Set the potentiometer to the minimum position and hit <ENTER>")
    k = 0
    while k < KMAX:
        pot_min, = controller.read_source('pot1')
        print('\r  reading = {:4.1f}'.format(pot_min), end='')
        time.sleep(.1)
        if select.select([sys.stdin], [], [], 0)[0]:
            line = sys.stdin.readline()
            if pot_min > TOL:
                inverted = True
                full_scale = pot_min
            break
        k += 1

    #if pot_min > TOL:
    #    return (False, 'potentiometer did not reach minimum')

    print("\n> Set the potentiometer to the maximum position and hit <ENTER>")
    k = 0
    pot_max = 0
    while k < KMAX:
        pot_max, = controller.read_source('pot1')
        print('\r  reading = {:4.1f}'.format(pot_max), end='')
        time.sleep(.1)
        if select.select([sys.stdin], [], [], 0)[0]:
            line = sys.stdin.readline()
            if pot_max > TOL:
                inverted = False
                full_scale = pot_max
            break
        k += 1

    #if pot_max < 100 - TOL:
    #    return (False, 'potentiometer did not reach maximum')

    if inverted:
        print('> Potentiometer is INVERTED')
    else:
        print('> Potentiometer IS NOT inverted')
    print('> Full scale is {}'.format(full_scale))

    return True, [pot_min, pot_max]

def main():

    print('Controller Test Routine')

    k = 1
    position1, position2 \
        = test('{}: MOTOR 1 FORWARD'.format(k),
               ('motor1','encoder1'),
               'Did the motor spin clockwise for two seconds?',
               'motor1 not working',
               test_motor_forward)

    # k += 1
    # test('{}: ENCODER 1 FORWARD'.format(k),
    #      (position1, position2),
    #      '',
    #      '',
    #      test_encoder)

    k += 1
    position1, position2 \
        = test('{}: MOTOR 2 FORWARD'.format(k),
               ('motor2','encoder2'),
               'Did the motor spin clockwise for two seconds?',
               'motor1 not working',
               test_motor_forward)

    k += 1
    test('{}: ENCODER 2 FORWARD'.format(k),
         (position1, position2),
         '',
         '',
         test_encoder)

    k += 1
    test('{}: CLOCK RESET'.format(k), (),
         '',
         '',
         test_reset_clock)

    k += 1
    position1, position2 \
        = test('{}: MOTOR BACKWARD'.format(k), (),
               'Did the motor spin counter-clockwise for two seconds?',
               'motor1 not working',
               test_motor_backward)

    k += 1
    test('{}: ENCODER BACKWARD'.format(k), (position2, position1),
         '',
         '',
         test_encoder)

    k += 1
    test('{}: MOTOR TWO SPEEDS'.format(k), (),
         'Did the motor spin at full speed then slowed down to half speed?',
         'motor1 not working',
         test_motor_speeds)

    k += 1
    position1, position2 \
        = test('{}: ENCODER RESET'.format(k), (),
               '',
               '',
               test_reset_encoder)

    if 'pot1' in controller.list_sources():
        k += 1
        position1, position2 \
            = test('{}: POTENTIOMETER RANGE'.format(k), (),
                   '',
                   '',
                   test_potentiometer)

    # Identify motor
    print('> Identifying motor parameters...')
    with controller:
        controller.set_signal('motor1',0)
        controller.set_source('encoder1', reset = True)

        controller.set_sink('logger', reset = True)
        controller.set_source('clock', reset = True)
        time.sleep(1)
        controller.set_signal('motor1',100)
        time.sleep(5)

        clock = controller.get_source('clock', 'period')
        Ts = clock['period']

        log = controller.read_sink('logger')
        t = log[:,0]
        position = log[:,1]
        velocity = numpy.zeros(t.shape, float)
        velocity[1:] = (position[1:]-position[:-1])/(t[1:]-t[:-1])

        max_velocity = numpy.max(velocity)
        ind = numpy.argwhere(velocity > .5*max_velocity)[0]

        #print('ind = {}'.format(ind))
        ind += int(2/Ts)
        #print('>> len = {}'.format(len(velocity)))
        #print('>> ind = {}'.format(ind))
        k = numpy.mean(velocity[ind:])

        print('> period = {}'.format(Ts))
        print('> max velocity = {:5.3f}'.format(max_velocity))

        print('> gain      = {:5.3f}'.format(k))

        ind = numpy.argwhere( (velocity > 0.1*k ) &
                              (velocity < 0.9*k ) )
        t10 = float(t[ind[0]])
        t90 = float(t[ind[-1]])
        tau = (t90 - t10) / 2.2
        print('> rise time = {:5.3f}'.format(t90 - t10))
        print('> lambda    = {:5.3f}'.format(1/tau))

if __name__ == "__main__":
    main()
<commit_msg>Added enabled_pin to motor<commit_after>import time
import math
import numpy
import platform, sys, select

from ctrl.client import Controller
import ctrl.block as block
import ctrl.block.logger as logger

# initialize controller
HOST, PORT = "192.168.10.102", 9999
controller = Controller(host = HOST, port = PORT)
controller.add_sink('logger',
                    logger.Logger(),
                    ['clock','encoder1','encoder2'])
controller.add_sink('printer', block.Printer(endln = '\r'),
                    ['clock','motor1', 'encoder1','motor2', 'encoder2'])

print(controller.info('all'))

# define tests

def test(k, args, query_msg, failed_msg, test_function):
    print('\n> TEST #{}'.format(k))
    passed, retval = test_function(args)
    if not passed:
        print("> Failed test #{}: {}".format(k, retval))
        sys.exit(2)
    time.sleep(.1)
    if query_msg:
        answer = input('\n< ' + query_msg + ' [Y/n]').lower()
        if 'n' in answer:
            print("> Failed test #{}: {}".format(k, failed_msg))
            sys.exit(2)
    return retval

def test_motor_forward(args):

    motor, encoder = args[0], args[1]
    with controller:
        position1 = controller.get_signal(encoder)
        controller.set_signal(motor,100)
        time.sleep(2)
        position2 = controller.get_signal(encoder)
        controller.set_signal(motor,0)
    return True, (position1, position2)

def test_encoder(args):

    position1, position2 = args[0], args[1]
    if position2 == position1:
        return False, 'encoder1 not working'
    elif position2 < position1:
        return False, 'encoder1 reading reversed'
    return True, []

def test_reset_clock(args):

    t1 = controller.get_signal('clock')
    controller.set_source('clock', reset = True)
    with controller:
        time.sleep(.1)
    t2 = controller.get_signal('clock')
    if t2 > t1:
        return False, 'clock did not reset ({} > {})'.format(t2,t1)
    return True, []

def test_motor_backward(args):

    motor, encoder = args[0], args[1]
    with controller:
        controller.set_source('clock', reset = True)
        position1 = controller.get_signal(encoder)
        controller.set_signal(motor,-100)
        time.sleep(2)
        position2 = controller.get_signal(encoder)
        controller.set_signal(motor,0)
    return True, (position1, position2)

def test_motor_speeds(args):

    motor, encoder = args[0], args[1]
    with controller:
        controller.set_source('clock', reset = True)
        controller.set_signal(motor,100)
        time.sleep(1)
        controller.set_signal(motor,50)
        time.sleep(1)
        controller.set_signal(motor,0)
    return True, []

def test_reset_encoder(args):

    encoder = args[0]
    with controller:
        time.sleep(.1) # sleep to make sure it is stoped
        position1 = controller.get_signal(encoder)
        controller.set_source(encoder, reset = True)
        time.sleep(.1) # sleep to make sure it did not move
        position2 = controller.get_signal(encoder)

    if position2 != 0:
        return False, 'could not reset encoder1 ({} != 0)'.format(position2)
    return True, [position1, position2]

def test_potentiometer(args):

    # Calibrate potentiometer
    KMAX = 600
    TOL = 2
    #controller.get_source('pot1', ['full_scale', 'invert'])
    controller.set_source('pot1', full_scale = 1, invert = False)
    inverted = False
    full_scale = 100
    print("> Set the potentiometer to the minimum position and hit <ENTER>")
    k = 0
    while k < KMAX:
        pot_min, = controller.read_source('pot1')
        print('\r  reading = {:4.1f}'.format(pot_min), end='')
        time.sleep(.1)
        if select.select([sys.stdin], [], [], 0)[0]:
            line = sys.stdin.readline()
            if pot_min > TOL:
                inverted = True
                full_scale = pot_min
            break
        k += 1

    #if pot_min > TOL:
    #    return (False, 'potentiometer did not reach minimum')

    print("\n> Set the potentiometer to the maximum position and hit <ENTER>")
    k = 0
    pot_max = 0
    while k < KMAX:
        pot_max, = controller.read_source('pot1')
        print('\r  reading = {:4.1f}'.format(pot_max), end='')
        time.sleep(.1)
        if select.select([sys.stdin], [], [], 0)[0]:
            line = sys.stdin.readline()
            if pot_max > TOL:
                inverted = False
                full_scale = pot_max
            break
        k += 1

    #if pot_max < 100 - TOL:
    #    return (False, 'potentiometer did not reach maximum')

    if inverted:
        print('> Potentiometer is INVERTED')
    else:
        print('> Potentiometer IS NOT inverted')
    print('> Full scale is {}'.format(full_scale))

    return True, [pot_min, pot_max]

def main():

    print('Controller Test Routine')

    k = 1
    position1, position2 \
        = test('{}: MOTOR 1 FORWARD'.format(k),
               ('motor1','encoder1'),
               'Did the motor spin clockwise for two seconds?',
               'motor1 not working',
               test_motor_forward)

    k += 1
    test('{}: ENCODER 1 FORWARD'.format(k),
         (position1, position2),
         '',
         '',
         test_encoder)

    k += 1
    position1, position2 \
        = test('{}: MOTOR 2 FORWARD'.format(k),
               ('motor2','encoder2'),
               'Did the motor spin clockwise for two seconds?',
               'motor1 not working',
               test_motor_forward)

    k += 1
    test('{}: ENCODER 2 FORWARD'.format(k),
         (position1, position2),
         '',
         '',
         test_encoder)

    k += 1
    test('{}: CLOCK RESET'.format(k), (),
         '',
         '',
         test_reset_clock)

    k += 1
    position1, position2 \
        = test('{}: MOTOR 1 BACKWARD'.format(k),
               ('motor1','encoder1'),
               'Did the motor spin counter-clockwise for two seconds?',
               'motor1 not working',
               test_motor_backward)

    k += 1
    test('{}: ENCODER 1 BACKWARD'.format(k),
         (position2, position1),
         '',
         '',
         test_encoder)

    k += 1
    position1, position2 \
        = test('{}: MOTOR 2 BACKWARD'.format(k),
               ('motor2','encoder2'),
               'Did the motor spin counter-clockwise for two seconds?',
               'motor1 not working',
               test_motor_backward)

    k += 1
    test('{}: ENCODER 2 BACKWARD'.format(k),
         (position2, position1),
         '',
         '',
         test_encoder)

    k += 1
    test('{}: MOTOR 1 TWO SPEEDS'.format(k),
         ('motor1','encoder1'),
         'Did the motor spin at full speed then slowed down to half speed?',
         'motor1 not working',
         test_motor_speeds)

    k += 1
    test('{}: MOTOR 2 TWO SPEEDS'.format(k),
         ('motor2','encoder2'),
         'Did the motor spin at full speed then slowed down to half speed?',
         'motor1 not working',
         test_motor_speeds)

    k += 1
    position1, position2 \
        = test('{}: ENCODER 1 RESET'.format(k),
               ('encoder1'),
               '',
               '',
               test_reset_encoder)

    k += 1
    position1, position2 \
        = test('{}: ENCODER 2 RESET'.format(k),
               ('encoder2'),
               '',
               '',
               test_reset_encoder)

    if 'pot1' in controller.list_sources():
        k += 1
        position1, position2 \
            = test('{}: POTENTIOMETER RANGE'.format(k), (),
                   '',
                   '',
                   test_potentiometer)

    # Identify motor
    print('> Identifying motor parameters...')
    with controller:
        controller.set_signal('motor1',0)
        controller.set_source('encoder1', reset = True)

        controller.set_sink('logger', reset = True)
        controller.set_source('clock', reset = True)
        time.sleep(1)
        controller.set_signal('motor1',100)
        time.sleep(5)

        clock = controller.get_source('clock', 'period')
        Ts = clock['period']

        log = controller.read_sink('logger')
        t = log[:,0]
        position = log[:,1]
        velocity = numpy.zeros(t.shape, float)
        velocity[1:] = (position[1:]-position[:-1])/(t[1:]-t[:-1])

        max_velocity = numpy.max(velocity)
        ind = numpy.argwhere(velocity > .5*max_velocity)[0]

        #print('ind = {}'.format(ind))
        ind += int(2/Ts)
        #print('>> len = {}'.format(len(velocity)))
        #print('>> ind = {}'.format(ind))
        k = numpy.mean(velocity[ind:])

        print('> period = {}'.format(Ts))
        print('> max velocity = {:5.3f}'.format(max_velocity))

        print('> gain      = {:5.3f}'.format(k))

        ind = numpy.argwhere( (velocity > 0.1*k ) &
                              (velocity < 0.9*k ) )
        t10 = float(t[ind[0]])
        t90 = float(t[ind[-1]])
        tau = (t90 - t10) / 2.2
        print('> rise time = {:5.3f}'.format(t90 - t10))
        print('> lambda    = {:5.3f}'.format(1/tau))

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


<commit_before>""""
BUGS

  - Baten verdwijnen

TODO

- 'prognose' posten toevoegen.
- verplaats alle decode/encode naar model (db_2_regel)

- Het kan zijn dat er begroting is op een KS die niet geboekt is. Dan komt hij NIET in het overzicht. FIXEN!

- Importeer functie maken die vraagt om welke kolom wat bevat (namen zijn strings die iedereen apart instelt in SAP....)

 - 'AFREKORD' grootboek weer toevoegen alleen als hij ook bestaat voor die orders.

 - kpl support toevoegen

 - WBS support toevoegen (betekend lijst maken met welk wbs bij welke groep hoort..)

- Show negative bestedingsruimte in red and bold.

- Merge overview en view class (lots of double code)

 - ik bedacht me later dat het misschien een goed idee is om boven alle tabbladen de boodschap te zetten in boldface:
Notice that these records show only transactions up to (datum van laatste update)

- Rewrite templates to be more modular with css and header parts:
    http://webpy.org/cookbook/layout_template

Somday/Maybe:

#cool d3 ding:
- http://bl.ocks.org/NPashaP/96447623ef4d342ee09b
"""
import web
web.config.debug = True #must be done before the rest.
import model
import GrootBoek
import GrootBoekGroep
import os
from config import config
from functions import moneyfmt, IpBlock

# web-pages
import webaccess
import webreport
import websalaris
import webadmin

class Index:
    def __init__(self):
        pass

    def GET(self):
        return render.index()

class View:
    settings_form = web.form.Form(
        #web.form.Checkbox("lovelycheckbox", description="lovelycheckbox", class_="standard", value="something.. Anything!"),
        web.form.Dropdown('jaar', [(2015, '2015'), (2014, '2014'), (2013, '2013'), (2012, '2012')]),
        web.form.Dropdown('maxdepth', [(0,'1. Totals'), (1,'2. Subtotals'), (10, '3. Details')]),
        web.form.Dropdown('ksgroep', []),
        web.form.Checkbox('clean'),
        web.form.Dropdown('periode', [('', 'all')]),
        web.form.Button('Update', 'update'),
    )
    def __init__(self):
        pass

    def get_post_params(self, form):

        maxdepth = form['maxdepth'].value
        if maxdepth is None:
            try:
                maxdepth = int(web.input()['maxdepth'])
            except:
                maxdepth = 1

        KSgroep = form['ksgroep'].value
        if KSgroep is None:
            try:
                KSgroep = int(web.input()['ksgroep'])
            except:
                KSgroep = 0

        jaar = form['jaar'].value
        if jaar is None:
            try:
                jaar = int(web.input()['jaar'])
            except:
                jaar = 2015

        periode = form['periode'].value
        if periode is None:
            try:
                periode = int(web.input()['periode'])
            except:
                periode = ''

        clean = web.input().has_key('clean')

        return {"maxdepth":maxdepth, "KSgroep":KSgroep, "jaar":jaar, "periode":periode, "clean":clean}

    def view(self, userHash, order, parent):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")

        form = self.settings_form()
        KSgroepen = model.loadKSgroepen()
        settings = self.get_post_params(form)
        if parent == 'GET':
            settings["clean"] = True
        self.fill_dropdowns(form, settings, KSgroepen)

        order = int(order)
        grootboek = KSgroepen[settings["KSgroep"]]
        sapdatum = config['lastSAPexport']

        root = GrootBoek.load(order, grootboek, settings["jaar"], settings["periode"])
        if settings["clean"]:
            root.clean_empty_nodes()

#TODO Begroting uit sap 'plan' halen!
        #begroting = model.get_begroting() # dit is de oude functie van VU
        totaal = {}
        htmlgrootboek = []

        totaal['order'] = order
        totaal['baten'] = 0
        totaal['lasten'] = 0
        totaal['ruimte'] = 0

        reserves = model.get_reserves()
        try:
            totaal['reserve'] = reserves[str(order)]
        except:
            totaal['reserve'] = 0

        totaal['begroting'] = 0#float(begroting[str(order)])

        if totaal['reserve'] < 0:
            totaal['ruimte'] = -1*(root.totaalGeboektTree + root.totaalObligosTree) + totaal['begroting'] + totaal['reserve']
        else:
            totaal['ruimte'] = -1*(root.totaalGeboektTree + root.totaalObligosTree) + totaal['begroting']

        for child in root.children:
            htmlgrootboek.append(child.html_tree(render, settings["maxdepth"], 0))
# TODO: DIT IS SPECIFIEK VOOR 29FALW2
            if child.name == 'BATEN-2900':
                totaal['baten'] = (-1*(child.totaalGeboektTree + child.totaalObligosTree))
            elif child.name == 'LASTEN2900':
                totaal['lasten'] = (-1*(child.totaalGeboektTree + child.totaalObligosTree))

        totaal['reserve'] = moneyfmt(totaal['reserve'])
        totaal['ruimte'] = moneyfmt(totaal['ruimte'])
        totaal['baten'] = moneyfmt(totaal['baten'])
        totaal['lasten'] = moneyfmt(totaal['lasten'])
        totaal['begroting'] = moneyfmt(totaal['begroting'])

# TODO: INFO ERGENS ANDERS VANDAAN HALEN VOOR UL
        #if str(order)[4] != '0' and str(order)[4] != '1':
            #return render.viewproject(grootboek, sapdatum, htmlgrootboek, totaal)

        #print '----------------'
        #root.walk_tree(9999)
        return render.vieworder(form, grootboek, sapdatum, htmlgrootboek, totaal)

    def POST(self, userHash, order):
        return self.view(userHash, order, 'POST')

    def GET(self, userHash, order):
        return self.view(userHash, order, 'GET')

    def fill_dropdowns(self, form, settings, KSgroepen):
        dropdownlist = []
        for i, path in enumerate(KSgroepen):
            dropdownlist.append( (i, os.path.split(path)[-1] ))
        form.ksgroep.args = dropdownlist

        form.ksgroep.value = settings["KSgroep"]
        form.jaar.value = settings["jaar"]
        form.maxdepth.value = settings["maxdepth"]
        form.periode.value = settings["periode"]
        form.clean.checked = settings["clean"]

class Report:
    def get_params(self):

        try:
            jaar = int(web.input()['jaar'])
        except:
            jaar = 2015

        try:
            periode = web.input()['periode']
        except:
            periode = '0,1,2,3,4,5,6,7,8,9,10,11,12'

        try:
            groep = web.input()['groep']
        except:
            groep = 'TOTAAL'

        return jaar, periode, groep

    def POST(self, userHash):
        return None

    def GET(self, userHash):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")
        jaar, periode, groep = self.get_params()
        report = webreport.groep_report(userHash, render, groep, jaar)
        return render.report(report)

class Salaris:
    def get_params(self):

        try:
            jaar = int(web.input()['jaar'])
        except:
            jaar = 2015

        try:
            groep = web.input()['groep']
        except:
            groep = 'TOTAAL'

        return jaar, groep

    def POST(self, userHash):
        return None

    def GET(self, userHash):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")
        jaar, groep = self.get_params()
        salaris = websalaris.groep_report(userHash, render, groep, jaar)
        return render.salaris(salaris)

class Login:
    login_form = web.form.Form(
        web.form.Password('password', web.form.notnull),
        web.form.Button('Login'),
        )

    def GET(self, userHash):
        form = self.login_form()
        return render.login(form, msg='')

    def POST(self, userHash):
        form = self.login_form()
        if not form.validates():
            return render.login(form)

        if form['password'].value == config["globalPW"]:
            session.logged_in = True
            raise web.seeother('/report'+userHash)

        return render.login(form, 'Wrong Password')

class Admin:
    upload_form = web.form.Form(
        web.form.File('myfile'),
        web.form.Button('Upload data'),
        )
    def GET(self):
        form = self.upload_form()
        msg = webadmin.checkDB()
        return render.webadmin_overview(form, msg)

    def POST(self):
        form = self.upload_form()
        x = web.input(myfile={})
        filedir = './data' # change this to the directory you want to store the file in.
        allowed = ['.txt', '.xlsx', '.xls', '.cvs']

        msg = ['Uploading file.']
        if 'myfile' in x:
            pwd, filenamefull = os.path.split(x.myfile.filename)
            filename, extension = os.path.splitext(filenamefull)
            if extension in allowed:
                fout = open(filedir +'/'+ filenamefull,'wb')
                fout.write(x.myfile.file.read())
                fout.close()
                msg.append('upload succes!')
            else:
                msg.append('file not allowed')

        return render.webadmin_overview(form, msg)

class Logout:
    def __init__(self):
        pass

    def GET(self):
        session.logged_in = False
        return render.logout()

### Url mappings
urls = (
    '/', 'Index',
    '/view/(.+)/(\d+)', 'View',
    '/login(.+)', 'Login',
    '/logout', 'Logout',
    '/report/(.+)', 'Report',
    '/salaris/(.+)', 'Salaris',
    '/admin', 'Admin',
)

### Templates
t_globals = {
    'datestr': web.datestr
}
render = web.template.render('templates/')
app = web.application(urls, globals())
if web.config.get('_session') is None:
    session = web.session.Session(app, web.session.DiskStore('sessions'), {'count': 0})
    web.config._session = session
else:
    session = web.config._session

if __name__ == "__main__":
    model.gen_auth_list(config['salt'])
    app.run()
<commit_msg>asks for input type and checks all user input<commit_after>""""
BUGS

  - Baten verdwijnen

TODO

- 'prognose' posten toevoegen.
- verplaats alle decode/encode naar model (db_2_regel)

- Het kan zijn dat er begroting is op een KS die niet geboekt is. Dan komt hij NIET in het overzicht. FIXEN!

- Importeer functie maken die vraagt om welke kolom wat bevat (namen zijn strings die iedereen apart instelt in SAP....)

 - 'AFREKORD' grootboek weer toevoegen alleen als hij ook bestaat voor die orders.

 - kpl support toevoegen

 - WBS support toevoegen (betekend lijst maken met welk wbs bij welke groep hoort..)

- Show negative bestedingsruimte in red and bold.

- Merge overview en view class (lots of double code)

 - ik bedacht me later dat het misschien een goed idee is om boven alle tabbladen de boodschap te zetten in boldface:
Notice that these records show only transactions up to (datum van laatste update)

- Rewrite templates to be more modular with css and header parts:
    http://webpy.org/cookbook/layout_template

Somday/Maybe:

#cool d3 ding:
- http://bl.ocks.org/NPashaP/96447623ef4d342ee09b
"""
import web
web.config.debug = True #must be done before the rest.
import model
import GrootBoek
import GrootBoekGroep
import os
from config import config
from functions import moneyfmt, IpBlock

# web-pages
import webaccess
import webreport
import websalaris
import webadmin

class Index:
    def __init__(self):
        pass

    def GET(self):
        return render.index()

class View:
    settings_form = web.form.Form(
        #web.form.Checkbox("lovelycheckbox", description="lovelycheckbox", class_="standard", value="something.. Anything!"),
        web.form.Dropdown('jaar', [(2015, '2015'), (2014, '2014'), (2013, '2013'), (2012, '2012')]),
        web.form.Dropdown('maxdepth', [(0,'1. Totals'), (1,'2. Subtotals'), (10, '3. Details')]),
        web.form.Dropdown('ksgroep', []),
        web.form.Checkbox('clean'),
        web.form.Dropdown('periode', [('', 'all')]),
        web.form.Button('Update', 'update'),
    )
    def __init__(self):
        pass

    def get_post_params(self, form):

        maxdepth = form['maxdepth'].value
        if maxdepth is None:
            try:
                maxdepth = int(web.input()['maxdepth'])
            except:
                maxdepth = 1

        KSgroep = form['ksgroep'].value
        if KSgroep is None:
            try:
                KSgroep = int(web.input()['ksgroep'])
            except:
                KSgroep = 0

        jaar = form['jaar'].value
        if jaar is None:
            try:
                jaar = int(web.input()['jaar'])
            except:
                jaar = 2015

        periode = form['periode'].value
        if periode is None:
            try:
                periode = int(web.input()['periode'])
            except:
                periode = ''

        clean = web.input().has_key('clean')

        return {"maxdepth":maxdepth, "KSgroep":KSgroep, "jaar":jaar, "periode":periode, "clean":clean}

    def view(self, userHash, order, parent):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")

        form = self.settings_form()
        KSgroepen = model.loadKSgroepen()
        settings = self.get_post_params(form)
        if parent == 'GET':
            settings["clean"] = True
        self.fill_dropdowns(form, settings, KSgroepen)

        order = int(order)
        grootboek = KSgroepen[settings["KSgroep"]]
        sapdatum = config['lastSAPexport']

        root = GrootBoek.load(order, grootboek, settings["jaar"], settings["periode"])
        if settings["clean"]:
            root.clean_empty_nodes()

#TODO Begroting uit sap 'plan' halen!
        #begroting = model.get_begroting() # dit is de oude functie van VU
        totaal = {}
        htmlgrootboek = []

        totaal['order'] = order
        totaal['baten'] = 0
        totaal['lasten'] = 0
        totaal['ruimte'] = 0

        reserves = model.get_reserves()
        try:
            totaal['reserve'] = reserves[str(order)]
        except:
            totaal['reserve'] = 0

        totaal['begroting'] = 0#float(begroting[str(order)])

        if totaal['reserve'] < 0:
            totaal['ruimte'] = -1*(root.totaalGeboektTree + root.totaalObligosTree) + totaal['begroting'] + totaal['reserve']
        else:
            totaal['ruimte'] = -1*(root.totaalGeboektTree + root.totaalObligosTree) + totaal['begroting']

        for child in root.children:
            htmlgrootboek.append(child.html_tree(render, settings["maxdepth"], 0))
# TODO: DIT IS SPECIFIEK VOOR 29FALW2
            if child.name == 'BATEN-2900':
                totaal['baten'] = (-1*(child.totaalGeboektTree + child.totaalObligosTree))
            elif child.name == 'LASTEN2900':
                totaal['lasten'] = (-1*(child.totaalGeboektTree + child.totaalObligosTree))

        totaal['reserve'] = moneyfmt(totaal['reserve'])
        totaal['ruimte'] = moneyfmt(totaal['ruimte'])
        totaal['baten'] = moneyfmt(totaal['baten'])
        totaal['lasten'] = moneyfmt(totaal['lasten'])
        totaal['begroting'] = moneyfmt(totaal['begroting'])

# TODO: INFO ERGENS ANDERS VANDAAN HALEN VOOR UL
        #if str(order)[4] != '0' and str(order)[4] != '1':
            #return render.viewproject(grootboek, sapdatum, htmlgrootboek, totaal)

        #print '----------------'
        #root.walk_tree(9999)
        return render.vieworder(form, grootboek, sapdatum, htmlgrootboek, totaal)

    def POST(self, userHash, order):
        return self.view(userHash, order, 'POST')

    def GET(self, userHash, order):
        return self.view(userHash, order, 'GET')

    def fill_dropdowns(self, form, settings, KSgroepen):
        dropdownlist = []
        for i, path in enumerate(KSgroepen):
            dropdownlist.append( (i, os.path.split(path)[-1] ))
        form.ksgroep.args = dropdownlist

        form.ksgroep.value = settings["KSgroep"]
        form.jaar.value = settings["jaar"]
        form.maxdepth.value = settings["maxdepth"]
        form.periode.value = settings["periode"]
        form.clean.checked = settings["clean"]

class Report:
    def get_params(self):

        try:
            jaar = int(web.input()['jaar'])
        except:
            jaar = 2015

        try:
            periode = web.input()['periode']
        except:
            periode = '0,1,2,3,4,5,6,7,8,9,10,11,12'

        try:
            groep = web.input()['groep']
        except:
            groep = 'TOTAAL'

        return jaar, periode, groep

    def POST(self, userHash):
        return None

    def GET(self, userHash):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")
        jaar, periode, groep = self.get_params()
        report = webreport.groep_report(userHash, render, groep, jaar)
        return render.report(report)

class Salaris:
    def get_params(self):

        try:
            jaar = int(web.input()['jaar'])
        except:
            jaar = 2015

        try:
            groep = web.input()['groep']
        except:
            groep = 'TOTAAL'

        return jaar, groep

    def POST(self, userHash):
        return None

    def GET(self, userHash):
        if not webaccess.check_auth(session, userHash):
            return web.notfound("Sorry the page you were looking for was not found.")
        jaar, groep = self.get_params()
        salaris = websalaris.groep_report(userHash, render, groep, jaar)
        return render.salaris(salaris)

class Login:
    login_form = web.form.Form(
        web.form.Password('password', web.form.notnull),
        web.form.Button('Login'),
        )

    def GET(self, userHash):
        form = self.login_form()
        return render.login(form, msg='')

    def POST(self, userHash):
        form = self.login_form()
        if not form.validates():
            return render.login(form)

        if form['password'].value == config["globalPW"]:
            session.logged_in = True
            raise web.seeother('/report'+userHash)

        return render.login(form, 'Wrong Password')

class Admin:
    upload_form = web.form.Form(
        web.form.File('myfile'),
        web.form.Dropdown('Type', [('', ''),('geboekt','Realisatie'), ('obligo','Obligo'), ('plan', 'Begroting Orders'), ('salaris', 'Salarissen'), ('salaris_begroting', 'Begroting Salarissen')]),
        web.form.Button('Upload data'),
        )

    def GET(self):
        form = self.upload_form()
        msg = webadmin.checkDB()
        return render.webadmin_overview(form, msg)

    def POST(self):
        form = self.upload_form()
        x = web.input(myfile={})
        filedir = './data' # change this to the directory you want to store the file in.
        allowed = ['.txt', '.xlsx', '.xls', '.cvs']

        msg = ['Uploading file.']
        succes_upload = False
        if 'myfile' in x:
            pwd, filenamefull = os.path.split(x.myfile.filename)
            filename, extension = os.path.splitext(filenamefull)
            if extension in allowed:
                fout = open(filedir +'/'+ filenamefull,'wb')
                fout.write(x.myfile.file.read())
                fout.close()
                succes_upload = True

        if not succes_upload:
            msg.append('upload failed!')
            return render.webadmin_overview(form, msg)

        msg.append('upload succes')
        table = web.input()['Type']
        table_allowed = False
        if table in ['geboekt', 'obligo', 'plan', 'salaris', 'salaris_begroting']:
            table_allowed = True

        if not table_allowed:
            msg.append('Type not selected!')
            return render.webadmin_overview(form, msg)

        msg.append('Preparing to process data for table: ' + table)

        # excel -> csv
        # extract headers csv
        # Move old table -> backup
        # Create new table (use csv headers!)
        # Fill table from CSV

        return render.webadmin_overview(form, msg)

class Logout:
    def __init__(self):
        pass

    def GET(self):
        session.logged_in = False
        return render.logout()

### Url mappings
urls = (
    '/', 'Index',
    '/view/(.+)/(\d+)', 'View',
    '/login(.+)', 'Login',
    '/logout', 'Logout',
    '/report/(.+)', 'Report',
    '/salaris/(.+)', 'Salaris',
    '/admin', 'Admin',
)

### Templates
t_globals = {
    'datestr': web.datestr
}
render = web.template.render('templates/')
app = web.application(urls, globals())
if web.config.get('_session') is None:
    session = web.session.Session(app, web.session.DiskStore('sessions'), {'count': 0})
    web.config._session = session
else:
    session = web.config._session

if __name__ == "__main__":
    model.gen_auth_list(config['salt'])
    app.run()
<|endoftext|>


<commit_before><commit_msg>FIX have modules do what they claim<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python
#
# p4-fast-export.py
#
# Author: Simon Hausmann <hausmann@kde.org>
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
#
# TODO:
#       - support integrations (at least p4i)
#       - support incremental imports
#       - create tags
#       - instead of reading all files into a variable try to pipe from
#       - support p4 submit (hah!)
#       - don't hardcode the import to master
#
import os, string, sys, time
import marshal, popen2

if len(sys.argv) != 2:
    print "usage: %s //depot/path[@revRange]" % sys.argv[0]
    print "\n    example:"
    print "    %s //depot/my/project/ -- to import everything"
    print "    %s //depot/my/project/@1,6 -- to import only from revision 1 to 6"
    print ""
    print "    (a ... is not needed in the path p4 specification, it's added implicitly)"
    print ""
    sys.exit(1)

prefix = sys.argv[1]
changeRange = ""
try:
    atIdx = prefix.index("@")
    changeRange = prefix[atIdx:]
    prefix = prefix[0:atIdx]
except ValueError:
    changeRange = ""

if prefix.endswith("..."):
    prefix = prefix[:-3]

if not prefix.endswith("/"):
    prefix += "/"

def p4CmdList(cmd):
    pipe = os.popen("p4 -G %s" % cmd, "rb")
    result = []
    try:
        while True:
            entry = marshal.load(pipe)
            result.append(entry)
    except EOFError:
        pass
    pipe.close()
    return result

def p4Cmd(cmd):
    list = p4CmdList(cmd)
    result = {}
    for entry in list:
        result.update(entry)
    return result;

def getUserMap():
    users = {}

    for output in p4CmdList("users"):
        if not output.has_key("User"):
            continue
        users[output["User"]] = output["FullName"] + " <" + output["Email"] + ">"
    return users

users = getUserMap()

output = os.popen("p4 changes %s...%s" % (prefix, changeRange)).readlines()

changes = []
for line in output:
    changeNum = line.split(" ")[1]
    changes.append(changeNum)

changes.reverse()

sys.stderr.write("\n")

tz = - time.timezone / 36

gitOutput, gitStream, gitError = popen2.popen3("git-fast-import")

cnt = 1
for change in changes:
    description = p4Cmd("describe %s" % change)

    sys.stdout.write("\rimporting revision %s (%s%%)" % (change, cnt * 100 / len(changes)))
    sys.stdout.flush()
    cnt = cnt + 1

    epoch = description["time"]
    author = description["user"]

    gitStream.write("commit refs/heads/master\n")
    if author in users:
        gitStream.write("committer %s %s %s\n" % (users[author], epoch, tz))
    else:
        gitStream.write("committer %s <a@b> %s %s\n" % (author, epoch, tz))
    gitStream.write("data <<EOT\n")
    gitStream.write(description["desc"])
    gitStream.write("EOT\n\n")

    fnum = 0
    while description.has_key("depotFile%s" % fnum):
        path = description["depotFile%s" % fnum]
        if not path.startswith(prefix):
            print "\nchanged files: ignoring path %s outside of %s in change %s" % (path, prefix, change)
            fnum = fnum + 1
            continue

        rev = description["rev%s" % fnum]
        depotPath = path + "#" + rev
        relPath = path[len(prefix):]
        action = description["action%s" % fnum]

        if action == "delete":
            gitStream.write("D %s\n" % relPath)
        else:
            mode = 644
            if description["type%s" % fnum].startswith("x"):
                mode = 755

            data = os.popen("p4 print -q \"%s\"" % depotPath, "rb").read()

            gitStream.write("M %s inline %s\n" % (mode, relPath))
            gitStream.write("data %s\n" % len(data))
            gitStream.write(data)
            gitStream.write("\n")

        fnum = fnum + 1

    gitStream.write("\n")

gitStream.close()
gitOutput.close()
gitError.close()

print ""
<commit_msg>Create a git tag for every changeset imported from perforce.<commit_after>#!/usr/bin/python
#
# p4-fast-export.py
#
# Author: Simon Hausmann <hausmann@kde.org>
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
#
# TODO:
#       - support integrations (at least p4i)
#       - support incremental imports
#       - create tags
#       - instead of reading all files into a variable try to pipe from
#       - support p4 submit (hah!)
#       - don't hardcode the import to master
#
import os, string, sys, time
import marshal, popen2

if len(sys.argv) != 2:
    print "usage: %s //depot/path[@revRange]" % sys.argv[0]
    print "\n    example:"
    print "    %s //depot/my/project/ -- to import everything"
    print "    %s //depot/my/project/@1,6 -- to import only from revision 1 to 6"
    print ""
    print "    (a ... is not needed in the path p4 specification, it's added implicitly)"
    print ""
    sys.exit(1)

prefix = sys.argv[1]
changeRange = ""
try:
    atIdx = prefix.index("@")
    changeRange = prefix[atIdx:]
    prefix = prefix[0:atIdx]
except ValueError:
    changeRange = ""

if prefix.endswith("..."):
    prefix = prefix[:-3]

if not prefix.endswith("/"):
    prefix += "/"

def p4CmdList(cmd):
    pipe = os.popen("p4 -G %s" % cmd, "rb")
    result = []
    try:
        while True:
            entry = marshal.load(pipe)
            result.append(entry)
    except EOFError:
        pass
    pipe.close()
    return result

def p4Cmd(cmd):
    list = p4CmdList(cmd)
    result = {}
    for entry in list:
        result.update(entry)
    return result;

def getUserMap():
    users = {}

    for output in p4CmdList("users"):
        if not output.has_key("User"):
            continue
        users[output["User"]] = output["FullName"] + " <" + output["Email"] + ">"
    return users

users = getUserMap()

output = os.popen("p4 changes %s...%s" % (prefix, changeRange)).readlines()

changes = []
for line in output:
    changeNum = line.split(" ")[1]
    changes.append(changeNum)

changes.reverse()

sys.stderr.write("\n")

tz = - time.timezone / 36

gitOutput, gitStream, gitError = popen2.popen3("git-fast-import")

cnt = 1
for change in changes:
    description = p4Cmd("describe %s" % change)

    sys.stdout.write("\rimporting revision %s (%s%%)" % (change, cnt * 100 / len(changes)))
    sys.stdout.flush()
    cnt = cnt + 1

    epoch = description["time"]
    author = description["user"]

    gitStream.write("commit refs/heads/master\n")
    committer = ""
    if author in users:
        committer = "%s %s %s" % (users[author], epoch, tz)
    else:
        committer = "%s <a@b> %s %s" % (author, epoch, tz)

    gitStream.write("committer %s\n" % committer)

    gitStream.write("data <<EOT\n")
    gitStream.write(description["desc"])
    gitStream.write("\n[ imported from %s; change %s ]\n" % (prefix, change))
    gitStream.write("EOT\n\n")

    fnum = 0
    while description.has_key("depotFile%s" % fnum):
        path = description["depotFile%s" % fnum]
        if not path.startswith(prefix):
            print "\nchanged files: ignoring path %s outside of %s in change %s" % (path, prefix, change)
            fnum = fnum + 1
            continue

        rev = description["rev%s" % fnum]
        depotPath = path + "#" + rev
        relPath = path[len(prefix):]
        action = description["action%s" % fnum]

        if action == "delete":
            gitStream.write("D %s\n" % relPath)
        else:
            mode = 644
            if description["type%s" % fnum].startswith("x"):
                mode = 755

            data = os.popen("p4 print -q \"%s\"" % depotPath, "rb").read()

            gitStream.write("M %s inline %s\n" % (mode, relPath))
            gitStream.write("data %s\n" % len(data))
            gitStream.write(data)
            gitStream.write("\n")

        fnum = fnum + 1

    gitStream.write("\n")

    gitStream.write("tag p4/%s\n" % change)
    gitStream.write("from refs/heads/master\n");
    gitStream.write("tagger %s\n" % committer);
    gitStream.write("data 0\n\n")

gitStream.close()
gitOutput.close()
gitError.close()

print ""
<|endoftext|>