<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>
#
##############################################################################

from osv import osv
from osv import fields
from tools.translate import _

class mail_compose_message(osv.osv_memory):
    _inherit = 'mail.compose.message'

    def get_value(self, cr, uid, model, resource_id, context=None):
        '''
        To get values of the resource_id for the model
        @param model: Object
        @param resource_id: id of a record for which values to be read

        @return: Returns a dictionary
        '''
        if context is None:
            context = {}
        result = super(mail_compose_message, self).get_value(cr, uid,  model, resource_id, context=context)
        if model == 'project.scrum.meeting' and resource_id:
            meeting_pool = self.pool.get('project.scrum.meeting')
            user_pool = self.pool.get('res.users')
            meeting = meeting_pool.browse(cr, uid, resource_id, context=context)

            sprint = meeting.sprint_id
            user_data = user_pool.browse(cr, uid, uid, context=context)
            result.update({'email_from': user_data.address_id and user_data.address_id.email or False})

            if sprint.scrum_master_id and sprint.scrum_master_id.user_email:
                result.update({'email_to': sprint.scrum_master_id.user_email})
            if sprint.product_owner_id and sprint.product_owner_id.user_email:
                result.update({'email_to': result.get('email_to',False) and result.get('email_to') + ',' +  sprint.product_owner_id.user_email or sprint.product_owner_id.user_email})

            subject = _("Scrum Meeting : %s") %(meeting.date)
            message = _("Hello  , \nI am sending you Scrum Meeting : %s for the Sprint  '%s' of Project '%s'") %(meeting.date, sprint.name, sprint.project_id.name)
            result.update({
                       'subject': subject,
                       'body_text': message,
                       'model': model,
                       'res_id': resource_id
                    })
        return result

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[FIX] Fixed the issue of giving error when click on send mail button<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>
#
##############################################################################

from osv import osv
from osv import fields
from tools.translate import _

class mail_compose_message(osv.osv_memory):
    _inherit = 'mail.compose.message'

    def get_value(self, cr, uid, model, resource_id, context=None):
        '''
        To get values of the resource_id for the model
        @param model: Object
        @param resource_id: id of a record for which values to be read

        @return: Returns a dictionary
        '''
        if context is None:
            context = {}
        result = super(mail_compose_message, self).get_value(cr, uid,  model, resource_id, context=context)
        if model == 'project.scrum.meeting' and resource_id:
            meeting_pool = self.pool.get('project.scrum.meeting')
            user_pool = self.pool.get('res.users')
            meeting = meeting_pool.browse(cr, uid, resource_id, context=context)

            sprint = meeting.sprint_id
            user_data = user_pool.browse(cr, uid, uid, context=context)
            result.update({'email_from': user_data.user_email or False})

            if sprint.scrum_master_id and sprint.scrum_master_id.user_email:
                result.update({'email_to': sprint.scrum_master_id.user_email})
            if sprint.product_owner_id and sprint.product_owner_id.user_email:
                result.update({'email_to': result.get('email_to',False) and result.get('email_to') + ',' +  sprint.product_owner_id.user_email or sprint.product_owner_id.user_email})

            subject = _("Scrum Meeting : %s") %(meeting.date)
            message = _("Hello  , \nI am sending you Scrum Meeting : %s for the Sprint  '%s' of Project '%s'") %(meeting.date, sprint.name, sprint.project_id.name)
            result.update({
                       'subject': subject,
                       'body_text': message,
                       'model': model,
                       'res_id': resource_id
                    })
        return result

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before>__version__ = '0.1.6'
<commit_msg>update version for pip<commit_after>__version__ = '0.1.7'
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""Parse command line and call the appropriate functions.

..todo:: Sanity check all input.  Be sure to avoid shell code ect...

"""
import argparse
import logging
import os
import sys

import zope.component
import zope.interface

from letsencrypt.client import CONFIG
from letsencrypt.client import client
from letsencrypt.client import display
from letsencrypt.client import errors
from letsencrypt.client import interfaces
from letsencrypt.client import log

def main():  # pylint: disable=too-many-statements,too-many-branches
    """Command line argument parsing and main script execution."""
    parser = argparse.ArgumentParser(
        description="An ACME client that can update Apache configurations.")

    parser.add_argument("-d", "--domains", dest="domains", metavar="DOMAIN",
                        nargs="+")
    parser.add_argument("-s", "--server", dest="server",
                        default=CONFIG.ACME_SERVER,
                        help="The ACME CA server. [%(default)s]")
    parser.add_argument("-p", "--privkey", dest="privkey", type=read_file,
                        help="Path to the private key file for certificate "
                             "generation.")
    parser.add_argument("-b", "--rollback", dest="rollback", type=int,
                        default=0, metavar="N",
                        help="Revert configuration N number of checkpoints.")
    parser.add_argument("-B", "--keysize", dest="key_size", type=int,
                        default=CONFIG.RSA_KEY_SIZE, metavar="N",
                        help="RSA key shall be sized N bits. [%(default)d]")
    parser.add_argument("-k", "--revoke", dest="revoke", action="store_true",
                        help="Revoke a certificate.")
    parser.add_argument("-v", "--view-config-changes",
                        dest="view_config_changes",
                        action="store_true",
                        help="View checkpoints and associated configuration "
                             "changes.")
    parser.add_argument("-r", "--redirect", dest="redirect",
                        action="store_const", const=True,
                        help="Automatically redirect all HTTP traffic to HTTPS "
                             "for the newly authenticated vhost.")
    parser.add_argument("-n", "--no-redirect", dest="redirect",
                        action="store_const", const=False,
                        help="Skip the HTTPS redirect question, allowing both "
                             "HTTP and HTTPS.")
    parser.add_argument("-e", "--agree-tos", dest="eula", action="store_true",
                        help="Skip the end user license agreement screen.")
    parser.add_argument("-t", "--text", dest="use_curses", action="store_false",
                        help="Use the text output instead of the curses UI.")
    parser.add_argument("--test", dest="test", action="store_true",
                        help="Run in test mode.")

    # note: arg parser internally handles --help (and exits afterwards)
    args = parser.parse_args()

    # note: check is done after arg parsing as --help should work w/o root also.
    if not os.geteuid() == 0:
        sys.exit(
            "{0}Root is required to run letsencrypt.  Please use sudo.{0}"
            .format(os.linesep))

    # Set up logging
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    if args.use_curses:
        logger.addHandler(log.DialogHandler())
        displayer = display.NcursesDisplay()
    else:
        displayer = display.FileDisplay(sys.stdout)
    zope.component.provideUtility(displayer)

    if args.view_config_changes:
        client.view_config_changes()
        sys.exit()

    if args.revoke:
        client.revoke(args.server)
        sys.exit()

    if args.rollback > 0:
        client.rollback(args.rollback)
        sys.exit()

    if not args.eula:
        display_eula()

    # Make sure we actually get an installer that is functioning properly
    # before we begin to try to use it.
    try:
        installer = client.determine_installer()
    except errors.LetsEncryptMisconfigurationError as err:
        logging.fatal("Please fix your configuration before proceeding.  "
                      "The Installer exited with the following message: "
                      "%s", err)
        sys.exit(1)

    # Use the same object if possible
    if interfaces.IAuthenticator.providedBy(installer):  # pylint: disable=no-member
        auth = installer
    else:
        auth = client.determine_authenticator()

    domains = choose_names(installer) if args.domains is None else args.domains

    # Prepare for init of Client
    if args.privkey is None:
        privkey = client.init_key(args.key_size)
    else:
        privkey = client.Client.Key(args.privkey[0], args.privkey[1])

    acme = client.Client(args.server, privkey, auth, installer)

    # Validate the key and csr
    client.validate_key_csr(privkey)

    # This more closely mimics the capabilities of the CLI
    # It should be possible for reconfig only, install-only, no-install
    # I am not sure the best way to handle all of the unimplemented abilities,
    # but this code should be safe on all environments.
    if auth is not None:
        cert_file, chain_file = acme.obtain_certificate(domains)
    if installer is not None and cert_file is not None:
        acme.deploy_certificate(domains, privkey, cert_file, chain_file)
    if installer is not None:
        acme.enhance_config(domains, args.redirect)

def display_eula():
    """Displays the end user agreement."""
    with open('EULA') as eula_file:
        if not zope.component.getUtility(interfaces.IDisplay).generic_yesno(
                eula_file.read(), "Agree", "Cancel"):
            sys.exit(0)

def choose_names(installer):
    """Display screen to select domains to validate.

    :param installer: An installer object
    :type installer: :class:`letsencrypt.client.interfaces.IInstaller`

    """
    # This function adds all names found in the installer configuration
    # Then filters them based on user selection
    code, names = zope.component.getUtility(
        interfaces.IDisplay).filter_names(get_all_names(installer))
    if code == display.OK and names:
        return names
    else:
        sys.exit(0)

def get_all_names(installer):
    """Return all valid names in the configuration.

    :param installer: An installer object
    :type installer: :class:`letsencrypt.client.interfaces.IInstaller`

    """
    names = list(installer.get_all_names())

    if not names:
        logging.fatal("No domain names were found in your installation")
        logging.fatal("Either specify which names you would like "
                      "letsencrypt to validate or add server names "
                      "to your virtual hosts")
        sys.exit(1)

    return names

def read_file(filename):
    """Returns the given file's contents with universal new line support.

    :param str filename: Filename

    :returns: A tuple of filename and its contents
    :rtype: tuple

    :raises argparse.ArgumentTypeError: File does not exist or is not readable.

    """
    try:
        return filename, open(filename, 'rU').read()
    except IOError as exc:
        raise argparse.ArgumentTypeError(exc.strerror)

if __name__ == "__main__":
    main()
<commit_msg>fix comment spelling<commit_after>#!/usr/bin/env python
"""Parse command line and call the appropriate functions.

..todo:: Sanity check all input.  Be sure to avoid shell code etc...

"""
import argparse
import logging
import os
import sys

import zope.component
import zope.interface

from letsencrypt.client import CONFIG
from letsencrypt.client import client
from letsencrypt.client import display
from letsencrypt.client import errors
from letsencrypt.client import interfaces
from letsencrypt.client import log

def main():  # pylint: disable=too-many-statements,too-many-branches
    """Command line argument parsing and main script execution."""
    parser = argparse.ArgumentParser(
        description="An ACME client that can update Apache configurations.")

    parser.add_argument("-d", "--domains", dest="domains", metavar="DOMAIN",
                        nargs="+")
    parser.add_argument("-s", "--server", dest="server",
                        default=CONFIG.ACME_SERVER,
                        help="The ACME CA server. [%(default)s]")
    parser.add_argument("-p", "--privkey", dest="privkey", type=read_file,
                        help="Path to the private key file for certificate "
                             "generation.")
    parser.add_argument("-b", "--rollback", dest="rollback", type=int,
                        default=0, metavar="N",
                        help="Revert configuration N number of checkpoints.")
    parser.add_argument("-B", "--keysize", dest="key_size", type=int,
                        default=CONFIG.RSA_KEY_SIZE, metavar="N",
                        help="RSA key shall be sized N bits. [%(default)d]")
    parser.add_argument("-k", "--revoke", dest="revoke", action="store_true",
                        help="Revoke a certificate.")
    parser.add_argument("-v", "--view-config-changes",
                        dest="view_config_changes",
                        action="store_true",
                        help="View checkpoints and associated configuration "
                             "changes.")
    parser.add_argument("-r", "--redirect", dest="redirect",
                        action="store_const", const=True,
                        help="Automatically redirect all HTTP traffic to HTTPS "
                             "for the newly authenticated vhost.")
    parser.add_argument("-n", "--no-redirect", dest="redirect",
                        action="store_const", const=False,
                        help="Skip the HTTPS redirect question, allowing both "
                             "HTTP and HTTPS.")
    parser.add_argument("-e", "--agree-tos", dest="eula", action="store_true",
                        help="Skip the end user license agreement screen.")
    parser.add_argument("-t", "--text", dest="use_curses", action="store_false",
                        help="Use the text output instead of the curses UI.")
    parser.add_argument("--test", dest="test", action="store_true",
                        help="Run in test mode.")

    # note: arg parser internally handles --help (and exits afterwards)
    args = parser.parse_args()

    # note: check is done after arg parsing as --help should work w/o root also.
    if not os.geteuid() == 0:
        sys.exit(
            "{0}Root is required to run letsencrypt.  Please use sudo.{0}"
            .format(os.linesep))

    # Set up logging
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    if args.use_curses:
        logger.addHandler(log.DialogHandler())
        displayer = display.NcursesDisplay()
    else:
        displayer = display.FileDisplay(sys.stdout)
    zope.component.provideUtility(displayer)

    if args.view_config_changes:
        client.view_config_changes()
        sys.exit()

    if args.revoke:
        client.revoke(args.server)
        sys.exit()

    if args.rollback > 0:
        client.rollback(args.rollback)
        sys.exit()

    if not args.eula:
        display_eula()

    # Make sure we actually get an installer that is functioning properly
    # before we begin to try to use it.
    try:
        installer = client.determine_installer()
    except errors.LetsEncryptMisconfigurationError as err:
        logging.fatal("Please fix your configuration before proceeding.  "
                      "The Installer exited with the following message: "
                      "%s", err)
        sys.exit(1)

    # Use the same object if possible
    if interfaces.IAuthenticator.providedBy(installer):  # pylint: disable=no-member
        auth = installer
    else:
        auth = client.determine_authenticator()

    domains = choose_names(installer) if args.domains is None else args.domains

    # Prepare for init of Client
    if args.privkey is None:
        privkey = client.init_key(args.key_size)
    else:
        privkey = client.Client.Key(args.privkey[0], args.privkey[1])

    acme = client.Client(args.server, privkey, auth, installer)

    # Validate the key and csr
    client.validate_key_csr(privkey)

    # This more closely mimics the capabilities of the CLI
    # It should be possible for reconfig only, install-only, no-install
    # I am not sure the best way to handle all of the unimplemented abilities,
    # but this code should be safe on all environments.
    if auth is not None:
        cert_file, chain_file = acme.obtain_certificate(domains)
    if installer is not None and cert_file is not None:
        acme.deploy_certificate(domains, privkey, cert_file, chain_file)
    if installer is not None:
        acme.enhance_config(domains, args.redirect)

def display_eula():
    """Displays the end user agreement."""
    with open('EULA') as eula_file:
        if not zope.component.getUtility(interfaces.IDisplay).generic_yesno(
                eula_file.read(), "Agree", "Cancel"):
            sys.exit(0)

def choose_names(installer):
    """Display screen to select domains to validate.

    :param installer: An installer object
    :type installer: :class:`letsencrypt.client.interfaces.IInstaller`

    """
    # This function adds all names found in the installer configuration
    # Then filters them based on user selection
    code, names = zope.component.getUtility(
        interfaces.IDisplay).filter_names(get_all_names(installer))
    if code == display.OK and names:
        return names
    else:
        sys.exit(0)

def get_all_names(installer):
    """Return all valid names in the configuration.

    :param installer: An installer object
    :type installer: :class:`letsencrypt.client.interfaces.IInstaller`

    """
    names = list(installer.get_all_names())

    if not names:
        logging.fatal("No domain names were found in your installation")
        logging.fatal("Either specify which names you would like "
                      "letsencrypt to validate or add server names "
                      "to your virtual hosts")
        sys.exit(1)

    return names

def read_file(filename):
    """Returns the given file's contents with universal new line support.

    :param str filename: Filename

    :returns: A tuple of filename and its contents
    :rtype: tuple

    :raises argparse.ArgumentTypeError: File does not exist or is not readable.

    """
    try:
        return filename, open(filename, 'rU').read()
    except IOError as exc:
        raise argparse.ArgumentTypeError(exc.strerror)

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


<commit_before># Copyright 2011,2012,2013 Colin Scott
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Implementation of an OpenFlow flow table
"""

from libopenflow_01 import *
from pox.lib.revent import *

import time

# FlowTable Entries:
#   match - ofp_match (13-tuple)
#   counters - hash from name -> count. May be stale
#   actions - ordered list of ofp_action_*s to apply for matching packets
class TableEntry (object):
  """
  Models a flow table entry, with a match, actions, and options/flags/counters.

  Note: The current time can either be specified explicitely with the optional
        'now' parameter or is taken from time.time()
  """
  def __init__ (self, priority=OFP_DEFAULT_PRIORITY, cookie=0, idle_timeout=0,
                hard_timeout=0, flags=0, match=ofp_match(), actions=[],
                buffer_id=None, now=None):
    """
    Initialize table entry
    """
    if now is None: now = time.time()
    self.counters = {
        'created': now,
        'last_touched': now,
        'bytes': 0,
        'packets': 0
    }
    self.priority = priority
    self.cookie = cookie
    self.idle_timeout = idle_timeout
    self.hard_timeout = hard_timeout
    self.flags = flags
    self.match = match
    self.actions = actions
    self.buffer_id = buffer_id

  @staticmethod
  def from_flow_mod (flow_mod):
    return TableEntry(priority=flow_mod.priority,
                      cookie=flow_mod.cookie,
                      idle_timeout=flow_mod.idle_timeout,
                      hard_timeout=flow_mod.hard_timeout,
                      flags=flow_mod.flags,
                      match=flow_mod.match,
                      actions=flow_mod.actions,
                      buffer_id=flow_mod.buffer_id)

  def to_flow_mod (self, flags=None, **kw):
    if flags is None: flags = self.flags
    return ofp_flow_mod(priority=self.priority,
                        cookie=self.cookie,
                        match=self.match,
                        idle_timeout=self.idle_timeout,
                        hard_timeout=self.hard_timeout,
                        actions=self.actions,
                        buffer_id=self.buffer_id,
                        flags=flags, **kw)

  def is_matched_by (self, match, priority=None, strict=False, out_port=None):
    """
    Tests whether a given match object matches this entry

    Used for, e.g., flow_mod updates
    """
    match_a = lambda a: isinstance(a, ofp_action_output) and a.port == out_port
    check_port = out_port is None or any(match_a(a) for a in self.actions)

    if strict:
      return self.match == match and self.priority == priority and check_port
    else:
      return match.matches_with_wildcards(self.match) and check_port

  def touch_packet (self, byte_count, now=None):
    """
    Updates information of this entry based on encountering a packet.

    Updates both the cumulative given byte counts of packets encountered and
    the expiration timer.
    """
    if now is None: now = time.time()
    self.counters["bytes"] += byte_count
    self.counters["packets"] += 1
    self.counters["last_touched"] = now

  def is_expired (self, now=None):
    """
    Tests whether this flow entry is expired due to its idle or hard timeout
    """
    if now is None: now = time.time()
    expired_hard = now - self.counters["created"] > self.hard_timeout
    expired_idle = now - self.counters["last_touched"] > self.idle_timeout
    return (self.hard_timeout > 0 and expired_hard
         or self.idle_timeout > 0 and expired_idle)

  def __str__ (self):
    return self.__class__.__name__ + "\n  " + self.show()

  def __repr__ (self):
    return "TableEntry(" + self.show() + ")"

  def show (self):
    outstr = ''
    outstr += "priority=%s, " % self.priority
    outstr += "cookie=%x, " % self.cookie
    outstr += "idle_timeout=%d, " % self.idle_timeout
    outstr += "hard_timeout=%d, " % self.hard_timeout
    outstr += "match=%s, " % self.match
    outstr += "actions=%s, " % repr(self.actions)
    outstr += "buffer_id=%s" % str(self.buffer_id)
    return outstr

  def flow_stats (self, now=None):
    if now is None: now = time.time()
    duration = now - self.counters["created"]
    return ofp_flow_stats(match=self.match,
                          duration_sec=int(duration),
                          duration_nsec=int(duration * 1e9),
                          priority=self.priority,
                          idle_timeout=self.idle_timeout,
                          hard_timeout=self.hard_timeout,
                          cookie=self.cookie,
                          packet_count=self.counters["packets"],
                          byte_count=self.counters["bytes"],
                          actions=self.actions)

class FlowTableModification (Event):
  def __init__ (self, added=[], removed=[]):
    Event.__init__(self)
    self.added = added
    self.removed = removed

class FlowTable (EventMixin):
  """
  General model of a flow table.

  Maintains an ordered list of flow entries, and finds matching entries for
  packets and other entries. Supports expiration of flows.
  """
  _eventMixin_events = set([FlowTableModification])

  def __init__ (self):
    EventMixin.__init__(self)
    # For now we represent the table as a multidimensional array.
    #
    # [ (cookie, match, counters, actions),
    #   (cookie, match, counters, actions),
    #    ...                        ]
    #
    # Implies O(N) lookup for now. TODO: fix
    self._table = []

  @property
  def entries (self):
    return self._table

  def __len__ (self):
    return len(self._table)

  def add_entry (self, entry):
    if not isinstance(entry, TableEntry):
      raise TypeError("Not an Entry type")
    self._table.append(entry)

    # keep table sorted by descending priority, with exact matches always first
    # note: python sort is stable
    key = lambda e: e.priority if e.match.is_wildcarded else (1<<16) + 1
    self._table.sort(key=key, reverse=True)

    self.raiseEvent(FlowTableModification(added=[entry]))

  def remove_entry (self, entry):
    if not isinstance(entry, TableEntry):
      raise TypeError("Not an Entry type")
    self._table.remove(entry)
    self.raiseEvent(FlowTableModification(removed=[entry]))

  def entries_for_port (self, port_no):
    entries = []
    for entry in self._table:
      actions = entry.actions
      if len(actions) > 0:
        last_action = actions[-1]
        if type(last_action) == ofp_action_output:
          outgoing_port = last_action.port#.port_no
          if outgoing_port == port_no:
            entries.append(entry)
    return entries

  def matching_entries (self, match, priority=0, strict=False, out_port=None):
    entry_match = lambda e: e.is_matched_by(match, priority, strict, out_port)
    return [ entry for entry in self._table if entry_match(entry) ]

  def flow_stats (self, match, out_port=None, now=None):
    mc_es = self.matching_entries(match=match, strict=False, out_port=out_port)
    return ( e.flow_stats() for e in mc_es )

  def expired_entries (self, now=None):
    return [ entry for entry in self._table if entry.is_expired(now) ]

  def _remove_specific_entries (self, remove_flows):
    #for entry in remove_flows:
    #  self._table.remove(entry)
    self._table = [entry for entry in self._table if entry not in remove_flows]
    self.raiseEvent(FlowTableModification(removed=remove_flows))

  def remove_expired_entries (self, now=None):
    remove_flows = self.expired_entries(now)
    self._remove_specific_entries(remove_flows)
    return remove_flows

  def remove_matching_entries (self, match, priority=0, strict=False):
    remove_flows = self.matching_entries(match, priority, strict)
    self._remove_specific_entries(remove_flows)
    return remove_flows

  def entry_for_packet (self, packet, in_port):
    """
    Finds the flow table entry that matches the given packet.

    Returns the highest priority flow table entry that matches the given packet
    on the given in_port, or None if no matching entry is found.
    """
    packet_match = ofp_match.from_packet(packet, in_port)

    for entry in self._table:
      if entry.match.matches_with_wildcards(packet_match,
                                            consider_other_wildcards=False):
        return entry

    return None

class SwitchFlowTable (FlowTable):
  """
  Models a flow table for our switch implementation.

  Handles the behavior in response to the OF messages send to the switch
  """

  def process_flow_mod (self, flow_mod):
    """
    Process a flow mod sent to the switch.

    Returns a tuple (added|modified|removed, [list of affected entries])
    """
    if flow_mod.flags & OFPFF_CHECK_OVERLAP:
      raise NotImplementedError("OFPFF_CHECK_OVERLAP checking not implemented")
    if flow_mod.out_port != OFPP_NONE and flow_mod.command == OFPFC_DELETE:
      raise NotImplementedError("flow_mod outport checking not implemented")

    command = flow_mod.command
    match = flow_mod.match
    priority = flow_mod.priority

    if command == OFPFC_ADD:
      # exactly matching entries have to be removed
      self.remove_matching_entries(match, priority=priority, strict=True)
      return ("added", self.add_entry(TableEntry.from_flow_mod(flow_mod)))
    elif command == OFPFC_MODIFY or command == OFPFC_MODIFY_STRICT:
      is_strict = (command == OFPFC_MODIFY_STRICT)
      modified = []
      for entry in self._table:
        # update the actions field in the matching flows
        if entry.is_matched_by(match, priority=priority, strict=is_strict):
          entry.actions = flow_mod.actions
          modified.append(entry)
      if len(modified) == 0:
        # if no matching entry is found, modify acts as add
        return ("added", self.add_entry(TableEntry.from_flow_mod(flow_mod)))
      else:
        return ("modified", modified)
    elif command == OFPFC_DELETE or command == OFPFC_DELETE_STRICT:
      is_strict = (command == OFPFC_DELETE_STRICT)
      return ("removed", self.remove_matching_entries(match, priority=priority, strict=is_strict))
    else:
      raise AttributeError("Command not yet implemented: %s" % command)
<commit_msg>flow_table: Remove counters dictionary<commit_after># Copyright 2011,2012,2013 Colin Scott
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Implementation of an OpenFlow flow table
"""

from libopenflow_01 import *
from pox.lib.revent import *

import time

# FlowTable Entries:
#   match - ofp_match (13-tuple)
#   counters - hash from name -> count. May be stale
#   actions - ordered list of ofp_action_*s to apply for matching packets
class TableEntry (object):
  """
  Models a flow table entry, with a match, actions, and options/flags/counters.

  Note: The current time can either be specified explicitely with the optional
        'now' parameter or is taken from time.time()
  """
  def __init__ (self, priority=OFP_DEFAULT_PRIORITY, cookie=0, idle_timeout=0,
                hard_timeout=0, flags=0, match=ofp_match(), actions=[],
                buffer_id=None, now=None):
    """
    Initialize table entry
    """
    if now is None: now = time.time()
    self.created = now
    self.last_touched = self.created
    self.byte_count = 0
    self.packet_count = 0
    self.priority = priority
    self.cookie = cookie
    self.idle_timeout = idle_timeout
    self.hard_timeout = hard_timeout
    self.flags = flags
    self.match = match
    self.actions = actions
    self.buffer_id = buffer_id

  @staticmethod
  def from_flow_mod (flow_mod):
    return TableEntry(priority=flow_mod.priority,
                      cookie=flow_mod.cookie,
                      idle_timeout=flow_mod.idle_timeout,
                      hard_timeout=flow_mod.hard_timeout,
                      flags=flow_mod.flags,
                      match=flow_mod.match,
                      actions=flow_mod.actions,
                      buffer_id=flow_mod.buffer_id)

  def to_flow_mod (self, flags=None, **kw):
    if flags is None: flags = self.flags
    return ofp_flow_mod(priority=self.priority,
                        cookie=self.cookie,
                        match=self.match,
                        idle_timeout=self.idle_timeout,
                        hard_timeout=self.hard_timeout,
                        actions=self.actions,
                        buffer_id=self.buffer_id,
                        flags=flags, **kw)

  def is_matched_by (self, match, priority=None, strict=False, out_port=None):
    """
    Tests whether a given match object matches this entry

    Used for, e.g., flow_mod updates
    """
    match_a = lambda a: isinstance(a, ofp_action_output) and a.port == out_port
    check_port = out_port is None or any(match_a(a) for a in self.actions)

    if strict:
      return self.match == match and self.priority == priority and check_port
    else:
      return match.matches_with_wildcards(self.match) and check_port

  def touch_packet (self, byte_count, now=None):
    """
    Updates information of this entry based on encountering a packet.

    Updates both the cumulative given byte counts of packets encountered and
    the expiration timer.
    """
    if now is None: now = time.time()
    self.byte_count += byte_count
    self.packet_count += 1
    self.last_touched = now

  def is_expired (self, now=None):
    """
    Tests whether this flow entry is expired due to its idle or hard timeout
    """
    if now is None: now = time.time()
    if self.hard_timeout > 0:
      if (now - self.created) > self.hard_timeout:
        return True
    if self.idle_timeout > 0:
      if (now - self.last_touched) > self.idle_timeout:
        return True
    return False

  def __str__ (self):
    return self.__class__.__name__ + "\n  " + self.show()

  def __repr__ (self):
    return "TableEntry(" + self.show() + ")"

  def show (self):
    outstr = ''
    outstr += "priority=%s, " % self.priority
    outstr += "cookie=%x, " % self.cookie
    outstr += "idle_timeout=%d, " % self.idle_timeout
    outstr += "hard_timeout=%d, " % self.hard_timeout
    outstr += "match=%s, " % self.match
    outstr += "actions=%s, " % repr(self.actions)
    outstr += "buffer_id=%s" % str(self.buffer_id)
    return outstr

  def flow_stats (self, now=None):
    if now is None: now = time.time()
    duration = now - self.created
    return ofp_flow_stats(match=self.match,
                          duration_sec=int(duration),
                          duration_nsec=int(duration * 1e9),
                          priority=self.priority,
                          idle_timeout=self.idle_timeout,
                          hard_timeout=self.hard_timeout,
                          cookie=self.cookie,
                          packet_count=self.packet_count,
                          byte_count=self.byte_count,
                          actions=self.actions)

class FlowTableModification (Event):
  def __init__ (self, added=[], removed=[]):
    Event.__init__(self)
    self.added = added
    self.removed = removed

class FlowTable (EventMixin):
  """
  General model of a flow table.

  Maintains an ordered list of flow entries, and finds matching entries for
  packets and other entries. Supports expiration of flows.
  """
  _eventMixin_events = set([FlowTableModification])

  def __init__ (self):
    EventMixin.__init__(self)
    # For now we represent the table as a multidimensional array.
    #
    # [ (cookie, match, counters, actions),
    #   (cookie, match, counters, actions),
    #    ...                        ]
    #
    # Implies O(N) lookup for now. TODO: fix
    self._table = []

  @property
  def entries (self):
    return self._table

  def __len__ (self):
    return len(self._table)

  def add_entry (self, entry):
    if not isinstance(entry, TableEntry):
      raise TypeError("Not an Entry type")
    self._table.append(entry)

    # keep table sorted by descending priority, with exact matches always first
    # note: python sort is stable
    key = lambda e: e.priority if e.match.is_wildcarded else (1<<16) + 1
    self._table.sort(key=key, reverse=True)

    self.raiseEvent(FlowTableModification(added=[entry]))

  def remove_entry (self, entry):
    if not isinstance(entry, TableEntry):
      raise TypeError("Not an Entry type")
    self._table.remove(entry)
    self.raiseEvent(FlowTableModification(removed=[entry]))

  def entries_for_port (self, port_no):
    entries = []
    for entry in self._table:
      actions = entry.actions
      if len(actions) > 0:
        last_action = actions[-1]
        if type(last_action) == ofp_action_output:
          outgoing_port = last_action.port#.port_no
          if outgoing_port == port_no:
            entries.append(entry)
    return entries

  def matching_entries (self, match, priority=0, strict=False, out_port=None):
    entry_match = lambda e: e.is_matched_by(match, priority, strict, out_port)
    return [ entry for entry in self._table if entry_match(entry) ]

  def flow_stats (self, match, out_port=None, now=None):
    mc_es = self.matching_entries(match=match, strict=False, out_port=out_port)
    return ( e.flow_stats() for e in mc_es )

  def expired_entries (self, now=None):
    return [ entry for entry in self._table if entry.is_expired(now) ]

  def _remove_specific_entries (self, remove_flows):
    #for entry in remove_flows:
    #  self._table.remove(entry)
    self._table = [entry for entry in self._table if entry not in remove_flows]
    self.raiseEvent(FlowTableModification(removed=remove_flows))

  def remove_expired_entries (self, now=None):
    remove_flows = self.expired_entries(now)
    self._remove_specific_entries(remove_flows)
    return remove_flows

  def remove_matching_entries (self, match, priority=0, strict=False):
    remove_flows = self.matching_entries(match, priority, strict)
    self._remove_specific_entries(remove_flows)
    return remove_flows

  def entry_for_packet (self, packet, in_port):
    """
    Finds the flow table entry that matches the given packet.

    Returns the highest priority flow table entry that matches the given packet
    on the given in_port, or None if no matching entry is found.
    """
    packet_match = ofp_match.from_packet(packet, in_port)

    for entry in self._table:
      if entry.match.matches_with_wildcards(packet_match,
                                            consider_other_wildcards=False):
        return entry

    return None

class SwitchFlowTable (FlowTable):
  """
  Models a flow table for our switch implementation.

  Handles the behavior in response to the OF messages send to the switch
  """

  def process_flow_mod (self, flow_mod):
    """
    Process a flow mod sent to the switch.

    Returns a tuple (added|modified|removed, [list of affected entries])
    """
    if flow_mod.flags & OFPFF_CHECK_OVERLAP:
      raise NotImplementedError("OFPFF_CHECK_OVERLAP checking not implemented")
    if flow_mod.out_port != OFPP_NONE and flow_mod.command == OFPFC_DELETE:
      raise NotImplementedError("flow_mod outport checking not implemented")

    command = flow_mod.command
    match = flow_mod.match
    priority = flow_mod.priority

    if command == OFPFC_ADD:
      # exactly matching entries have to be removed
      self.remove_matching_entries(match, priority=priority, strict=True)
      return ("added", self.add_entry(TableEntry.from_flow_mod(flow_mod)))
    elif command == OFPFC_MODIFY or command == OFPFC_MODIFY_STRICT:
      is_strict = (command == OFPFC_MODIFY_STRICT)
      modified = []
      for entry in self._table:
        # update the actions field in the matching flows
        if entry.is_matched_by(match, priority=priority, strict=is_strict):
          entry.actions = flow_mod.actions
          modified.append(entry)
      if len(modified) == 0:
        # if no matching entry is found, modify acts as add
        return ("added", self.add_entry(TableEntry.from_flow_mod(flow_mod)))
      else:
        return ("modified", modified)
    elif command == OFPFC_DELETE or command == OFPFC_DELETE_STRICT:
      is_strict = (command == OFPFC_DELETE_STRICT)
      return ("removed", self.remove_matching_entries(match, priority=priority, strict=is_strict))
    else:
      raise AttributeError("Command not yet implemented: %s" % command)
<|endoftext|>


<commit_before>#
# pymoku example: Phasemeter networking streaming
#
# This example provides a network stream of Phasemeter
# data samples from Channel 1 and Channel 2. These samples
# are output in the form (I,Q,F,phi,counter) for each channel.
#
# (c) 2016 Liquid Instruments Pty. Ltd.
#
from pymoku import Moku, NoDataException
from pymoku.instruments import *
import time, logging, math, numpy
import matplotlib.pyplot as plt

logging.basicConfig(format='%(asctime)s:%(name)s:%(levelname)s::%(message)s')
logging.getLogger('pymoku').setLevel(logging.DEBUG)

# Use Moku.get_by_serial() or get_by_name() if you don't know the IP
m = Moku.get_by_name('example')

i = m.discover_instrument()

if i is None or i.type != 'phasemeter':
	print("No or wrong instrument deployed")
	i = PhaseMeter()
	m.attach_instrument(i)
else:
	print("Attached to existing Phasemeter")

try:
	#################################
	# BEGIN Instrument Configuration
	# ------------------------------
	# Set these parameters
	#################################
	'''
		Which channels are ON?
	'''
	ch1 = True
	ch2 = True

	'''
		Initial channel scan frequencies
	'''
	ch1_freq = 10e6
	ch2_freq = 10e6

	'''
		Ouput sinewaves
	'''
	ch1_out_enable = True
	ch1_out_freq = 10e6
	ch1_out_amp = 1

	ch2_out_enable = True
	ch2_out_freq = 10e6
	ch2_out_amp = 1

	'''
		Log duration (sec)
	'''
	duration = 100
	#################################
	# END Instrument Configuration
	#################################

	# Set the initial phase-lock loop frequency for both channels
	i.set_initfreq(1, ch1_freq)
	i.set_initfreq(2, ch2_freq)

	# The sample rate must be set <=100Hz to avoid data loss so we set it to 10Hz
	i.set_samplerate(PM_LOGRATE_SLOW)

	# Set up signal generator for enabled channels
	if(ch1_out_enable):
		i.synth_sinewave(1, ch1_out_amp, ch1_out_freq)
		i.enable_output(1,ch1_out_enable)
	if(ch2_out_enable):
		i.synth_sinewave(2, ch2_out_amp, ch2_out_freq)
		i.enable_output(2,ch2_out_enable)

	# Atomically apply all instrument settings above
	i.commit()

	# Allow time for commit to flow down
	time.sleep(0.8)

	# Stop any existing data logging sessions and begin a new session
	# Logging session:
	# 		Start time - 0 sec
	#		Duration - 20 sec
	#		Channel 1 - ON, Channel 2 - ON
	#		Log file type - Network Stream
	i.datalogger_stop()
	i.datalogger_start(start=0, duration=duration, use_sd=True, ch1=ch1, ch2=ch2, filetype='net')

	# Set up basic plot configurations
	if ch1:
		ydata1 = [None] * 1024
		line1, = plt.plot(ydata1)
	if ch2:
		ydata2 = [None] * 1024
		line2, = plt.plot(ydata2)

	xdata = numpy.linspace(-1*(i.get_timestep()*1023), 0, 1024)

	plt.ion()
	plt.show()
	plt.grid(b=True)
	ax = plt.gca()
	ax.get_yaxis().get_major_formatter().set_useOffset(False)
	plt.xlim([-1*(i.get_timestep()*1023), 0])
	plt.ylabel('Amplitude (V)')
	plt.xlabel('Time (s)')

	while True:
		# Get samples
		try:
			ch, idx, samp = i.datalogger_get_samples(timeout=5)
		except NoDataException as e:
			print("Data stream complete")
			break
		print("Ch: %d, Idx: %d, #Samples: %s" % (ch, idx, len(samp)))

		# Process the retrieved samples
		if ch1 & (ch==1):
			datalen = len(samp)
			ydata1 = ydata1[(datalen-1):-1]
			for s in samp:
				# Process individual sample 's' here. Output format [I,Q,f,phase]
				#
				#

				# Convert I,Q to amplitude and append to line graph
				ydata1 = ydata1 + [math.sqrt(s[4]**2 + s[5]**2)]

		elif ch2 & (ch==2):
			datalen = len(samp)
			ydata2 = ydata2[(datalen-1):-1]
			for s in samp:
				# Process individual sample 's' here. Output format [I,Q,f,phase]
				#
				#

				# Convert I,Q to amplitude and append to line graph
				ydata2 = ydata2 + [math.sqrt(s[4]**2 + s[5]**2)]

		# Must set lines for each draw loop
		if ch1:
			line1.set_ydata(ydata1)
			line1.set_xdata(xdata)
		if ch2:
			line2.set_ydata(ydata2)
			line2.set_xdata(xdata)

		ax.relim()
		ax.autoscale_view()
		plt.draw()

	# Check if there were any errors
	e = i.datalogger_error()

	if e:
		print("Error occured: %s" % e)

	i.datalogger_stop()
except Exception as e:
	print(e)
finally:
	m.close()<commit_msg>Fixed minor bugs in basic_phasemeter example script<commit_after>#
# pymoku example: Phasemeter networking streaming
#
# This example provides a network stream of Phasemeter
# data samples from Channel 1 and Channel 2. These samples
# are output in the form (I,Q,F,phi,counter) for each channel.
#
# (c) 2016 Liquid Instruments Pty. Ltd.
#

# The phasemeter is a little more complex than some instruments as its native output
# is a stream of measurements, accessed through the datalogger; rather than a sequence
# of frames containing a range of data.  One can record this stream to a CSV or binary
# file, but this example streams the samples over the network so they can be accessed,
# processed and plotted in real time.

from pymoku import Moku, NoDataException
from pymoku.instruments import *
import time, logging, math, numpy
import matplotlib.pyplot as plt

logging.basicConfig(format='%(asctime)s:%(name)s:%(levelname)s::%(message)s')
logging.getLogger('pymoku').setLevel(logging.DEBUG)

# Use Moku.get_by_serial() or get_by_name() if you don't know the IP
m = Moku('192.168.XXX.XXX')
i = m.discover_instrument()

if i is None or i.type != 'phasemeter':
	print("No or wrong instrument deployed")
	i = PhaseMeter()
	m.attach_instrument(i)
else:
	print("Attached to existing Phasemeter")

try:
	#################################
	# BEGIN Instrument Configuration
	# ------------------------------
	# Set these parameters
	#################################

	# Which channels are ON?
	ch1 = True
	ch2 = True

	#Initial channel scan frequencies
	ch1_freq = 10e6
	ch2_freq = 10e6

	#Ouput sinewaves
	ch1_out_enable = True
	ch1_out_freq = 10e6
	ch1_out_amp = 1

	ch2_out_enable = True
	ch2_out_freq = 10e6
	ch2_out_amp = 1

	#Log duration (sec)
	duration = 20

	# Measurements to display on the plot
	plot_points = 500
	#################################
	# END Instrument Configuration
	#################################

	# Set the initial phase-lock loop frequency for both channels
	i.set_initfreq(1, ch1_freq)
	i.set_initfreq(2, ch2_freq)

	# The sample rate must be set <=100Hz to avoid data loss so we set it to 10Hz
	i.set_samplerate(PM_LOGRATE_SLOW)

	# Set up signal generator for enabled channels
	if(ch1_out_enable):
		i.synth_sinewave(1, ch1_out_amp, ch1_out_freq)
		i.enable_output(1,ch1_out_enable)
	if(ch2_out_enable):
		i.synth_sinewave(2, ch2_out_amp, ch2_out_freq)
		i.enable_output(2,ch2_out_enable)

	# Atomically apply all instrument settings above
	i.commit()

	# Allow time for commit to flow down
	time.sleep(0.8)

	# Stop any existing data logging sessions and begin a new session
	# Logging session:
	# 		Start time - 0 sec
	#		Duration - 20 sec
	#		Channel 1 - ON, Channel 2 - ON
	#		Log file type - Network Stream
	i.datalogger_stop()
	i.datalogger_start(start=0, duration=duration, use_sd=True, ch1=ch1, ch2=ch2, filetype='net')

	# Set up basic plot configurations
	if ch1:
		ydata1 = [None] * plot_points
		line1, = plt.plot(ydata1)
	if ch2:
		ydata2 = [None] * plot_points
		line2, = plt.plot(ydata2)

	xtent = -1 * (i.get_timestep() * (plot_points - 1))
	xdata = numpy.linspace(xtent, 0, plot_points)

	plt.ion()
	plt.show()
	plt.grid(b=True)
	ax = plt.gca()
	ax.get_yaxis().get_major_formatter().set_useOffset(False)
	plt.xlim([xtent, 0])
	plt.ylabel('Amplitude (V)')
	plt.xlabel('Time (s)')

	while True:
		# Get samples
		try:
			ch, idx, samp = i.datalogger_get_samples(timeout=5)
		except NoDataException as e:
			print("Data stream complete")
			break
		print("Ch: %d, Idx: %d, #Samples: %s" % (ch, idx, len(samp)))

		# Process the retrieved samples
		# Process individual sample 's' here. Output format [fs, f, count, phase, I, Q]
		# fs = setpoint frequency
		# f = measured frequency
		# Convert I,Q to amplitude and append to line graph
		if ch1 & (ch==1):
			for s in samp:
				ydata1 = ydata1 + [math.sqrt(s[4]**2 + s[5]**2)]

				# Extract phase data instead
				# ydata1 = ydata1 + [s[3]]
		elif ch2 & (ch==2):
			for s in samp:
				ydata2 = ydata2 + [math.sqrt(s[4]**2 + s[5]**2)]

				# Extract phase data instead
				# ydata2 = ydata2 + [s[3]]

		# Must set lines for each draw loop
		if ch1:
			ydata1 = ydata1[-plot_points:]
			line1.set_ydata(ydata1)
			line1.set_xdata(xdata)
		if ch2:
			ydata2 = ydata2[-plot_points:]
			line2.set_ydata(ydata2)
			line2.set_xdata(xdata)

		ax.relim()
		ax.autoscale_view()
		plt.pause(0.001)
		plt.draw()

	# Check if there were any errors
	e = i.datalogger_error()

	if e:
		print("Error occured: %s" % e)

	i.datalogger_stop()
except Exception as e:
	print(e)
finally:
	m.close()<|endoftext|>


<commit_before>import os
import sys
import argparse
import importlib
import ast
import logging
import subprocess
import numpy as np
from skimage import io

def get_sample_entries(search_dir, sample_confs, tomo_folder='tomo'):
    out = []

    for root, dirs, files in os.walk(search_dir):
        comps = root.split(os.sep)
        for sample_name, axis in sample_confs.iteritems():
            if tomo_folder in os.path.basename(root) and sample_name in comps:
               out.append({'name': sample_name, 'path': root, 'axis': axis})

    return out

def run_tofu(sample_entries, \
             proj_folder='proj360', \
             num_axes=40, \
             tomo=True, \
             slices_per_device=None, \
             overall_angle=None, \
             roll_angle=None, \
             lamino_angle=None, \
             z_param=None, \
             param_region=None, \
             y_pos=None, \
             reco_height=1, \
             output_folder='slices', \
             output_axis_folder='slices_axis'):

    def run_process(cmd_template, args, working_path):
        app = cmd_template.format(**args)
        print app
        process = subprocess.Popen(app, shell=True, cwd=working_path)
        streamdata = process.communicate()[0]
        #print app

    for i, sample_entry in enumerate(sample_entries):
        path = sample_entry['path']
        sample_name = sample_entry['name']

        proj_path = os.path.join(path, proj_folder)
        projs = [f for f in os.listdir(proj_path) \
                 if os.path.isfile(os.path.join(proj_path, f))]

        data = io.imread(os.path.join(proj_path, projs[0]))
        height, width = data.shape
        hc,wc = int(height/2), int(width/2)

        axis_is_container, axis_is_number = \
                isinstance(sample_entry['axis'], tuple) or \
                isinstance(sample_entry['axis'], list), \
                isinstance(sample_entry['axis'], int) or \
                isinstance(sample_entry['axis'], float)

        if axis_is_container:
            wc = sample_entry['axis'][0]
        elif axis_is_number:
            wc = sample_entry['axis']
        else:
            raise ValueError('The axis has incorrect type.')

        rot_axes = None
        if num_axes:
            rot_axes = range(wc-num_axes, wc+num_axes+1)

        if y_pos is None:
            y_pos = hc

        num_proj = len(projs) - 1
        args_fmt = {'projFolder': proj_folder, \
                    'angleRad': 2 * np.pi / float(num_proj), \
                    'projNum': num_proj}

        cmd_template = None

        if tomo:
            args_fmt['recoHeight'] = reco_height
            args_fmt['yPos'] = y_pos

            cmd_template = 'tofu tomo ' \
            '--fix-nan-and-inf ' \
            '--absorptivity ' \
            '--darks dark/ ' \
            '--flats flat/ ' \
            '--projections {projFolder}/ ' \
            '--angle {angleRad} ' \
            '--axis {axisPos} ' \
            '--method fbp ' \
            '--y {yPos} ' \
            '--height {recoHeight} ' \
            '--number {projNum}'
        else:
            args_fmt['slicesPerDevice'] = slices_per_device
            args_fmt['overallAngle'] = overall_angle
            args_fmt['rollAngle'] = roll_angle
            args_fmt['laminoAngle'] = lamino_angle
            args_fmt['zParam'] = z_param
            args_fmt['paramRegion'] = param_region

            if axis_is_container:
                args_fmt['yPos'] = sample_entry['axis'][1]
            else:
                args_fmt['yPos'] = hc

            cmd_template = 'tofu lamino ' \
            '--fix-nan-and-inf ' \
            '--absorptivity ' \
            '--darks dark/ ' \
            '--flats flat/ ' \
            '--projections {projFolder}/ ' \
            '--angle {angleRad} ' \
            '--lamino-angle {laminoAngle} ' \
            '--roll-angle {rollAngle} ' \
            '--overall-angle {overallAngle} ' \
            '--slices-per-device {slicesPerDevice} ' \
            '--z-parameter {zParam} ' \
            '--region="{paramRegion}" ' \
            '--number {projNum} ' \
            '--verbose'

            if axis_is_container:
                cmd_template += ' --axis "{axisPos},{yPos}"'
            elif axis_is_number:
                cmd_template += ' --axis "{axisPos},{yPos}"'
            else:
                raise ValueError('The axis has incorrect value.')

        if num_axes:
            cmd_template += ' --output {outAxisSlicesFolder}/slice-{axisPos}-%05i.tif' \
                                if tomo else \
                                    ' --output {outAxisSlicesFolder}/slice-{axisPos}'
        else:
            cmd_template += ' --output {outSlicesFolder}/slice-%05i.tif' \
                                if tomo else \
                                    ' --output {outSlicesFolder}/slice'

        args_fmt['outSlicesFolder'] = output_folder
        args_fmt['outAxisSlicesFolder'] = output_axis_folder

        if rot_axes is not None:
            for rot_axis in rot_axes:
                args_fmt['axisPos'] = rot_axis

                run_process(cmd_template, args_fmt, path)

                print '{0} [Axis: {1}]'.format(sample_name, rot_axis)
        else:
            args_fmt['axisPos'] = wc
            run_process(cmd_template, args_fmt, path)

def start_reconstruction(search_dir, \
                         sample_confs, \
                         num_axes, \
                         tomo=True, \
                         slices_per_device=None, \
                         overall_angle=None, \
                         roll_angle=None, \
                         lamino_angle=None, \
                         z_param=None, \
                         param_region=None, \
                         y_pos=None, \
                         reco_height=1, \
                         output_folder='slices', \
                         output_axis_folder='slices_axis'):

    sample_entries = get_sample_entries(search_dir, sample_confs)

    run_tofu(sample_entries, \
             num_axes=num_axes, \
             tomo=tomo, \
             slices_per_device=slices_per_device, \
             overall_angle=overall_angle, \
             roll_angle=roll_angle, \
             lamino_angle=lamino_angle, \
             z_param=z_param, \
             param_region=param_region, \
             y_pos=y_pos, \
             reco_height=reco_height, \
             output_folder=output_folder, \
             output_axis_folder=output_axis_folder)

#http://stackoverflow.com/questions/2859674/converting-python-list-of-strings-to-their-type
def _tryeval(val):
    try:
        val = ast.literal_eval(val)
    except ValueError:
        pass
    return val

def _list_type(string):
    lst = string.replace('[','')
    lst = lst.replace(']','')
    lst = lst.split(',')
    lst = [k.replace("'", "").replace('"', '').replace(" ", "") for k in lst]
    lst = [_tryeval(l) for l in lst]
    return lst

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--search_dir", \
                        help="Path to the folder containing the splitted data of samples", \
                        type=str, \
                        required=True)
    parser.add_argument("--sample-configs", \
                        help="List of sample entries as dictionaries {name: axis_x,axis_y} or {name: axis_x} to process", \
                        type=_tryeval, \
                        required=True)
    parser.add_argument("--lamino", \
                        help="The imaging setup is laminography", \
                        dest='tomo', \
                        action='store_false')
    parser.add_argument("--num_axes", \
                        help="The number of axes to calculate", \
                        type=int, \
                        default=40)
    parser.add_argument("--slices-per-device", \
                        help="The number of slices per device", \
                        type=int, \
                        default=10)
    parser.add_argument("--lamino-angle", \
                        help="The laminography angle", \
                        type=float, \
                        default=59.653557)
    parser.add_argument("--overall-angle", \
                        help=" The total angle over which projections were taken in degrees", \
                        type=int, \
                        default=-360)
    parser.add_argument("--roll-angle", \
                        help="The phi-misalignment angle", \
                        type=float, \
                        default=0.617746)
    parser.add_argument("--z-parameter", \
                        help="Z-axis parameter", \
                        type=str, \
                        default='z')
    parser.add_argument("--region", \
                        help="Z-axis parameter region as from,to,step", \
                        type=str, \
                        default='0,1,1')
    parser.add_argument("--y", \
                        help="The y-position in reconstructed volume", \
                        type=int, \
                        default=None)
    parser.add_argument("--height", \
                        help="The height of reconstructed volume", \
                        type=int, \
                        default=None)
    parser.add_argument("--output-folder", \
                        help="The name of the output folder of the reconstruction", \
                        type=str, \
                        default='slices')
    parser.add_argument("--output-axis-folder", \
                        help="The name of the output folder of slices of found rotation axes", \
                        type=str, \
                        default='slices_axis')

    args = parser.parse_args()

    start_reconstruction(args.search_dir, \
                         args.sample_configs, \
                         args.num_axes, \
                         tomo=args.tomo, \
                         slices_per_device=args.slices_per_device, \
                         overall_angle=args.overall_angle, \
                         roll_angle=args.roll_angle, \
                         lamino_angle=args.lamino_angle, \
                         z_param=args.z_parameter, \
                         param_region=args.region, \
                         y_pos=args.y, \
                         reco_height=args.height, \
                         output_folder=args.output_folder, \
                         output_axis_folder=args.output_axis_folder)

if __name__ == "__main__":
    sys.exit(main())
<commit_msg>Add capability to turn off absorptivity correction<commit_after>import os
import sys
import argparse
import importlib
import ast
import logging
import subprocess
import numpy as np
from skimage import io

def get_sample_entries(search_dir, sample_confs, tomo_folder='tomo'):
    out = []

    for root, dirs, files in os.walk(search_dir):
        comps = root.split(os.sep)
        for sample_name, axis in sample_confs.iteritems():
            if tomo_folder in os.path.basename(root) and sample_name in comps:
               out.append({'name': sample_name, 'path': root, 'axis': axis})

    return out

def run_tofu(sample_entries, \
             proj_folder='proj360', \
             num_axes=40, \
             tomo=True, \
             slices_per_device=None, \
             overall_angle=None, \
             roll_angle=None, \
             lamino_angle=None, \
             z_param=None, \
             param_region=None, \
             y_pos=None, \
             reco_height=1, \
             output_folder='slices', \
             output_axis_folder='slices_axis', \
             correction=True):

    def run_process(cmd_template, args, working_path):
        app = cmd_template.format(**args)
        print app
        process = subprocess.Popen(app, shell=True, cwd=working_path)
        streamdata = process.communicate()[0]
        #print app

    for i, sample_entry in enumerate(sample_entries):
        path = sample_entry['path']
        sample_name = sample_entry['name']

        proj_path = os.path.join(path, proj_folder)
        projs = [f for f in os.listdir(proj_path) \
                 if os.path.isfile(os.path.join(proj_path, f))]

        data = io.imread(os.path.join(proj_path, projs[0]))
        height, width = data.shape
        hc,wc = int(height/2), int(width/2)

        axis_is_container, axis_is_number = \
                isinstance(sample_entry['axis'], tuple) or \
                isinstance(sample_entry['axis'], list), \
                isinstance(sample_entry['axis'], int) or \
                isinstance(sample_entry['axis'], float)

        if axis_is_container:
            wc = sample_entry['axis'][0]
        elif axis_is_number:
            wc = sample_entry['axis']
        else:
            raise ValueError('The axis has incorrect type.')

        rot_axes = None
        if num_axes:
            rot_axes = range(wc-num_axes, wc+num_axes+1)

        if y_pos is None:
            y_pos = hc

        num_proj = len(projs) - 1
        args_fmt = {'projFolder': proj_folder, \
                    'angleRad': 2 * np.pi / float(num_proj), \
                    'projNum': num_proj}

        cmd_template = None

        if tomo:
            args_fmt['recoHeight'] = reco_height
            args_fmt['yPos'] = y_pos

            cmd_template = 'tofu tomo ' \
            '--fix-nan-and-inf ' \
            '--projections {projFolder}/ ' \
            '--angle {angleRad} ' \
            '--axis {axisPos} ' \
            '--method fbp ' \
            '--y {yPos} ' \
            '--height {recoHeight} ' \
            '--number {projNum} ' \
            '--verbose'
        else:
            args_fmt['slicesPerDevice'] = slices_per_device
            args_fmt['overallAngle'] = overall_angle
            args_fmt['rollAngle'] = roll_angle
            args_fmt['laminoAngle'] = lamino_angle
            args_fmt['zParam'] = z_param
            args_fmt['paramRegion'] = param_region

            if axis_is_container:
                args_fmt['yPos'] = sample_entry['axis'][1]
            else:
                args_fmt['yPos'] = hc

            cmd_template = 'tofu lamino ' \
            '--fix-nan-and-inf ' \
            '--projections {projFolder}/ ' \
            '--angle {angleRad} ' \
            '--lamino-angle {laminoAngle} ' \
            '--roll-angle {rollAngle} ' \
            '--overall-angle {overallAngle} ' \
            '--slices-per-device {slicesPerDevice} ' \
            '--z-parameter {zParam} ' \
            '--region="{paramRegion}" ' \
            '--number {projNum} ' \
            '--verbose'

            if axis_is_container:
                cmd_template += ' --axis "{axisPos},{yPos}"'
            elif axis_is_number:
                cmd_template += ' --axis "{axisPos},{yPos}"'
            else:
                raise ValueError('The axis has incorrect value.')

        if correction:
            cmd_template += ' --absorptivity --darks dark/ --flats flat/'

        if num_axes:
            cmd_template += ' --output {outAxisSlicesFolder}/slice-{axisPos}-%05i.tif' \
                                if tomo else \
                                    ' --output {outAxisSlicesFolder}/slice-{axisPos}'
        else:
            cmd_template += ' --output {outSlicesFolder}/slice-%05i.tif' \
                                if tomo else \
                                    ' --output {outSlicesFolder}/slice'

        args_fmt['outSlicesFolder'] = output_folder
        args_fmt['outAxisSlicesFolder'] = output_axis_folder

        if rot_axes is not None:
            for rot_axis in rot_axes:
                args_fmt['axisPos'] = rot_axis

                run_process(cmd_template, args_fmt, path)

                print '{0} [Axis: {1}]'.format(sample_name, rot_axis)
        else:
            args_fmt['axisPos'] = wc
            run_process(cmd_template, args_fmt, path)

def start_reconstruction(search_dir, \
                         sample_confs, \
                         num_axes, \
                         tomo=True, \
                         slices_per_device=None, \
                         overall_angle=None, \
                         roll_angle=None, \
                         lamino_angle=None, \
                         z_param=None, \
                         param_region=None, \
                         y_pos=None, \
                         reco_height=1, \
                         output_folder='slices', \
                         output_axis_folder='slices_axis', \
                         correction=True):

    sample_entries = get_sample_entries(search_dir, sample_confs)

    run_tofu(sample_entries, \
             num_axes=num_axes, \
             tomo=tomo, \
             slices_per_device=slices_per_device, \
             overall_angle=overall_angle, \
             roll_angle=roll_angle, \
             lamino_angle=lamino_angle, \
             z_param=z_param, \
             param_region=param_region, \
             y_pos=y_pos, \
             reco_height=reco_height, \
             output_folder=output_folder, \
             output_axis_folder=output_axis_folder, \
             correction=correction)

#http://stackoverflow.com/questions/2859674/converting-python-list-of-strings-to-their-type
def _tryeval(val):
    try:
        val = ast.literal_eval(val)
    except ValueError:
        pass
    return val

def _list_type(string):
    lst = string.replace('[','')
    lst = lst.replace(']','')
    lst = lst.split(',')
    lst = [k.replace("'", "").replace('"', '').replace(" ", "") for k in lst]
    lst = [_tryeval(l) for l in lst]
    return lst

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--search_dir", \
                        help="Path to the folder containing the splitted data of samples", \
                        type=str, \
                        required=True)
    parser.add_argument("--sample-configs", \
                        help="List of sample entries as dictionaries {name: axis_x,axis_y} or {name: axis_x} to process", \
                        type=_tryeval, \
                        required=True)
    parser.add_argument("--lamino", \
                        help="The imaging setup is laminography", \
                        dest='tomo', \
                        action='store_false')
    parser.add_argument("--no-absorptivity", \
                        help="Disable absorptivity correction", \
                        dest='correction', \
                        action='store_false')
    parser.add_argument("--num_axes", \
                        help="The number of axes to calculate", \
                        type=int, \
                        default=40)
    parser.add_argument("--slices-per-device", \
                        help="The number of slices per device", \
                        type=int, \
                        default=10)
    parser.add_argument("--lamino-angle", \
                        help="The laminography angle", \
                        type=float, \
                        default=59.653557)
    parser.add_argument("--overall-angle", \
                        help=" The total angle over which projections were taken in degrees", \
                        type=int, \
                        default=-360)
    parser.add_argument("--roll-angle", \
                        help="The phi-misalignment angle", \
                        type=float, \
                        default=0.617746)
    parser.add_argument("--z-parameter", \
                        help="Z-axis parameter", \
                        type=str, \
                        default='z')
    parser.add_argument("--region", \
                        help="Z-axis parameter region as from,to,step", \
                        type=str, \
                        default='0,1,1')
    parser.add_argument("--y", \
                        help="The y-position in reconstructed volume", \
                        type=int, \
                        default=None)
    parser.add_argument("--height", \
                        help="The height of reconstructed volume", \
                        type=int, \
                        default=None)
    parser.add_argument("--output-folder", \
                        help="The name of the output folder of the reconstruction", \
                        type=str, \
                        default='slices')
    parser.add_argument("--output-axis-folder", \
                        help="The name of the output folder of slices of found rotation axes", \
                        type=str, \
                        default='slices_axis')

    args = parser.parse_args()

    start_reconstruction(args.search_dir, \
                         args.sample_configs, \
                         args.num_axes, \
                         tomo=args.tomo, \
                         slices_per_device=args.slices_per_device, \
                         overall_angle=args.overall_angle, \
                         roll_angle=args.roll_angle, \
                         lamino_angle=args.lamino_angle, \
                         z_param=args.z_parameter, \
                         param_region=args.region, \
                         y_pos=args.y, \
                         reco_height=args.height, \
                         output_folder=args.output_folder, \
                         output_axis_folder=args.output_axis_folder, \
                         correction=args.correction)

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


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
from frappe.utils import getdate, date_diff

class AdditionalSalary(Document):
	def validate(self):
		self.validate_dates()
		if self.amount < 0:
			frappe.throw(_("Amount should not be less than zero."))

	def validate_dates(self):
 		date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
			["date_of_joining", "relieving_date"])
 		if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
 			frappe.throw(_("Payroll date can not be less than employee's joining date"))

	def get_amount(self, sal_start_date, sal_end_date):
		start_date = getdate(sal_start_date)
		end_date = getdate(sal_end_date)
		total_days = date_diff(getdate(self.to_date), getdate(self.from_date)) + 1
		amount_per_day = self.amount / total_days
		if getdate(sal_start_date) <= getdate(self.from_date):
			start_date = getdate(self.from_date)
		if getdate(sal_end_date) > getdate(self.to_date):
			end_date = getdate(self.to_date)
		no_of_days = date_diff(getdate(end_date), getdate(start_date)) + 1
		return amount_per_day * no_of_days

@frappe.whitelist()
def get_additional_salary_component(employee, start_date, end_date):
	additional_components = frappe.db.sql("""
		select salary_component, sum(amount) as amount, overwrite_salary_structure_amount from `tabAdditional Salary`
		where employee=%(employee)s
			and docstatus = 1
			and payroll_date between %(from_date)s and %(to_date)s
		group by salary_component, overwrite_salary_structure_amount
		order by salary_component, overwrite_salary_structure_amount
	""", {
		'employee': employee,
		'from_date': start_date,
		'to_date': end_date
	}, as_dict=1)

	additional_components_list = []
	for d in additional_components:
		component = frappe.get_doc("Salary Component", d.salary_component)
		struct_row = {'salary_component': d.salary_component}
		for field in ["depends_on_payment_days", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
			struct_row[field] = component.get(field)

		additional_components_list.append({
			'amount': d.amount,
			'type': component.type,
			'struct_row': struct_row,
			'overwrite': d.overwrite_salary_structure_amount
		})
	return additional_components_list<commit_msg>validate: if additional salary exists (#17529)<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
from frappe.utils import getdate, date_diff

class AdditionalSalary(Document):
	def before_insert(self):
		if frappe.db.exists("Additional Salary", {"employee": self.employee, "salary_component": self.salary_component,
			"amount": self.amount, "payroll_date": self.payroll_date, "company": self.company}):

			frappe.throw(_("Additional Salary Component Exists."))

	def validate(self):
		self.validate_dates()
		if self.amount < 0:
			frappe.throw(_("Amount should not be less than zero."))

	def validate_dates(self):
 		date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
			["date_of_joining", "relieving_date"])
 		if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
 			frappe.throw(_("Payroll date can not be less than employee's joining date"))

	def get_amount(self, sal_start_date, sal_end_date):
		start_date = getdate(sal_start_date)
		end_date = getdate(sal_end_date)
		total_days = date_diff(getdate(self.to_date), getdate(self.from_date)) + 1
		amount_per_day = self.amount / total_days
		if getdate(sal_start_date) <= getdate(self.from_date):
			start_date = getdate(self.from_date)
		if getdate(sal_end_date) > getdate(self.to_date):
			end_date = getdate(self.to_date)
		no_of_days = date_diff(getdate(end_date), getdate(start_date)) + 1
		return amount_per_day * no_of_days

@frappe.whitelist()
def get_additional_salary_component(employee, start_date, end_date):
	additional_components = frappe.db.sql("""
		select salary_component, sum(amount) as amount, overwrite_salary_structure_amount from `tabAdditional Salary`
		where employee=%(employee)s
			and docstatus = 1
			and payroll_date between %(from_date)s and %(to_date)s
		group by salary_component, overwrite_salary_structure_amount
		order by salary_component, overwrite_salary_structure_amount
	""", {
		'employee': employee,
		'from_date': start_date,
		'to_date': end_date
	}, as_dict=1)

	additional_components_list = []
	for d in additional_components:
		component = frappe.get_doc("Salary Component", d.salary_component)
		struct_row = {'salary_component': d.salary_component}
		for field in ["depends_on_payment_days", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
			struct_row[field] = component.get(field)

		additional_components_list.append({
			'amount': d.amount,
			'type': component.type,
			'struct_row': struct_row,
			'overwrite': d.overwrite_salary_structure_amount
		})
	return additional_components_list<|endoftext|>