<commit_before># -*- coding: utf-8 -*-
"""
Tools for sending sms
"""
from __future__ import unicode_literals

import re

import django
from distutils.version import StrictVersion

if StrictVersion(django.get_version()) > StringVersion("1.8"):
    from django.utils.module_loading import import_string
else:
    from django.utils.module_loading import import_by_path as import_string

from sms.message import SMSMessage
from sms.conf import settings as sms_settings
import sms
import logging
import json

logger = logging.getLogger('hwbuluo')

def get_connection(backend=None, fail_silently=False, **kwds):
    """Load an sms backend and return an instance of it.
    If backend is None (default) settings.SMS_BACKEND is used.
    Both fail_silently and other keyword arguments are used in the
    constructor of the backend.
    """
    klass = import_string(backend or sms_settings.SMS_BACKEND)
    return klass(fail_silently=fail_silently, **kwds)

def send_sms(tpl_id=None,
             content='',
             recipient_list=None,
             fail_silently=False,
             connection=None):
    """
    Easy wrapper for sending a single message to a recipient list. All members
    of the recipient list will see the other recipients in the 'To' field.
    """
    connection = connection or get_connection(fail_silently=fail_silently)

    return SMSMessage(tpl_id, content,
                      recipient_list,connection=connection).send()

MOBILE_RE = r'^(13[0-9]|15[012356789]|18[0-9]|14[57]|17[6-8])[0-9]{8}$'
MOBILE_RE_PATTERN = re.compile(MOBILE_RE)
def is_correct_mobile(mnumber):
    """
    http://www.jihaoba.com/tools/?com=haoduan
    http://blog.csdn.net/fengshi_sh/article/details/12085307
    移动：139 138 137 136 135 134 147 150 151 152 157 158 159 178 182
          183 184 187 188
    联通：130 131 132 155 156 185 186 145 176
    电信：133 153 177 180 181 189
    ^(0|86|17951)?(13[0-9]|15[012356789]|18[0-9]|14[57]|17[6-8])[0-9]{8}$
    """
    match = MOBILE_RE_PATTERN.match(mnumber)
    if match:
        return True
    else:
        return False

def simple_send_sms(tpl_id, phone_nos, content):
    """
    tpl_id 模版ＩＤ
    phone_nos 电话号码
    content 内容
    """
    if sms_settings.SMS_DEBUG:#本地local server测试时需要
        print 'send sms activiation %s' % content

    result = send_sms(tpl_id=tpl_id,
                      content=content,
                      recipient_list=phone_nos)
    # add log and add receive send error deal
    #http://www.yunpian.com/api/retcode.html
    response_msgs = result[1]
    for response_msg in response_msgs:
        res = json.loads(response_msg)
        code = res.get("code", None)
        msg = res.get("msg", '')
        if code is not None:
            if code == 0:
                logger.info("success send a msg")
            elif code > 0:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
            elif code <= -1 and code > -50:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
            elif code <= -50:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
        else:
            logger.error('Sms Response No code!')
    return response_msgs
<commit_msg>import_by_path change to import_string<commit_after># -*- coding: utf-8 -*-
"""
Tools for sending sms
"""
from __future__ import unicode_literals

import re

import django
from distutils.version import StrictVersion

if StrictVersion(django.get_version()) > StrictVersion("1.8"):
    from django.utils.module_loading import import_string
else:
    from django.utils.module_loading import import_by_path as import_string

from sms.message import SMSMessage
from sms.conf import settings as sms_settings
import sms
import logging
import json

logger = logging.getLogger('hwbuluo')

def get_connection(backend=None, fail_silently=False, **kwds):
    """Load an sms backend and return an instance of it.
    If backend is None (default) settings.SMS_BACKEND is used.
    Both fail_silently and other keyword arguments are used in the
    constructor of the backend.
    """
    klass = import_string(backend or sms_settings.SMS_BACKEND)
    return klass(fail_silently=fail_silently, **kwds)

def send_sms(tpl_id=None,
             content='',
             recipient_list=None,
             fail_silently=False,
             connection=None):
    """
    Easy wrapper for sending a single message to a recipient list. All members
    of the recipient list will see the other recipients in the 'To' field.
    """
    connection = connection or get_connection(fail_silently=fail_silently)

    return SMSMessage(tpl_id, content,
                      recipient_list,connection=connection).send()

MOBILE_RE = r'^(13[0-9]|15[012356789]|18[0-9]|14[57]|17[6-8])[0-9]{8}$'
MOBILE_RE_PATTERN = re.compile(MOBILE_RE)
def is_correct_mobile(mnumber):
    """
    http://www.jihaoba.com/tools/?com=haoduan
    http://blog.csdn.net/fengshi_sh/article/details/12085307
    移动：139 138 137 136 135 134 147 150 151 152 157 158 159 178 182
          183 184 187 188
    联通：130 131 132 155 156 185 186 145 176
    电信：133 153 177 180 181 189
    ^(0|86|17951)?(13[0-9]|15[012356789]|18[0-9]|14[57]|17[6-8])[0-9]{8}$
    """
    match = MOBILE_RE_PATTERN.match(mnumber)
    if match:
        return True
    else:
        return False

def simple_send_sms(tpl_id, phone_nos, content):
    """
    tpl_id 模版ＩＤ
    phone_nos 电话号码
    content 内容
    """
    if sms_settings.SMS_DEBUG:#本地local server测试时需要
        print 'send sms activiation %s' % content

    result = send_sms(tpl_id=tpl_id,
                      content=content,
                      recipient_list=phone_nos)
    # add log and add receive send error deal
    #http://www.yunpian.com/api/retcode.html
    response_msgs = result[1]
    for response_msg in response_msgs:
        res = json.loads(response_msg)
        code = res.get("code", None)
        msg = res.get("msg", '')
        if code is not None:
            if code == 0:
                logger.info("success send a msg")
            elif code > 0:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
            elif code <= -1 and code > -50:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
            elif code <= -50:
                detail = res.get("detail", '')
                rmsg = "send sms Error:调用API时发生错误，需要开发者进行相应的处理。#===code:%d msg:%s detail:%s===#" % (
                code, msg, detail)
                logger.error(rmsg)
        else:
            logger.error('Sms Response No code!')
    return response_msgs
<|endoftext|>


<commit_before>###############################################################################
#
# Copyright (c) 2008-2010 SIA "KN dati". (http://kndati.lv) All Rights Reserved.
#                    General contacts <info@kndati.lv>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
###############################################################################

import os
import sys
import logging
from tools.translate import _
from osv import fields, osv, expression
from report import report_sxw
from report.report_sxw import rml_parse
from datetime import datetime, timedelta

_logger = logging.getLogger(__name__)

dow = {0: "lun", 1: "mar", 2: "mer", 3: "gio", 4: "ven", 5: "sab", 6: "dom"}

class Parser(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context):
        ''' Parser init
        '''
        if context is None:
            context = {}
        super(Parser, self).__init__(cr, uid, name, context)
        self.localcontext.update({
            'get_calendar': self.get_calendar,
            'get_filter_description': self.get_filter_description,
            'week_day': self.week_day,
            })

    def week_day(self, day, data):
        ''' Return the day of a week for day passed in month and year of wizard
        '''
        try:
            pdate = datetime.strptime("%s-%s-%s" % (
                data.get('year',0), data.get('month',0), day), "%Y-%m-%d")
            is_festivity = "\nFES" if self.pool.get(
                'contract.employee.festivity').is_festivity(
                    self.cr, self.uid, pdate) else "" # festivity
            day_of_week = pdate.weekday()

            return "%s\n%s%s" % (day, dow[day_of_week], is_festivity)
        except:
            return "" # Error return always false (so no sunday)

    def get_filter_description(self, data):
        ''' Return string that describe wizard filter elements
            (from data passed)
        '''
        if not data:
            return "Nessun filtro"
        else:
            return 'Dipartimento: %s - Periodo: %s-%s' % (
                data.get('department_name', 'All'),
                data.get('month', '00'),
                data.get('year', '0000'),
                )

    def get_calendar(self, data=None):
        ''' Get calendar for user/mont/year passed
        '''
        if data is None:
            data = {}
        return self.pool.get('hr.analytic.timesheet').get_calendar(
            self.cr, self.uid, data)

class hr_analytic_timesheet(osv.osv):
    ''' Put utility function here for to be used alse from external
        > Wizard
        > Importation
    '''
    _inherit = 'hr.analytic.timesheet'

    # -------------------------------------------------------------------------
    #                             Utility:
    # -------------------------------------------------------------------------
    def get_employee_worked_hours(self, cr, uid, user_ids, from_date, to_date,
            worked, not_worked, not_worked_recover, context=None):
        ''' Search in analytic account line all employee_id.user_id that
            has worked hour for the period
            compile worked and not worked dict with:
                   {user_id: {day_of_month: worked}
                   {user_id: {day_of_month: not worked}
        '''
        res = {}

        # ---------------------------------------
        # only this user_id in the from-to period
        # ---------------------------------------
        line_ids = self.search(cr, uid, [
            ('user_id', 'in', user_ids),
            ('date', '>=', from_date.strftime("%Y-%m-%d")),
            ('date', '<=', to_date.strftime("%Y-%m-%d")),
            ])

        # -----------------------------------
        # loop all lines for totalize results
        # -----------------------------------
        for line in self.browse(cr, uid, line_ids):
            month_day = int(line.date[8:10])
            amount = line.unit_amount or 0.0

            # Type of hour:
            if line.account_id.is_recover:
                dict_ref = not_worked_recover # recover:
            elif line.account_id.not_working:
                dict_ref = not_worked # absence:
            else:
                dict_ref = worked # presence

            if line.user_id.id not in dict_ref:
                dict_ref[line.user_id.id] = {}
                dict_ref[line.user_id.id][month_day] = amount
            else:
                if month_day in dict_ref[line.user_id.id]:
                    dict_ref[line.user_id.id][month_day] += amount
                else:
                    dict_ref[line.user_id.id][month_day] = amount

            # total column:
            if 32 in dict_ref[line.user_id.id]:
                dict_ref[line.user_id.id][32] += amount
            else:
                dict_ref[line.user_id.id][32] = amount
            # TODO update total!!!! (worked and not worked)
        return

    def get_calendar(self, cr, uid, data=None, context=None):
        ''' Original function moved here from parser for calculate all database
            for report intervent
            NOTE: The function is moved here as we call also from importation
        '''
        # ---------------------------------------------------------------------
        #                          Utility function:
        # ---------------------------------------------------------------------
        def get_block(start_date, ref_month, day_of_month, employee_work,
                tot_hour_to_work, employee_worked_hours,
                employee_not_worked_hours, employee_not_worked_recover_hours):
            ''' start_date = datetime element for first day of calendar
                ref_month = actual month, used to test end of month during day
                    calc
                employee_work = dict with work hour per day (contract)
                tot_hour_to_work = list passed as totalizator of hour to work
                employee_worked_hours = dict with worked hours (intervent)
                employee_not_worked_hours = dict with not worked hours
                    (intervent with account absence)
                employee_not_worked_recover_hours = dict with not worked hours
                    for recover (intervent with account absence)

                Return: block for represent one day for one employee
                Setup default parameter as:
                [ work hour > calculated depending on employee_work
                  hour worked
                  hour festivity
                  status: FER = Festivity, WE= Week end, OK work + festivity >=
                      hour to work, KO if <
                ]
            '''

            res = [0.0, 0.0, 0.0, "", 0.0] # default value
            actual_date = start_date + timedelta(days = day_of_month - 1)
            wd = datetime.weekday(actual_date)

            if day_of_month == 32: # Total column:
                res[0] = tot_hour_to_work[0]
                # total worked hours
                res[1] = employee_worked_hours[
                    32] if 32 in employee_worked_hours else 0.0
                # total not worked hours
                res[2] = employee_not_worked_hours[
                    32] if 32 in employee_not_worked_hours else 0.0

                # total not worked recover hours
                res[4] = employee_not_worked_recover_hours[
                    32] if 32 in employee_not_worked_recover_hours else 0.0

                # worked - to work - recover (used)
                todo = res[1] - res[0] - res[4]

                # last column is 0 not "OK"
                res[3] = "%s\n%3.2f" % (
                    "recup." if todo >= 0 else "manca",
                    todo)

            elif actual_date.strftime("%m") == ref_month: # same month
                # test if is festivity day:
                if festivity_pool.is_festivity(
                        cr, uid, actual_date):
                    # festivity
                    res[0] = 0.0 # no work hours
                    res[3] = "\nFES"
                else:
                    # other day:
                    wh = employee_work[wd] if wd in employee_work else 0.0
                    res[0] = wh
                    tot_hour_to_work[0] += wh
                    #if wd in (5,6): # saturday and sunday:
                    #    res[3] = "\nW.E."

                # work and not work hours:
                if day_of_month in employee_worked_hours:
                    res[1] = employee_worked_hours[day_of_month]

                if day_of_month in employee_not_worked_hours:
                    res[2] = employee_not_worked_hours[day_of_month]

                if day_of_month in employee_not_worked_recover_hours:
                    res[4] = employee_not_worked_recover_hours[day_of_month]

                # -------
                # Status:
                # -------
                if not (res[0] or res[1] or res[2] or res[4]):
                    # all 0
                    res[3] = ""
                elif res[1] + res[2] + res[4] == res[0]:
                    # OK
                    res[3] = "="
                elif res[1] + res[2] + res[4] < res[0]:
                    # KO
                    res[3] = "<\nERR"
                elif res[1] + res[2] + res[4] - 10.0 > res[0]:
                    #ERR (too much extra hours)
                    res[3] = ">\nERR"
                elif res[1] + res[2] + res[4] - 4.0 > res[0]:
                    #WAR (much extra hours)
                    res[3] = ">\nWAR"
                elif res[1] + res[2] + res[4] > res[0]:
                    # OK > (extra hours)
                    res[3] = ">"
                else:
                    res[3] = "???"

            else: # new month
                res = ["", "", "", "", ""]
            return res[:]

        # ----------
        # Pool used:
        # ----------
        ts_pool = self.pool.get('hr.analytic.timesheet')
        employee_pool = self.pool.get('hr.employee')
        festivity_pool = self.pool.get('contract.employee.festivity')

        # Constant used:
        day_number = {
            'mo': 0, 'tu': 1, 'we': 2, 'th': 3, 'fr': 4, 'sa': 5, 'su': 6}

        # ---------------------------------------------------------------------
        #                         DATA PARAMETERS:
        # ---------------------------------------------------------------------
        if data is None:
           data = {}

        # Common parameters:
        # Get refer for data (else take actual month):
        ref_month = "%02d" % (
            int(data.get('month', datetime.now().strftime("%m"))))
        ref_year  = "%04d" % (
            int(data.get('year', datetime.now().strftime("%Y"))))

        # From wizard:
        department_id = data.get('department_id', False) # no from importation

        # From importation:
        importation_user_ids = data.get('user_ids', False)

        # ---------------
        # Variables used:
        # ---------------
        res_dict = {}

        start_date = datetime.strptime("%s-%s-01" % (
            ref_year, ref_month), "%Y-%m-%d")
        stop_d_1 = datetime.strptime("%04d-%02d-%s" % (
            start_date.year if start_date.month <12 else start_date.year + 1,
            start_date.month + 1 if start_date.month < 12 else 1,
            1), "%Y-%m-%d")

        stop_date = (stop_d_1 + timedelta(days = -1))

        # ------------------
        # Get employee list:
        # ------------------
        if importation_user_ids: # from importation:
            # NOTE: from importation no department_id admitted
            employee_ids = employee_pool.search(
                cr, uid, [('user_id', 'in', importation_user_ids)])

        else: # from wizard:
            # Filter department or all:
            if department_id: # get filter if department is present
                filter_department = [('department_id', '=', department_id)]
            else:
                filter_department = []
            employee_ids = employee_pool.search(
                cr, uid, filter_department) #, order='name')

        employee_proxy = employee_pool.browse(cr, uid, employee_ids)

        # ----------------------------------------------------------
        # Load all worked hours and festivity for selected employee:
        # ----------------------------------------------------------
        # Search user_id list
        user_ids = []
        for employee in employee_proxy: # sorted by name
            if employee.user_id and employee.user_id.id not in user_ids:
                user_ids.append(employee.user_id.id)

        # Populate worked and not worked hours:
        employee_worked_hours = {}
        employee_not_worked_hours = {}
        employee_not_worked_recover_hours = {}

        ts_pool.get_employee_worked_hours(cr, uid, user_ids,
            start_date, stop_date, employee_worked_hours,
            employee_not_worked_hours, employee_not_worked_recover_hours)

        # ------------------
        # Create print list:
        # ------------------
        for employee in employee_proxy: # sorted by name
            if employee.user_id: # there's linked user

                # Load all working hour for employee
                employee_work_hours = {}
                if employee.contract_tipology_id:
                    for line in employee.contract_tipology_id.line_ids:
                        employee_work_hours[
                            day_number[line.week_day]] = line.name
                    exist_tipology=True
                else:
                    exist_tipology=False

                # Create default month loading block
                # (after compute worked hour and absence hour)
                tot_hour_to_work = [0.0]
                res_dict[employee.user_id.id] = ["%s\n(%s)\n%s" % (
                    employee.name,
                    employee.department_id.name if employee.department_id else "Impostare dipartimento",
                    "" if exist_tipology else "\nImpostare orario",
                    )] + [
                        get_block(start_date,
                        ref_month,
                        item,
                        employee_work_hours,
                        tot_hour_to_work,
                        employee_worked_hours[
                            employee.user_id.id] if employee.user_id.id in employee_worked_hours else {},
                        employee_not_worked_hours[
                            employee.user_id.id] if employee.user_id.id in employee_not_worked_hours else {},
                        employee_not_worked_recover_hours[
                            employee.user_id.id] if employee.user_id.id in employee_not_worked_recover_hours else {},
                        ) for item in range(1,33)]
            else:
                pass # TODO error if there's not a user in employee
        ris = [res_dict[k] for k in res_dict]
        ris.sort()
        return ris

hr_analytic_timesheet()
<commit_msg>Correct function for check origin and return a dict with name in report or dict with ID in import<commit_after>###############################################################################
#
# Copyright (c) 2008-2010 SIA "KN dati". (http://kndati.lv) All Rights Reserved.
#                    General contacts <info@kndati.lv>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
###############################################################################

import os
import sys
import logging
from tools.translate import _
from osv import fields, osv, expression
from report import report_sxw
from report.report_sxw import rml_parse
from datetime import datetime, timedelta

_logger = logging.getLogger(__name__)

dow = {0: "lun", 1: "mar", 2: "mer", 3: "gio", 4: "ven", 5: "sab", 6: "dom"}

class Parser(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context):
        ''' Parser init
        '''
        if context is None:
            context = {}
        super(Parser, self).__init__(cr, uid, name, context)
        self.localcontext.update({
            'get_calendar': self.get_calendar,
            'get_filter_description': self.get_filter_description,
            'week_day': self.week_day,
            })

    def week_day(self, day, data):
        ''' Return the day of a week for day passed in month and year of wizard
        '''
        try:
            pdate = datetime.strptime("%s-%s-%s" % (
                data.get('year',0), data.get('month',0), day), "%Y-%m-%d")
            is_festivity = "\nFES" if self.pool.get(
                'contract.employee.festivity').is_festivity(
                    self.cr, self.uid, pdate) else "" # festivity
            day_of_week = pdate.weekday()

            return "%s\n%s%s" % (day, dow[day_of_week], is_festivity)
        except:
            return "" # Error return always false (so no sunday)

    def get_filter_description(self, data):
        ''' Return string that describe wizard filter elements
            (from data passed)
        '''
        if not data:
            return "Nessun filtro"
        else:
            return 'Dipartimento: %s - Periodo: %s-%s' % (
                data.get('department_name', 'All'),
                data.get('month', '00'),
                data.get('year', '0000'),
                )

    def get_calendar(self, data=None):
        ''' Get calendar for user/mont/year passed
        '''
        if data is None:
            data = {}
        return self.pool.get('hr.analytic.timesheet').get_calendar(
            self.cr, self.uid, data)

class hr_analytic_timesheet(osv.osv):
    ''' Put utility function here for to be used alse from external
        > Wizard
        > Importation
    '''
    _inherit = 'hr.analytic.timesheet'

    # -------------------------------------------------------------------------
    #                             Utility:
    # -------------------------------------------------------------------------
    def get_employee_worked_hours(self, cr, uid, user_ids, from_date, to_date,
            worked, not_worked, not_worked_recover, context=None):
        ''' Search in analytic account line all employee_id.user_id that
            has worked hour for the period
            compile worked and not worked dict with:
                   {user_id: {day_of_month: worked}
                   {user_id: {day_of_month: not worked}
        '''
        res = {}

        # ---------------------------------------
        # only this user_id in the from-to period
        # ---------------------------------------
        line_ids = self.search(cr, uid, [
            ('user_id', 'in', user_ids),
            ('date', '>=', from_date.strftime("%Y-%m-%d")),
            ('date', '<=', to_date.strftime("%Y-%m-%d")),
            ])

        # -----------------------------------
        # loop all lines for totalize results
        # -----------------------------------
        for line in self.browse(cr, uid, line_ids):
            month_day = int(line.date[8:10])
            amount = line.unit_amount or 0.0

            # Type of hour:
            if line.account_id.is_recover:
                dict_ref = not_worked_recover # recover:
            elif line.account_id.not_working:
                dict_ref = not_worked # absence:
            else:
                dict_ref = worked # presence

            if line.user_id.id not in dict_ref:
                dict_ref[line.user_id.id] = {}
                dict_ref[line.user_id.id][month_day] = amount
            else:
                if month_day in dict_ref[line.user_id.id]:
                    dict_ref[line.user_id.id][month_day] += amount
                else:
                    dict_ref[line.user_id.id][month_day] = amount

            # total column:
            if 32 in dict_ref[line.user_id.id]:
                dict_ref[line.user_id.id][32] += amount
            else:
                dict_ref[line.user_id.id][32] = amount
            # TODO update total!!!! (worked and not worked)
        return

    def get_calendar(self, cr, uid, data=None, origin='report', context=None):
        ''' Original function moved here from parser for calculate all database
            for report intervent
            NOTE: The function is moved here as we call also from importation

            self: instance obj
            cr: database curso
            uid: user ID
            data: wizard data dict for pass parameters
            origin: 'report' or 'importation' are admitted
            context: extra parameters array
        '''
        # ---------------------------------------------------------------------
        #                          Utility function:
        # ---------------------------------------------------------------------
        def get_block(start_date, ref_month, day_of_month, employee_work,
                tot_hour_to_work, employee_worked_hours,
                employee_not_worked_hours, employee_not_worked_recover_hours):
            ''' start_date = datetime element for first day of calendar
                ref_month = actual month, used to test end of month during day
                    calc
                employee_work = dict with work hour per day (contract)
                tot_hour_to_work = list passed as totalizator of hour to work
                employee_worked_hours = dict with worked hours (intervent)
                employee_not_worked_hours = dict with not worked hours
                    (intervent with account absence)
                employee_not_worked_recover_hours = dict with not worked hours
                    for recover (intervent with account absence)

                Return: block for represent one day for one employee
                Setup default parameter as:
                [ work hour > calculated depending on employee_work
                  hour worked
                  hour festivity
                  status: FER = Festivity, WE= Week end, OK work + festivity >=
                      hour to work, KO if <
                ]
            '''

            res = [0.0, 0.0, 0.0, "", 0.0] # default value
            actual_date = start_date + timedelta(days = day_of_month - 1)
            wd = datetime.weekday(actual_date)

            if day_of_month == 32: # Total column:
                res[0] = tot_hour_to_work[0]
                # total worked hours
                res[1] = employee_worked_hours[
                    32] if 32 in employee_worked_hours else 0.0
                # total not worked hours
                res[2] = employee_not_worked_hours[
                    32] if 32 in employee_not_worked_hours else 0.0

                # total not worked recover hours
                res[4] = employee_not_worked_recover_hours[
                    32] if 32 in employee_not_worked_recover_hours else 0.0

                # worked - to work - recover (used)
                todo = res[1] - res[0] - res[4]

                # last column is 0 not "OK"
                res[3] = "%s\n%3.2f" % (
                    "recup." if todo >= 0 else "manca",
                    todo)

            elif actual_date.strftime("%m") == ref_month: # same month
                # test if is festivity day:
                if festivity_pool.is_festivity(
                        cr, uid, actual_date):
                    # festivity
                    res[0] = 0.0 # no work hours
                    res[3] = "\nFES"
                else:
                    # other day:
                    wh = employee_work[wd] if wd in employee_work else 0.0
                    res[0] = wh
                    tot_hour_to_work[0] += wh
                    #if wd in (5,6): # saturday and sunday:
                    #    res[3] = "\nW.E."

                # work and not work hours:
                if day_of_month in employee_worked_hours:
                    res[1] = employee_worked_hours[day_of_month]

                if day_of_month in employee_not_worked_hours:
                    res[2] = employee_not_worked_hours[day_of_month]

                if day_of_month in employee_not_worked_recover_hours:
                    res[4] = employee_not_worked_recover_hours[day_of_month]

                # -------
                # Status:
                # -------
                if not (res[0] or res[1] or res[2] or res[4]):
                    # all 0
                    res[3] = ""
                elif res[1] + res[2] + res[4] == res[0]:
                    # OK
                    res[3] = "="
                elif res[1] + res[2] + res[4] < res[0]:
                    # KO
                    res[3] = "<\nERR"
                elif res[1] + res[2] + res[4] - 10.0 > res[0]:
                    #ERR (too much extra hours)
                    res[3] = ">\nERR"
                elif res[1] + res[2] + res[4] - 4.0 > res[0]:
                    #WAR (much extra hours)
                    res[3] = ">\nWAR"
                elif res[1] + res[2] + res[4] > res[0]:
                    # OK > (extra hours)
                    res[3] = ">"
                else:
                    res[3] = "???"

            else: # new month
                res = ["", "", "", "", ""]
            return res[:]

        # ----------
        # Pool used:
        # ----------
        ts_pool = self.pool.get('hr.analytic.timesheet')
        employee_pool = self.pool.get('hr.employee')
        festivity_pool = self.pool.get('contract.employee.festivity')

        # Constant used:
        day_number = {
            'mo': 0, 'tu': 1, 'we': 2, 'th': 3, 'fr': 4, 'sa': 5, 'su': 6}

        # ---------------------------------------------------------------------
        #                         DATA PARAMETERS:
        # ---------------------------------------------------------------------
        if data is None:
           data = {}

        # Common parameters:
        # Get refer for data (else take actual month):
        ref_month = "%02d" % (
            int(data.get('month', datetime.now().strftime("%m"))))
        ref_year  = "%04d" % (
            int(data.get('year', datetime.now().strftime("%Y"))))

        # From wizard:
        department_id = data.get('department_id', False) # no from importation

        # From importation:
        importation_user_ids = data.get('user_ids', False)

        # ---------------
        # Variables used:
        # ---------------
        res_dict = {}

        start_date = datetime.strptime("%s-%s-01" % (
            ref_year, ref_month), "%Y-%m-%d")
        stop_d_1 = datetime.strptime("%04d-%02d-%s" % (
            start_date.year if start_date.month <12 else start_date.year + 1,
            start_date.month + 1 if start_date.month < 12 else 1,
            1), "%Y-%m-%d")

        stop_date = (stop_d_1 + timedelta(days = -1))

        # ------------------
        # Get employee list:
        # ------------------
        if importation_user_ids: # from importation:
            # NOTE: from importation no department_id admitted
            employee_ids = employee_pool.search(
                cr, uid, [('user_id', 'in', importation_user_ids)])

        else: # from wizard:
            # Filter department or all:
            if department_id: # get filter if department is present
                filter_department = [('department_id', '=', department_id)]
            else:
                filter_department = []
            employee_ids = employee_pool.search(
                cr, uid, filter_department) #, order='name')

        employee_proxy = employee_pool.browse(cr, uid, employee_ids)

        # ----------------------------------------------------------
        # Load all worked hours and festivity for selected employee:
        # ----------------------------------------------------------
        # Search user_id list
        user_ids = []
        for employee in employee_proxy: # sorted by name
            if employee.user_id and employee.user_id.id not in user_ids:
                user_ids.append(employee.user_id.id)

        # Populate worked and not worked hours:
        employee_worked_hours = {}
        employee_not_worked_hours = {}
        employee_not_worked_recover_hours = {}

        ts_pool.get_employee_worked_hours(cr, uid, user_ids,
            start_date, stop_date, employee_worked_hours,
            employee_not_worked_hours, employee_not_worked_recover_hours)

        # ------------------
        # Create print list:
        # ------------------
        for employee in employee_proxy: # sorted by name
            if employee.user_id: # there's linked user

                # Load all working hour for employee
                employee_work_hours = {}
                if employee.contract_tipology_id:
                    for line in employee.contract_tipology_id.line_ids:
                        employee_work_hours[
                            day_number[line.week_day]] = line.name
                    exist_tipology=True
                else:
                    exist_tipology=False

                # Create default month loading block
                # (after compute worked hour and absence hour)
                tot_hour_to_work = [0.0]
                res_dict[employee.user_id.id] = ["%s\n(%s)\n%s" % (
                    employee.name,
                    employee.department_id.name if employee.department_id else "Impostare dipartimento",
                    "" if exist_tipology else "\nImpostare orario",
                    )] + [
                        get_block(start_date,
                        ref_month,
                        item,
                        employee_work_hours,
                        tot_hour_to_work,
                        employee_worked_hours[
                            employee.user_id.id] if employee.user_id.id in employee_worked_hours else {},
                        employee_not_worked_hours[
                            employee.user_id.id] if employee.user_id.id in employee_not_worked_hours else {},
                        employee_not_worked_recover_hours[
                            employee.user_id.id] if employee.user_id.id in employee_not_worked_recover_hours else {},
                        ) for item in range(1,33)]
            else:
                pass # TODO error if there's not a user in employee
        if origin == 'report':
            calendar = [res_dict[k] for k in res_dict]
            calendar.sort()
        else: # importation
            calendar = [k for k in res_dict]

        return calendar

hr_analytic_timesheet()
<|endoftext|>


<commit_before>from zasim.cagen import *
from zasim.simulator import *
from zasim.display.console import *

class Grid(object):
    pass

class Grid1DEuclidean(Grid):
    border = None
    acc = None
    loop = None
    size = []
    neighbourhood = ""
    neigh_names = ()

    def __init__(self):
        self.loop = OneDimCellLoop()

    def use_von_neumann_neighbourhood(self, radius=1):
        assert radius == 1
        self.neighbourhood = "von_neumann"

        class NeighHandle(object):
            def compass_names(foo):
                print "compass names for ", self
                self.neigh_names = ("w", "m", "e")
            def direction_names(foo):
                print "direction names for ", self
                self.neigh_names = ("left", "center", "right")
            def ordering_names(foo):
                print "ordering names for ", self
                self.neigh_names = ("prev", "current", "next")
        return NeighHandle()

    def use_cyclic_boundaries_handler(self):
        self.border = SimpleBorderCopier()

    def use_constant_boundaries_handler(self, constant=0):
        assert constant == 0
        self.border = BorderSizeEnsurer()

    def set_extent(self, size):
        self.size = [size]

    def make_neigh(self, baseclass=None):
        assert self.neighbourhood, "call use_*_neighbourhood on the grid first!"
        assert len(self.neigh_names) > 0, "call *_names on the neighbourhood first!"
        if self.neighbourhood == "von_neumann":
            cls = ElementaryFlatNeighbourhood
        else:
            raise "Unimplemented neighbourhood " + self.neighbourhood
        if baseclass:
            self.neigh = cls(baseclass)
        else:
            self.neigh = cls()
        self.neigh.names = self.neigh_names

class Grid2DEuclidean(Grid):
    border = None
    acc = None
    loop = None
    size = []
    neighbourhood = ""
    neigh_names = ()

    def __init__(self):
        self.loop = TwoDimCellLoop()

    def use_von_neumann_neighbourhood(self, radius=1):
        assert radius == 1
        self.neighbourhood = "von_neumann"

        class NeighHandle(object):
            def compass_names(foo):
                print "compass names for ", self
                self.neigh_names = ("n", "w", "s", "e", "m")
            def direction_names(foo):
                print "direction names for ", self
                self.neigh_names = ("up", "left", "down", "right", "middle")
        return NeighHandle()

    def use_cyclic_boundaries_handler(self):
        self.border = TwoDimSlicingBorderCopier()

    def use_constant_boundaries_handler(self, constant=0):
        assert constant == 0
        self.border = BorderSizeEnsurer()

    def set_extent(self, *size):
        self.size = size

    def make_neigh(self, baseclass=None):
        assert self.neighbourhood, "call use_*_neighbourhood on the grid first!"
        assert len(self.neigh_names) > 0, "call *_names on the neighbourhood first!"
        if self.neighbourhood == "von_neumann":
            cls = VonNeumannNeighbourhood
        else:
            raise "Unimplemented neighbourhood " + self.neighbourhood
        if baseclass:
            self.neigh = cls(baseclass)
        else:
            self.neigh = cls()
        self.neigh.names = self.neigh_names

class Domain(object):
    def values(self):
        """Return a list of possible values"""
        return []
    def accepts(self, other):
        """Is the given value in the domain?"""
        return False

class RangeDomain(Domain):
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def values(self):
        return range(self.start, self.end)

    def accepts(self, other):
        return self.start <= other <= self.end

class ValuesDomain(Domain):
    def __init__(self, *values):
        self.vals = values

    def values(self): return self.vals[:]
    def accepts(self, other): return other in self.vals

class CellDescriptor(object):
    """Gives a nice API to set different cell's attributes on a State instance"""
    def __init__(self, state, cellname):
        self.state = state
        self.name = cellname

    def dtype(self, dtype):
        self.state.types[self.name] = dtype
        return self

    def default(self, value):
        self.state.defaults[self.name] = value
        return self

    def domain(self, domain):
        if isinstance(domain, tuple) and len(domain) == 2:
            self.state.domain[self.name] = RangeDomain(*domain)
        else:
            self.state.domain[self.name] = ValuesDomain(*domain)
        return self

class InteractivePalette(dict):
    def __init__(self, provider):
        super(InteractivePalette, self).__init__()
        self.provider = provider

    def __missing__(self, key):
        return self.provider(key)

class DisplayDef(object):
    pass

class AnsiDisplayDef(DisplayDef):
    """A display definition that supports characters, colors and a few
    terminal attributes like bold, inverted or underlined - depending on
    the terminal in use."""

    rendertype = ""
    """The kind of rendering to do

    - boxes
        Align all or some of the subcells in a big box.
        the "renderers" attribute is a dictionary that prescribes a rendering
        method for each subcell. Those are then composed into boxes using the
        inner_border and outer_border specifications.

    - box
        A custom function is used to generate one string representation of a
        whole cell and that is then wrapped into a box, if outer_border is
        set.
        This function is stored in the renderer attribute.
    """

    # TODO there should be a way to create boxes that derive from multiple subcells

    _sets = None
    _boxes = None
    borders = None
    renderer = None
    renderers = None
    col_widths = None
    row_heights = None
    cellspan_def = None

    def __init__(self, state, name):
        self.state = state
        self.name = name

        self._sets = None
        self._boxes = None
        self.renderers = {}

    def border(self, subcell, cell):
        self.borders = (subcell, cell)
        return self

    def boxes(self, **boxes):
        """Set the positioning of the subcells, if boxes are to be used."""
        self.rendertype = "boxes"
        fixed_boxes = {}
        fixed_sets = {}
        for k, v in boxes.iteritems():
            fixed_boxes[v] = k
            fixed_sets[v] = self.state.domain[k].values()
        self._boxes = fixed_boxes
        self._sets = fixed_sets
        return self

    def span_box(self, cell, width=1, height=1):
        """Define a box to span columns or rows"""
        assert (width != 1) != (height != 1), "can only rowspan or colspan" # XXX arbitrary restriction ...
        cellspan_def[cell] = (width, height)
        return self

    def numbers(self, *subcells):
        """Specify that numbers are to be used to render a subcell's contents"""
        for sc in subcells:
            self.renderers[sc] = ("numbers",) # XXX create a class or something for these?
        return self

    def palette(self, **subcell_palettes):
        """Takes a named argument for each subcell that provides a list or
        dictionary mapping subcell values to display characters"""
        for cell, scp in subcell_palettes.iteritems():
            self.renderers[cell] = ("palette", scp)
        return self

    def palettize_cell(self, fun):
        self.rendertype = "box"
        self.renderer = fun
        return fun

    def palettize_subcell(self, subcell):
        def subcell_palletizer_wrapper(fun):
            self.renderers[subcell] = ("function", fun)
            return fun
        return subcell_palletizer_wrapper

class State(object):
    names = None
    """The names of the state's subcells"""

    types = None
    """A mapping of name to type"""

    defaults = None
    """A mapping of name to default value"""

    domain = None
    """A mapping of name to what values are possible.

    Optional."""

    displays = None
    """A mapping of name to definition"""

    subcell = False

    def __init__(self):
        self.names = []
        self.types = {}
        self.defaults = {}
        self.domain = {}
        self.displays = {}

    def cell(self, name):
        self.names.append(name)
        if not self.subcell and len(self.names) > 1:
            self.subcell = True
        return CellDescriptor(self, name)

    def __getattr__(self, attr):
        if attr.startswith("display_"):
            clsname = (attr[len("display_"):]).title() + "DisplayDef"
            if clsname in globals():
                def make_the_display_class(name):
                    instance = globals()[clsname](self, name)
                    self.displays[name] = instance
                    return instance
                return make_the_display_class
            else:
                raise AttributeError()
        else:
            raise AttributeError()

class DoubleBufferStorage(object):
    state = None

    def __init__(self, grid, state, buffer_names=('cur', 'new')):
        self.state = state
        if state.subcell:
            print "using a subcell accessor"
            grid.acc = SubcellAccessor(state.names)
            grid.make_neigh(SubcellNeighbourhood)
        else:
            grid.acc = SimpleStateAccessor()
            grid.make_neigh()

class SubcellSimulator(CagenSimulator):
    sets = []
    def __init__(self, sim, sets, **kwargs):
        self.sets = sets
        super(SubcellSimulator, self).__init__(sim)

    def get_config(self):
        res = {}
        for k in self.sets:
            res[k] = getattr(self.t, "cconf_%s" % k)
        return res

class ZA(object):
    def __init__(self, grid, mem, code, base=2, extra_list=()):
        if isinstance(code, basestring):
            code = PasteComputation(py_code = code)

        self.size = grid.size
        self.mem = mem
        if self.mem.state.subcell:
            target = SubcellTarget(cells=self.mem.state.names, size=self.size, base=base)
        else:
            target = Target(self.size, None, base=base)
        stepfunc = StepFunc(
                loop=grid.loop,
                accessor=grid.acc,
                neighbourhood=grid.neigh,
                border=grid.border,
                visitors=[code] + list(extra_list),
                target=target)
        self.stepfunc = stepfunc
        self.stepfunc.gen_code()
        self.disp = {}
        self.sim = SubcellSimulator(stepfunc, self.mem.state.names)

    def display(self, display_to_use):
        displaydef = self.mem.state.displays[display_to_use]

        if isinstance(displaydef, AnsiDisplayDef):
            if displaydef.rendertype == "boxes":
                palettes = {}
                for box, render in displaydef.renderers.iteritems():
                    if render[0] == "palette":
                        palettes[box] = render[1]
                    elif render[0] == "numbers":
                        pass
                    elif render[0] == "function":
                        raise NotImplementedError("function renderers not yet implemented")
            self.disp[display_to_use] = SubcellConsoleDisplay(self.sim, displaydef._boxes, displaydef._sets, palettes)
        else:
            raise NotImplementedError("Only AnsiDisplayDef implemented so far")

        #if self.mem.state.subcell:
            #class SubcellOneDimConsolePainter(SubcellPainterMixin, OneDimConsolePainter):
                #pass
        #self.disp = SubcellOneDimConsolePainter(self.sim, 1)

    def compile_py(self):
        pass

    def run(self, steps):
        for i in range(steps):
            self.sim.step_pure_py()
<commit_msg>fix the neighbourhood names<commit_after>from zasim.cagen import *
from zasim.simulator import *
from zasim.display.console import *

class Grid(object):
    pass

class Grid1DEuclidean(Grid):
    border = None
    acc = None
    loop = None
    size = []
    neighbourhood = ""
    neigh_names = ()

    def __init__(self):
        self.loop = OneDimCellLoop()

    def use_von_neumann_neighbourhood(self, radius=1):
        assert radius == 1
        self.neighbourhood = "von_neumann"

        class NeighHandle(object):
            def compass_names(foo):
                print "compass names for ", self
                self.neigh_names = ("w", "m", "e")
            def direction_names(foo):
                print "direction names for ", self
                self.neigh_names = ("left", "center", "right")
            def ordering_names(foo):
                print "ordering names for ", self
                self.neigh_names = ("prev", "current", "next")
        return NeighHandle()

    def use_cyclic_boundaries_handler(self):
        self.border = SimpleBorderCopier()

    def use_constant_boundaries_handler(self, constant=0):
        assert constant == 0
        self.border = BorderSizeEnsurer()

    def set_extent(self, size):
        self.size = [size]

    def make_neigh(self, baseclass=None):
        assert self.neighbourhood, "call use_*_neighbourhood on the grid first!"
        assert len(self.neigh_names) > 0, "call *_names on the neighbourhood first!"
        if self.neighbourhood == "von_neumann":
            cls = ElementaryFlatNeighbourhood
        else:
            raise "Unimplemented neighbourhood " + self.neighbourhood
        if baseclass:
            self.neigh = cls(baseclass)
        else:
            self.neigh = cls()
        self.neigh.names = self.neigh_names

class Grid2DEuclidean(Grid):
    border = None
    acc = None
    loop = None
    size = []
    neighbourhood = ""
    neigh_names = ()

    def __init__(self):
        self.loop = TwoDimCellLoop()

    def use_von_neumann_neighbourhood(self, radius=1):
        assert radius == 1
        self.neighbourhood = "von_neumann"

        class NeighHandle(object):
            def compass_names(foo):
                print "compass names for ", self
                self.neigh_names = ("w", "n", "m", "s", "e")
            def direction_names(foo):
                print "direction names for ", self
                self.neigh_names = ("up", "left", "down", "right", "middle")
        return NeighHandle()

    def use_cyclic_boundaries_handler(self):
        self.border = TwoDimSlicingBorderCopier()

    def use_constant_boundaries_handler(self, constant=0):
        assert constant == 0
        self.border = BorderSizeEnsurer()

    def set_extent(self, *size):
        self.size = size

    def make_neigh(self, baseclass=None):
        assert self.neighbourhood, "call use_*_neighbourhood on the grid first!"
        assert len(self.neigh_names) > 0, "call *_names on the neighbourhood first!"
        if self.neighbourhood == "von_neumann":
            cls = VonNeumannNeighbourhood
        else:
            raise "Unimplemented neighbourhood " + self.neighbourhood
        if baseclass:
            self.neigh = cls(baseclass)
        else:
            self.neigh = cls()
        self.neigh.names = self.neigh_names

class Domain(object):
    def values(self):
        """Return a list of possible values"""
        return []
    def accepts(self, other):
        """Is the given value in the domain?"""
        return False

class RangeDomain(Domain):
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def values(self):
        return range(self.start, self.end)

    def accepts(self, other):
        return self.start <= other <= self.end

class ValuesDomain(Domain):
    def __init__(self, *values):
        self.vals = values

    def values(self): return self.vals[:]
    def accepts(self, other): return other in self.vals

class CellDescriptor(object):
    """Gives a nice API to set different cell's attributes on a State instance"""
    def __init__(self, state, cellname):
        self.state = state
        self.name = cellname

    def dtype(self, dtype):
        self.state.types[self.name] = dtype
        return self

    def default(self, value):
        self.state.defaults[self.name] = value
        return self

    def domain(self, domain):
        if isinstance(domain, tuple) and len(domain) == 2:
            self.state.domain[self.name] = RangeDomain(*domain)
        else:
            self.state.domain[self.name] = ValuesDomain(*domain)
        return self

class InteractivePalette(dict):
    def __init__(self, provider):
        super(InteractivePalette, self).__init__()
        self.provider = provider

    def __missing__(self, key):
        return self.provider(key)

class DisplayDef(object):
    pass

class AnsiDisplayDef(DisplayDef):
    """A display definition that supports characters, colors and a few
    terminal attributes like bold, inverted or underlined - depending on
    the terminal in use."""

    rendertype = ""
    """The kind of rendering to do

    - boxes
        Align all or some of the subcells in a big box.
        the "renderers" attribute is a dictionary that prescribes a rendering
        method for each subcell. Those are then composed into boxes using the
        inner_border and outer_border specifications.

    - box
        A custom function is used to generate one string representation of a
        whole cell and that is then wrapped into a box, if outer_border is
        set.
        This function is stored in the renderer attribute.
    """

    # TODO there should be a way to create boxes that derive from multiple subcells

    _sets = None
    _boxes = None
    borders = None
    renderer = None
    renderers = None
    col_widths = None
    row_heights = None
    cellspan_def = None

    def __init__(self, state, name):
        self.state = state
        self.name = name

        self._sets = None
        self._boxes = None
        self.renderers = {}

    def border(self, subcell, cell):
        self.borders = (subcell, cell)
        return self

    def boxes(self, **boxes):
        """Set the positioning of the subcells, if boxes are to be used."""
        self.rendertype = "boxes"
        fixed_boxes = {}
        fixed_sets = {}
        for k, v in boxes.iteritems():
            fixed_boxes[v] = k
            fixed_sets[v] = self.state.domain[k].values()
        self._boxes = fixed_boxes
        self._sets = fixed_sets
        return self

    def span_box(self, cell, width=1, height=1):
        """Define a box to span columns or rows"""
        assert (width != 1) != (height != 1), "can only rowspan or colspan" # XXX arbitrary restriction ...
        cellspan_def[cell] = (width, height)
        return self

    def numbers(self, *subcells):
        """Specify that numbers are to be used to render a subcell's contents"""
        for sc in subcells:
            self.renderers[sc] = ("numbers",) # XXX create a class or something for these?
        return self

    def palette(self, **subcell_palettes):
        """Takes a named argument for each subcell that provides a list or
        dictionary mapping subcell values to display characters"""
        for cell, scp in subcell_palettes.iteritems():
            self.renderers[cell] = ("palette", scp)
        return self

    def palettize_cell(self, fun):
        self.rendertype = "box"
        self.renderer = fun
        return fun

    def palettize_subcell(self, subcell):
        def subcell_palletizer_wrapper(fun):
            self.renderers[subcell] = ("function", fun)
            return fun
        return subcell_palletizer_wrapper

class State(object):
    names = None
    """The names of the state's subcells"""

    types = None
    """A mapping of name to type"""

    defaults = None
    """A mapping of name to default value"""

    domain = None
    """A mapping of name to what values are possible.

    Optional."""

    displays = None
    """A mapping of name to definition"""

    subcell = False

    def __init__(self):
        self.names = []
        self.types = {}
        self.defaults = {}
        self.domain = {}
        self.displays = {}

    def cell(self, name):
        self.names.append(name)
        if not self.subcell and len(self.names) > 1:
            self.subcell = True
        return CellDescriptor(self, name)

    def __getattr__(self, attr):
        if attr.startswith("display_"):
            clsname = (attr[len("display_"):]).title() + "DisplayDef"
            if clsname in globals():
                def make_the_display_class(name):
                    instance = globals()[clsname](self, name)
                    self.displays[name] = instance
                    return instance
                return make_the_display_class
            else:
                raise AttributeError()
        else:
            raise AttributeError()

class DoubleBufferStorage(object):
    state = None

    def __init__(self, grid, state, buffer_names=('cur', 'new')):
        self.state = state
        if state.subcell:
            print "using a subcell accessor"
            grid.acc = SubcellAccessor(state.names)
            grid.make_neigh(SubcellNeighbourhood)
        else:
            grid.acc = SimpleStateAccessor()
            grid.make_neigh()

class SubcellSimulator(CagenSimulator):
    sets = []
    def __init__(self, sim, sets, **kwargs):
        self.sets = sets
        super(SubcellSimulator, self).__init__(sim)

    def get_config(self):
        res = {}
        for k in self.sets:
            res[k] = getattr(self.t, "cconf_%s" % k)
        return res

class ZA(object):
    def __init__(self, grid, mem, code, base=2, extra_list=()):
        if isinstance(code, basestring):
            code = PasteComputation(py_code = code)

        self.size = grid.size
        self.mem = mem
        if self.mem.state.subcell:
            target = SubcellTarget(cells=self.mem.state.names, size=self.size, base=base)
        else:
            target = Target(self.size, None, base=base)
        stepfunc = StepFunc(
                loop=grid.loop,
                accessor=grid.acc,
                neighbourhood=grid.neigh,
                border=grid.border,
                visitors=[code] + list(extra_list),
                target=target)
        self.stepfunc = stepfunc
        self.stepfunc.gen_code()
        self.disp = {}
        self.sim = SubcellSimulator(stepfunc, self.mem.state.names)

    def display(self, display_to_use):
        displaydef = self.mem.state.displays[display_to_use]

        if isinstance(displaydef, AnsiDisplayDef):
            if displaydef.rendertype == "boxes":
                palettes = {}
                for box, render in displaydef.renderers.iteritems():
                    if render[0] == "palette":
                        palettes[box] = render[1]
                    elif render[0] == "numbers":
                        pass
                    elif render[0] == "function":
                        raise NotImplementedError("function renderers not yet implemented")
            self.disp[display_to_use] = SubcellConsoleDisplay(self.sim, displaydef._boxes, displaydef._sets, palettes)
        else:
            raise NotImplementedError("Only AnsiDisplayDef implemented so far")

        #if self.mem.state.subcell:
            #class SubcellOneDimConsolePainter(SubcellPainterMixin, OneDimConsolePainter):
                #pass
        #self.disp = SubcellOneDimConsolePainter(self.sim, 1)

    def compile_py(self):
        pass

    def run(self, steps):
        for i in range(steps):
            self.sim.step_pure_py()
<|endoftext|>


<commit_before>from st2tests.base import BaseActionAliasTestCase

class DeployActionAliasTestCase(BaseActionAliasTestCase):
    alias_name = 'deploy_pack'

    def test_deploy_alias(self):
        # Includes packs
        format_string_1 = self.action_alias_db.formats[0]['representation'][0]

        # String with branch
        command = 'pack deploy StackStorm/st2contrib branch master'
        command = 'pack deploy StackStorm/st2contrib branch ma_branch'

        format_string_2 = self.action_alias_db.formats[0]['representation'][1]

        # Doesnt include packs
        format_string_1 = self.action_alias_db.formats[1]['representation'][0]
        format_string_2 = self.action_alias_db.formats[1]['representation'][1]
        print format_string_1
        pass
<commit_msg>Update and add tests for deploy pack alias.<commit_after>from st2tests.base import BaseActionAliasTestCase

class DeployActionAliasTestCase(BaseActionAliasTestCase):
    alias_name = 'deploy_pack'

    def test_deploy_alias(self):
        # Includes packs
        format_string = self.action_alias_db.formats[0]['representation'][0]

        # Command with branch
        command = 'pack deploy StackStorm/st2contrib packs libcloud,aws branch master'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib',
            'packs': 'libcloud,aws',
            'branch': 'master'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)

        command = 'pack deploy StackStorm/st2contrib packs libcloud branch ma_branch'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib',
            'packs': 'libcloud',
            'branch': 'ma_branch'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)

        # Command without branch
        format_string = self.action_alias_db.formats[0]['representation'][1]
        command = 'pack deploy StackStorm/st2contrib packs libcloud,aws'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib',
            'packs': 'libcloud,aws'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)

        command = 'pack deploy StackStorm/st2contrib packs libcloud'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib',
            'packs': 'libcloud'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)

        # Doesnt include packs
        format_string = self.action_alias_db.formats[1]['representation'][0]
        command = 'pack deploy StackStorm/st2contrib branch trunk'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib',
            'branch': 'trunk'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)

        format_string = self.action_alias_db.formats[1]['representation'][1]
        command = 'pack deploy StackStorm/st2contrib'
        expected_parameters = {
            'repo_name': 'StackStorm/st2contrib'
        }
        self.assertExtractedParametersMatch(format_string=format_string,
                                            command=command,
                                            values=expected_parameters)
<|endoftext|>


<commit_before>#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Search and Store Tweets utility.

Search for tweets in the Twitter API for given search query, then store
the tweet and the tweet author data, adding new objects or updating existing
ones.

The input may be command-line text for easy ad hoc queries, or the name of
an existing Campaign in the db so that its search query string can be
looked up.

Add the default label as Campaign for processed Tweets to signal that the Tweet
was processed by this script. If looking up Tweets using the search query from
a Campaign specified in arguments, then also allocate the processed Tweets
to that Campaign.

Add the default label as Category for Profiles which are processed due to
processing their Tweets.

The persist value is set based on an answer here:
    https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse

TODO: Consolidate use of writeToDB and persist in this repo.
"""
import argparse
import datetime
import os
import sys

from sqlobject import SQLObjectNotFound

# Allow imports to be done when executing this file directly.
sys.path.insert(0, os.path.abspath(os.path.join(
    os.path.dirname(__file__), os.path.pardir, os.path.pardir)
))

from lib import database as db, flattenText, tweets
from lib.config import AppConf
from lib.twitter_api import auth, search
from lib.query.tweets.campaigns import printAvailableCampaigns, \
                                       printCampaignsAndTweets

conf = AppConf ()
UTILITY_CATEGORY = UTILITY_CAMPAIGN = conf.get('Labels', 'search')

# Create initial global API connection object, which needs to be set using
# a function on auth.
API_CONN = None

def _searchAndStore(searchQuery, pageCount=1, persist=True, extended=True):
    """
    Search the Twitter Search API for tweets matching input search terms.

    By default, the tweets are created or updated as Tweet records in the
    local DB.

    Only matches on tweets for users which had their language set to English
    or undefined.

    @param searchQuery: Query text to search on the Twitter API.
    @param pageCount: Count pages of tweets to fetch. Each page contains 100
        tweets, which is the Search API's limit.
    @param persist. Default True. If set to False, does not store data
        in the database and only prints to stdout.
    @param extended: If True, get the expanded tweet message instead of the
        truncated form.

    @return processedTweets: count of tweets fetched, unaffected by
        with the data is persisted. This count will be a number up to the
        totalCount argument, but may less if fewer tweets are available in
        the 7-day window.
    @return profileRecs: List of local Profile records inserted or updated.
        Defaults to empty list.
    @return tweetRecs: List of local Tweet records inserted or updated.
        Defaults to empty list.
    """
    assert API_CONN, ("Authenticate with Twitter API before doing"
                      " a search for tweets.")
    searchPages = search.fetchTweetsPaging(
        API_CONN,
        searchQuery=searchQuery,
        pageCount=pageCount,
        extended=extended
    )

    processedTweets = 0
    profileRecs = []
    tweetRecs = []

    for page in searchPages:
        for fetchedTweet in page:
            if persist:
                profileRec = tweets.insertOrUpdateProfile(fetchedTweet.author)
                profileRecs.append(profileRec)
                data, tweetRec = tweets.insertOrUpdateTweet(
                    fetchedTweet,
                    profileRec.id
                )
                tweetRecs.append(tweetRec)
                if (processedTweets + 1) % 100 == 0:
                    print "Processed so far: {}".format(processedTweets + 1)
            else:
                # Assume extended mode, otherwise fall back to standard mode.
                try:
                    text = fetchedTweet.full_text
                except AttributeError:
                    text = fetchedTweet.text

                print u"{index:3d} @{screenName}: {message}".format(
                    index=processedTweets + 1,
                    screenName=fetchedTweet.author.screen_name,
                    message=flattenText(text)
                )
            processedTweets += 1
    print

    return processedTweets, profileRecs, tweetRecs

def searchStoreAndLabel(query, pages, persist, utilityCampaignRec, customCampaignRec):
    """
    Fetch and store tweet data and assign labels.

    @param str query: Twitter API search query.
    @param int pages: Count of pages of tweets to fetch.
    @param bool persist: If True, persist data.
    @param models.tweets.Campaign utilityCampaignRec:
    @param models.tweets.Campaign customCampaignRec:

    @return: None
    """
    now = datetime.datetime.now()
    processedCount, profileRecs, tweetRecs = _searchAndStore(
        query,
        pageCount=pages,
        persist=persist
    )
    print "Completed tweet processing: {0:,d}".format(processedCount)
    print "took {0}".format(datetime.datetime.now() - now)

    if profileRecs:
        print "Assigning category links... ",
        now = datetime.datetime.now()
        try:
            utilityCategoryRec = db.Category.byName(UTILITY_CATEGORY)
        except SQLObjectNotFound:
            utilityCategoryRec = db.Category(name=UTILITY_CATEGORY)
        tweets.bulkAssignProfileCategory(
            categoryID=utilityCategoryRec.id,
            profileIDs=(profile.id for profile in profileRecs)
        )
        print "DONE"
        print "took {0}".format(datetime.datetime.now() - now)

    if tweetRecs:
        print "Assigning utility's campaign links... ",
        now = datetime.datetime.now()
        tweets.bulkAssignTweetCampaign(
            campaignID=utilityCampaignRec.id,
            tweetIDs=(tweet.id for tweet in tweetRecs)
        )
        print "DONE"
        print "took {0}".format(datetime.datetime.now() - now)

        if customCampaignRec:
            print "Assigning custom campaign links... ",
            now = datetime.datetime.now()
            # Reset generator to first item, after using it above within
            # the bulk assign function.
            tweetIDs = (tweet.id for tweet in tweetRecs)
            tweets.bulkAssignTweetCampaign(
                campaignID=customCampaignRec.id,
                tweetIDs=tweetIDs
            )
            print "DONE"
            print "took {0}".format(datetime.datetime.now() - now)

def main():
    """
    Handle command-line arguments to search for tweets, store data for
    Tweet and Profile objects and then assign labels.
    """
    global API_CONN

    parser = argparse.ArgumentParser(
        description="""\
Utility to search for tweets and then the store tweet and profile data locally.

Search with either an ad hoc query, or the name of a stored Campaign which
has a search query set. To create or edit a Campaign, use the Campaign Manager
utility.
        """,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    view = parser.add_argument_group(
        "View",
        "Print data to stdout"
    )
    view.add_argument(
        '-a', '--available',
        action='store_true',
        help="""Output available Campaigns in db, with Tweet counts and
             search query for each."""
    )
    view.add_argument(
        '-t', '--tweets',
        action='store_true',
        help="Output local Tweets grouped by Campaign."
    )
    view.add_argument(
        '-s', '--search-help',
        action='store_true',
        help="""Print guide for writing search queries, with examples of
            syntax safe for the command-line. See Twitter's search
            documentation for full rules."""
    )

    fetch = parser.add_argument_group(
        "Fetch",
        "Select a search query to get Tweets from Twitter Search API."
    )
    fetch.add_argument(
        '-c', '--campaign',
        help="""Name of existing campaign in the db. If supplied and the
            Campaign record has a query string, fetch Tweets from the Twitter
            Search API and store. Then assign the given custom Campaign name
            to processed Tweets. This argument may not be used with the
            --query argument.
        """
    )
    fetch.add_argument(
        '-q', '--query',
        help="""Word or phrase to search on the Twitter API as an ad hoc
            query which is not associated with a Campaign. This argument
            may not be used with the --campaign argument."""
    )
    fetch.add_argument(
        '-p', '--pages',
        metavar='N',
        type=int,
        default=1,
        help="Default 1. Count of pages of tweets to get for the search query,"
            " where each page contains up to 100 tweets."
    )
    fetch.add_argument(
        '--persist',
        dest='persist',
        action='store_true',
        help="(DEFAULT) Store fetched tweets and profiles in the database."
    )
    fetch.add_argument(
        '--no-persist',
        dest='persist',
        action='store_false',
        help="Print fetched tweet and profile data without storing."
    )
    fetch.set_defaults(persist=True)

    args = parser.parse_args()

    if args.available:
        printAvailableCampaigns()
    if args.tweets:
        printCampaignsAndTweets()
    if args.search_help:
        print search.getSearchQueryHelp()

    if args.query or args.campaign:
        try:
            utilityCampaignRec = db.Campaign.byName(UTILITY_CAMPAIGN)
        except SQLObjectNotFound:
            # The campaign manager is not needed externally for creating
            # this one, since the searchQuery is best set to NULL for
            # this specific campaign and therefore can be automatic.
            utilityCampaignRec = db.Campaign(
                name=UTILITY_CAMPAIGN,
                searchQuery=None
            )

        if args.query:
            customCampaignRec = None
            query = unicode(args.query, 'utf-8')
        else:
            campaignName = args.campaign
            try:
                customCampaignRec = db.Campaign.byName(campaignName)
            except SQLObjectNotFound as e:
                raise type(e)("Use the campaign manager to create the Campaign"
                              " as name and search query. Name not found: {0}"
                              .format(campaignName))
            query = customCampaignRec.searchQuery
            assert query, "Use the Campaign Manager to set a search query"\
                          " for the campaign: {0}".format(args.campaign)

        # Process the category and campaign records above before fetching
        # data from the API.
        print u"Search query: {0}".format(query)

        # Use app auth here for up to 480 search requests per window, rather
        # than 180 when using the user auth.
        API_CONN = auth.getAppOnlyConnection()
        searchStoreAndLabel(
            query,
            args.pages, args.persist,
            utilityCampaignRec, customCampaignRec,
        )

if __name__ == '__main__':
    main()
<commit_msg>docs: Update function docstring<commit_after>#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Search and Store Tweets utility.

Search for tweets in the Twitter API for given search query, then store
the tweet and the tweet author data, adding new objects or updating existing
ones.

The input may be command-line text for easy ad hoc queries, or the name of
an existing Campaign in the db so that its search query string can be
looked up.

Add the default label as Campaign for processed Tweets to signal that the Tweet
was processed by this script. If looking up Tweets using the search query from
a Campaign specified in arguments, then also allocate the processed Tweets
to that Campaign.

Add the default label as Category for Profiles which are processed due to
processing their Tweets.

The persist value is set based on an answer here:
    https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse

TODO: Consolidate use of writeToDB and persist in this repo.
"""
import argparse
import datetime
import os
import sys

from sqlobject import SQLObjectNotFound

# Allow imports to be done when executing this file directly.
sys.path.insert(0, os.path.abspath(os.path.join(
    os.path.dirname(__file__), os.path.pardir, os.path.pardir)
))

from lib import database as db, flattenText, tweets
from lib.config import AppConf
from lib.twitter_api import auth, search
from lib.query.tweets.campaigns import printAvailableCampaigns, \
                                       printCampaignsAndTweets

conf = AppConf ()
UTILITY_CATEGORY = UTILITY_CAMPAIGN = conf.get('Labels', 'search')

# Create initial global API connection object, which needs to be set using
# a function on auth.
API_CONN = None

def _searchAndStore(searchQuery, pageCount=1, persist=True, extended=True):
    """
    Search the Twitter Search API for tweets matching input search terms.

    Tweets are created or updated and their authors are created or updated
    as Profile records.

    @param searchQuery: Query text to search on the Twitter API.
    @param pageCount: Count pages of tweets to fetch. Each page contains 100
        tweets, which is the Search API's limit.
    @param persist. Default True. If set to False, does not store data
        in the database and only prints to stdout.
    @param extended: If True, get the expanded tweet message instead of the
        truncated form.

    @return processedTweets: count of tweets fetched, unaffected by
        with the data is persisted. This count will be a number up to the
        totalCount argument, but may less if fewer tweets are available in
        the 7-day window.
    @return profileRecs: List of local Profile records inserted or updated.
        Defaults to empty list.
    @return tweetRecs: List of local Tweet records inserted or updated.
        Defaults to empty list.
    """
    assert API_CONN, ("Authenticate with Twitter API before doing"
                      " a search for tweets.")
    searchPages = search.fetchTweetsPaging(
        API_CONN,
        searchQuery=searchQuery,
        pageCount=pageCount,
        extended=extended
    )

    processedTweets = 0
    profileRecs = []
    tweetRecs = []

    for page in searchPages:
        for fetchedTweet in page:
            if persist:
                profileRec = tweets.insertOrUpdateProfile(fetchedTweet.author)
                profileRecs.append(profileRec)
                data, tweetRec = tweets.insertOrUpdateTweet(
                    fetchedTweet,
                    profileRec.id
                )
                tweetRecs.append(tweetRec)
                if (processedTweets + 1) % 100 == 0:
                    print "Processed so far: {}".format(processedTweets + 1)
            else:
                # Assume extended mode, otherwise fall back to standard mode.
                try:
                    text = fetchedTweet.full_text
                except AttributeError:
                    text = fetchedTweet.text

                print u"{index:3d} @{screenName}: {message}".format(
                    index=processedTweets + 1,
                    screenName=fetchedTweet.author.screen_name,
                    message=flattenText(text)
                )
            processedTweets += 1
    print

    return processedTweets, profileRecs, tweetRecs

def searchStoreAndLabel(query, pages, persist, utilityCampaignRec, customCampaignRec):
    """
    Fetch and store tweet data and assign labels.

    @param str query: Twitter API search query.
    @param int pages: Count of pages of tweets to fetch.
    @param bool persist: If True, persist data.
    @param models.tweets.Campaign utilityCampaignRec:
    @param models.tweets.Campaign customCampaignRec:

    @return: None
    """
    now = datetime.datetime.now()
    processedCount, profileRecs, tweetRecs = _searchAndStore(
        query,
        pageCount=pages,
        persist=persist
    )
    print "Completed tweet processing: {0:,d}".format(processedCount)
    print "took {0}".format(datetime.datetime.now() - now)

    if profileRecs:
        print "Assigning category links... ",
        now = datetime.datetime.now()
        try:
            utilityCategoryRec = db.Category.byName(UTILITY_CATEGORY)
        except SQLObjectNotFound:
            utilityCategoryRec = db.Category(name=UTILITY_CATEGORY)
        tweets.bulkAssignProfileCategory(
            categoryID=utilityCategoryRec.id,
            profileIDs=(profile.id for profile in profileRecs)
        )
        print "DONE"
        print "took {0}".format(datetime.datetime.now() - now)

    if tweetRecs:
        print "Assigning utility's campaign links... ",
        now = datetime.datetime.now()
        tweets.bulkAssignTweetCampaign(
            campaignID=utilityCampaignRec.id,
            tweetIDs=(tweet.id for tweet in tweetRecs)
        )
        print "DONE"
        print "took {0}".format(datetime.datetime.now() - now)

        if customCampaignRec:
            print "Assigning custom campaign links... ",
            now = datetime.datetime.now()
            # Reset generator to first item, after using it above within
            # the bulk assign function.
            tweetIDs = (tweet.id for tweet in tweetRecs)
            tweets.bulkAssignTweetCampaign(
                campaignID=customCampaignRec.id,
                tweetIDs=tweetIDs
            )
            print "DONE"
            print "took {0}".format(datetime.datetime.now() - now)

def main():
    """
    Handle command-line arguments to search for tweets, store data for
    Tweet and Profile objects and then assign labels.
    """
    global API_CONN

    parser = argparse.ArgumentParser(
        description="""\
Utility to search for tweets and then the store tweet and profile data locally.

Search with either an ad hoc query, or the name of a stored Campaign which
has a search query set. To create or edit a Campaign, use the Campaign Manager
utility.
        """,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    view = parser.add_argument_group(
        "View",
        "Print data to stdout"
    )
    view.add_argument(
        '-a', '--available',
        action='store_true',
        help="""Output available Campaigns in db, with Tweet counts and
             search query for each."""
    )
    view.add_argument(
        '-t', '--tweets',
        action='store_true',
        help="Output local Tweets grouped by Campaign."
    )
    view.add_argument(
        '-s', '--search-help',
        action='store_true',
        help="""Print guide for writing search queries, with examples of
            syntax safe for the command-line. See Twitter's search
            documentation for full rules."""
    )

    fetch = parser.add_argument_group(
        "Fetch",
        "Select a search query to get Tweets from Twitter Search API."
    )
    fetch.add_argument(
        '-c', '--campaign',
        help="""Name of existing campaign in the db. If supplied and the
            Campaign record has a query string, fetch Tweets from the Twitter
            Search API and store. Then assign the given custom Campaign name
            to processed Tweets. This argument may not be used with the
            --query argument.
        """
    )
    fetch.add_argument(
        '-q', '--query',
        help="""Word or phrase to search on the Twitter API as an ad hoc
            query which is not associated with a Campaign. This argument
            may not be used with the --campaign argument."""
    )
    fetch.add_argument(
        '-p', '--pages',
        metavar='N',
        type=int,
        default=1,
        help="Default 1. Count of pages of tweets to get for the search query,"
            " where each page contains up to 100 tweets."
    )
    fetch.add_argument(
        '--persist',
        dest='persist',
        action='store_true',
        help="(DEFAULT) Store fetched tweets and profiles in the database."
    )
    fetch.add_argument(
        '--no-persist',
        dest='persist',
        action='store_false',
        help="Print fetched tweet and profile data without storing."
    )
    fetch.set_defaults(persist=True)

    args = parser.parse_args()

    if args.available:
        printAvailableCampaigns()
    if args.tweets:
        printCampaignsAndTweets()
    if args.search_help:
        print search.getSearchQueryHelp()

    if args.query or args.campaign:
        try:
            utilityCampaignRec = db.Campaign.byName(UTILITY_CAMPAIGN)
        except SQLObjectNotFound:
            # The campaign manager is not needed externally for creating
            # this one, since the searchQuery is best set to NULL for
            # this specific campaign and therefore can be automatic.
            utilityCampaignRec = db.Campaign(
                name=UTILITY_CAMPAIGN,
                searchQuery=None
            )

        if args.query:
            customCampaignRec = None
            query = unicode(args.query, 'utf-8')
        else:
            campaignName = args.campaign
            try:
                customCampaignRec = db.Campaign.byName(campaignName)
            except SQLObjectNotFound as e:
                raise type(e)("Use the campaign manager to create the Campaign"
                              " as name and search query. Name not found: {0}"
                              .format(campaignName))
            query = customCampaignRec.searchQuery
            assert query, "Use the Campaign Manager to set a search query"\
                          " for the campaign: {0}".format(args.campaign)

        # Process the category and campaign records above before fetching
        # data from the API.
        print u"Search query: {0}".format(query)

        # Use app auth here for up to 480 search requests per window, rather
        # than 180 when using the user auth.
        API_CONN = auth.getAppOnlyConnection()
        searchStoreAndLabel(
            query,
            args.pages, args.persist,
            utilityCampaignRec, customCampaignRec,
        )

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


<commit_before>import os

def build_hpo_dict():
    with open("hp.obo",'r') as f:
        lines = f.readlines()
        current_id = None
        current_is_a = None
        hpo_dict = {}
        current_is_a_tuple = ()
        for line in lines:
            if line.startswith("id:"):
                current_id = line.strip().split("id:")
                current_id = current_id[1].strip()
            elif line.startswith("is_a:"):
                current_is_a = line.strip().split("is_a:")
                current_is_a = current_is_a[1]
                b = current_is_a.split("!")
                current_is_a_tuple = (b[0].strip(),b[1].strip())
            if current_id is not None:
                hpo_dict[current_id]=current_is_a_tuple
        print hpo_dict
        return hpo_dict

build_hpo_dict()
<commit_msg>unfinished parsing script<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python3
# -*- coding: UTF-8 -*-
#
# This might check style & grammar one day. I'm hopeful. Kinda.

import sys, os, subprocess, shutil
from lxml import etree

openfile = False
dcfile = False
resultpath = "/tmp/"
arguments = sys.argv
location = os.path.dirname(os.path.realpath(__file__)) + '/'

if ( "--help" in arguments ) or ( "-h" in arguments ):
  sys.exit( """Usage: %s [OPTIONS] FILE

Options:
      --dc  Use a DC file as input, this will invoke DAPS to create a bigfile
    --open  Open final report in $BROWSER
 --version  Print version number
    --help  Show this screen""" % arguments[0] )

if ( "--version" in arguments ) or ( "-v" in arguments ):
  sys.exit( "Documentation Style Checker 0.1.0pre" )

if ("--open" in arguments ) or ( "-o" in arguments ):
  if ( os.environ.get('BROWSER') == None ):
    sys.exit( "Before using the --open option, do: export BROWSER=\"MY/FAVORITE/BROWSER\"" )
  openfile = True
  arguments = list(filter(('--open').__ne__, arguments))
  arguments = list(filter(('-o').__ne__, arguments))

if ("--dc" in arguments) or ( "-d" in arguments ):
  dcfile = True
  resultpath = "build/.tmp/"
  arguments = list(filter(('--dc').__ne__, arguments))
  arguments = list(filter(('-d').__ne__, arguments))

if len( arguments ) < 2:
  sys.exit( """Not enough arguments provided.
Usage: %s [OPTIONS] FILE
To see all options, do: %s --help""" % ( arguments[0], arguments[0] ) )

if not os.path.exists( arguments[-1] ):
  sys.exit( "File %s does not exist.\n" % arguments[-1] )

inputfile = arguments[-1]

if dcfile == True:
  inputfile = (subprocess.check_output( [ 'daps', '-d', arguments[-1], 'bigfile' ] )
              .decode( 'UTF-8' ) ).replace( '\n', '' )

parser = etree.XMLParser(ns_clean=True,
                         remove_pis=False,
                         dtd_validation=False)
inputfile = etree.parse( inputfile, parser )
transform = etree.XSLT( etree.parse( location + 'xsl-checks/procedure-steps.xsl', parser ) )
result = transform( inputfile )

root = result.getroot()

result.write( resultpath + 'checkresult.xml',
              xml_declaration=True,
              encoding="UTF-8",
              pretty_print=True)

shutil.copyfile( location + 'check.css', resultpath + 'checkresult.css' )

if openfile == True:
  subprocess.call( [ os.environ['BROWSER'] , resultpath + 'checkresult.xml' ] )<commit_msg>Commit WIP to construct XML on the fly<commit_after>#!/usr/bin/python3
# -*- coding: UTF-8 -*-
#
# This might check style & grammar one day. I'm hopeful. Kinda.

import sys, os, subprocess, shutil
from lxml import etree

openfile = False
dcfile = False
resultpath = "/tmp/"
arguments = sys.argv
location = os.path.dirname(os.path.realpath(__file__)) + '/'

# Handle arguments
if ( "--help" in arguments ) or ( "-h" in arguments ):
  sys.exit( """Usage: %s [OPTIONS] FILE

Options:
      --dc  Use a DC file as input, this will invoke DAPS to create a bigfile
    --open  Open final report in $BROWSER
 --version  Print version number
    --help  Show this screen""" % arguments[0] )

if ( "--version" in arguments ) or ( "-v" in arguments ):
  sys.exit( "Documentation Style Checker 0.1.0pre" )

if ("--open" in arguments ) or ( "-o" in arguments ):
  if ( os.environ.get('BROWSER') == None ):
    sys.exit( "Before using the --open option, do: export BROWSER=\"MY/FAVORITE/BROWSER\"" )
  openfile = True
  arguments = list(filter(('--open').__ne__, arguments))
  arguments = list(filter(('-o').__ne__, arguments))

if ("--dc" in arguments) or ( "-d" in arguments ):
  dcfile = True
  resultpath = "build/.tmp/"
  arguments = list(filter(('--dc').__ne__, arguments))
  arguments = list(filter(('-d').__ne__, arguments))

if len( arguments ) < 2:
  sys.exit( """Not enough arguments provided.
Usage: %s [OPTIONS] FILE
To see all options, do: %s --help""" % ( arguments[0], arguments[0] ) )

if not os.path.exists( arguments[-1] ):
  sys.exit( "File %s does not exist.\n" % arguments[-1] )

inputfile = arguments[-1]

# Some crazy DAPS integration
if dcfile == True:
  inputfile = (subprocess.check_output( [ 'daps', '-d', arguments[-1], 'bigfile' ] )
              .decode( 'UTF-8' ) ).replace( '\n', '' )

output = etree.XML('<?xml-stylesheet type="text/css" href="check.css"?><results></results>')
rootelement = output.xpath( '/results' )

# Checking via XSLT
parser = etree.XMLParser(ns_clean=True,
                         remove_pis=False,
                         dtd_validation=False)
inputfile = etree.parse( inputfile, parser )
transform = etree.XSLT( etree.parse( location + 'xsl-checks/procedure-steps.xsl', parser ) )
result = transform( inputfile ).getroot()

print(rootelement[0])

if not result == None:
  output = rootelement[0].append(result)
print(output)

# output.getroottree().write( resultpath + 'checkresult.xml',
#               xml_declaration=True,
#               encoding="UTF-8",
#               pretty_print=True)

# shutil.copyfile( location + 'check.css', resultpath + 'checkresult.css' )

# if openfile == True:
#   subprocess.call( [ os.environ['BROWSER'] , resultpath + 'checkresult.xml' ] )<|endoftext|>


<commit_before>"""
Glue code between nsloaders and Mybuild bindings for py/my DSL files.
"""

__author__ = "Eldar Abusalimov"
__date__ = "2013-08-07"

from _compat import *

from nsloader import myfile
from nsloader import pyfile

from mybuild.binding import mydsl
from mybuild.binding import pydsl

class MyDslLoader(myfile.MyFileLoader):

    FILENAME = 'Mybuild'

    @property
    def defaults(self):
        return dict(super(MyDslLoader, self).defaults,
                    module=mydsl.module,
                    option=mydsl.option)

class PyDslLoader(pyfile.PyFileLoader):

    FILENAME = 'Pybuild'

    @property
    def defaults(self):
        return dict(super(PyDslLoader, self).defaults,
                    module=pydsl.module,
                    option=pydsl.option)

<commit_msg>glue: avoid code duplication, first draft of CC tool<commit_after>"""
Glue code between nsloaders and Mybuild bindings for py/my DSL files.
"""

__author__ = "Eldar Abusalimov"
__date__ = "2013-08-07"

from _compat import *

from nsloader import myfile
from nsloader import pyfile

import mybuild
from mybuild.binding import mydsl
from mybuild.binding import pydsl

from util.operator import attr
from util.prop import cumulative_mapping_property

class LoaderMixin(object):

    dsl = None

    @property
    def defaults(self):
        return dict(super(LoaderMixin, self).defaults,
                    module  = self.dsl.module,
                    project = self.dsl.project,
                    option  = self.dsl.option,
                    tool=tool,
                    MYBUILD_VERSION=mybuild.__version__)

class MyDslLoader(LoaderMixin, myfile.MyFileLoader):
    FILENAME = 'Mybuild'
    dsl = mydsl

class PyDslLoader(LoaderMixin, pyfile.PyFileLoader):
    FILENAME = 'Pybuild'
    dsl = pydsl

class NsObject(object):
    """docstring for NsObject"""

    def __init__(self, dict_={}, **kwargs):
        super(NsObject, self).__init__()
        self.__dict__.update(dict_, **kwargs)

class RoNsObject(NsObject):
    """docstring for RoNsObject"""

    def __setattr__(self, attr, value):
        raise AttributeError
    def __delattr__(self, attr):
        raise AttributeError

class WafBasedTool(mybuild.core.Tool):
    waf_tools = []

    def options(self, module, ctx):
        ctx.load(self.waf_tools)
    def configure(self, module, ctx):
        ctx.load(self.waf_tools)

class CcNs(NsObject):
    defines = cumulative_mapping_property(attr.__defines)

class CcTool(WafBasedTool):
    waf_tools = ['compiler_c']

    def create_namespaces(self, module):
        return dict(cc=CcNs())

    def build(self, module, ctx):
        for name, value in iteritems(module.cc.defines):
            ctx.define(name, value)
        ctx.program(source=module.files, target=module._name)

tool = NsObject(cc=CcTool())

<|endoftext|>


<commit_before>import sys
from appvalidator import validate_app, validate_packaged_app

path = sys.argv[1]
if path.endswith(".webapp"):
    print validate_app(path, format="json")
else:
    print validate_packaged_app(path, format="json")
<commit_msg>Remove grizwald back-end<commit_after><|endoftext|>