<commit_before>from abc import ABCMeta, abstractmethod, abstractproperty
from sorl.thumbnail.conf import settings
from sorl.thumbnail.storage import ImageFile
from sorl.thumbnail.helpers import get_module_class, tokey
from sorl.thumbnail.helpers import serialize, deserialize
from sorl.thumbnail.parsers import parse_geometry

THUMBNAILS_KEY_SUFFIX = 'thumbnails'

def prefix_key(key):
    """
    Adds a prefix to the key
    """
    return '%s%s' % (settings.THUMBNAIL_KEY_PREFIX, key)

class ThumbnailBackendBase(object):
    __metaclass__ = ABCMeta

    default_options = {
        'format': settings.THUMBNAIL_FORMAT,
        'quality': settings.THUMBNAIL_QUALITY,
        'colorspace': settings.THUMBNAIL_COLORSPACE,
        'upscale': settings.THUMBNAIL_UPSCALE,
        'crop': False,
    }

    extensions = {
        'JPEG': 'jpg',
        'PNG': 'png',
    }

    def __init__(self, engine=None, storage=None):
        if engine is None:
            engine = get_module_class(settings.THUMBNAIL_ENGINE)()
        if storage is None:
            storage = get_module_class(settings.THUMBNAIL_STORAGE)()
        self.engine = engine
        self.storage = storage

    def get_thumbnail(self, file_, geometry_string, options):
        source = ImageFile(file_)
        for key, value in self.default_options.iteritems():
            options.setdefault(key, value)

        name = self._get_thumbnail_filename(source, geometry_string, options)
        thumbnail = ImageFile(name, self.storage)
        if not self.store_get(thumbnail):
            if not thumbnail.exists():
                self._create_thumbnail(source, geometry_string, options,
                                       thumbnail)
            # If the thumbnail exists we don't do anything, the other option is
            # to delete and write but this could lead to race conditions so I
            # will just leave that out for now.
            self.store_set(thumbnail, source)
        return thumbnail

    def _create_thumbnail(self, source, geometry_string, options, thumbnail):
        image = self.engine.get_image(source)
        image_size = self.engine.get_image_size(image)
        geometry = parse_geometry(geometry_string, image_size)
        thumbnail_image = self.engine.create(image, geometry, options)
        self.engine.write(thumbnail_image, options, thumbnail)
        # its much cheaper to set the size here since we probably have the
        # image in memory
        thumbnail.size = self.engine.get_image_size(thumbnail_image)

    def _get_thumbnail_filename(self, source, geometry_string, options):
        """
        Computes the destination filename.
        """
        key = tokey(source.name, source.storage_path, geometry_string,
                    serialize(options))
        # make some subdirs
        path = '%s/%s/%s' % (key[:2], key[2:4], key)
        return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path,
                            self.extensions[options['format']])

    @abstractmethod
    def _store_get_raw(self, key):
        pass

    @abstractmethod
    def _store_set_raw(self, key, value):
        pass

    @abstractmethod
    def _store_delete_raw(self, key):
        pass

    def _store_get(self, key):
        """
        Deserializing, prefix wrapper for ThumbnailBackendBase._store_get_raw
        """
        value = self._store_get(prefix_key(key))
        if value is None:
            return None
        return deserialize(value)

    def _store_set(self, key, value):
        """
        Serializing, prefix wrapper for ThumbnailBackendBase._store_set_raw
        """
        self._store_set(prefix_key(key), serialize(value))

    def _store_delete(self, key):
        """
        Prefix wrapper for ThumbnailBackendBase._store_delete_raw
        """
        self._store_delete_raw(prefix_key(key))

    def store_get(self, image_file):
        value = self._store_get(image_file.key)
        if value is None:
            return False
        image_file.size = value
        return True

    def store_set(self, image_file, source=None):
        if source is not None:
            # update the list of thumbnails for source
            key = tokey(source.key, THUMBNAILS_KEY_SUFFIX)
            thumbnails = self._store_get(key) or []
            if image_file.name not in thumbnails:
                thumbnails.append(image_file.name)
            self._store_set(key, thumbnails)
        # now set store for the image_file and make sure it's got a size
        if image_file.size is None:
            if hasattr(image_file.storage, 'image_size'):
                image_file.size = image_file.storage.image_size(self.name)
            else:
                # This is the worst case scenario
                image = self.engine.get_image(self)
                image_file.size = self.engine.get_image_size(image)
        self._store_set(image_file.key, image_file.size)

    def store_delete(self, image_file, delete_thumbnails=True):
        if delete_thumbnails:
            key = tokey(image_file.key, THUMBNAILS_KEY_SUFFIX)
            thumbnails = self._store_get(key)
            if thumbnails:
                # Delete all thumbnail keys from store and delete the
                # ImageFiles
                for name in thumbnails:
                    thumbnail = ImageFile(name, self.storage)
                    self._store_delete(thumbnail.key)
                    thumbnail.delete()
            # Delete the thumbnails key from store
            self._store_delete(key)
        self._store_delete(image_file.key)

<commit_msg>threading avaoiding...<commit_after>from abc import ABCMeta, abstractmethod, abstractproperty
from sorl.thumbnail.conf import settings
from sorl.thumbnail.storage import ImageFile
from sorl.thumbnail.helpers import get_module_class, tokey
from sorl.thumbnail.helpers import serialize, deserialize
from sorl.thumbnail.parsers import parse_geometry

THUMBNAILS_KEY_SUFFIX = 'thumbnails'

def prefix_key(key):
    """
    Adds a prefix to the key
    """
    return '%s%s' % (settings.THUMBNAIL_KEY_PREFIX, key)

class ThumbnailBackendBase(object):
    __metaclass__ = ABCMeta

    default_options = {
        'format': settings.THUMBNAIL_FORMAT,
        'quality': settings.THUMBNAIL_QUALITY,
        'colorspace': settings.THUMBNAIL_COLORSPACE,
        'upscale': settings.THUMBNAIL_UPSCALE,
        'crop': False,
    }

    extensions = {
        'JPEG': 'jpg',
        'PNG': 'png',
    }

    def __init__(self, engine=None, storage=None):
        if engine is None:
            engine = get_module_class(settings.THUMBNAIL_ENGINE)()
        if storage is None:
            storage = get_module_class(settings.THUMBNAIL_STORAGE)()
        self.engine = engine
        self.storage = storage

    def get_thumbnail(self, file_, geometry_string, options):
        source = ImageFile(file_)
        for key, value in self.default_options.iteritems():
            options.setdefault(key, value)

        name = self._get_thumbnail_filename(source, geometry_string, options)
        thumbnail = ImageFile(name, self.storage)
        if not self.store_get(thumbnail):
            if not thumbnail.exists():
                self._create_thumbnail(source, geometry_string, options,
                                       thumbnail)
            # If the thumbnail exists we don't do anything, the other option is
            # to delete and write but this could lead to race conditions so I
            # will just leave that out for now.
            self.store_set(thumbnail, source)
        return thumbnail

    def _create_thumbnail(self, source, geometry_string, options, thumbnail):
        image = self.engine.get_image(source)
        image_size = self.engine.get_image_size(image)
        geometry = parse_geometry(geometry_string, image_size)
        thumbnail_image = self.engine.create(image, geometry, options)
        self.engine.write(thumbnail_image, options, thumbnail)
        # its much cheaper to set the size here since we probably have the
        # image in memory
        thumbnail.size = self.engine.get_image_size(thumbnail_image)

    def _get_thumbnail_filename(self, source, geometry_string, options):
        """
        Computes the destination filename.
        """
        key = tokey(source.name, source.storage_path, geometry_string,
                    serialize(options))
        # make some subdirs
        path = '%s/%s/%s' % (key[:2], key[2:4], key)
        return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path,
                            self.extensions[options['format']])

    @abstractmethod
    def _store_get_raw(self, key):
        pass

    @abstractmethod
    def _store_set_raw(self, key, value):
        pass

    @abstractmethod
    def _store_delete_raw(self, key):
        pass

    def _store_get(self, key):
        """
        Deserializing, prefix wrapper for ThumbnailBackendBase._store_get_raw
        """
        value = self._store_get(prefix_key(key))
        if value is None:
            return None
        return deserialize(value)

    def _store_set(self, key, value):
        """
        Serializing, prefix wrapper for ThumbnailBackendBase._store_set_raw
        """
        self._store_set(prefix_key(key), serialize(value))

    def _store_delete(self, key):
        """
        Prefix wrapper for ThumbnailBackendBase._store_delete_raw
        """
        self._store_delete_raw(prefix_key(key))

    def store_get(self, image_file):
        value = self._store_get(image_file.key)
        if value is None:
            return False
        image_file.size = value
        return True

    def store_set(self, image_file, source=None):
        if source is not None:
            # update the list of thumbnails for source
            key = tokey(source.key, THUMBNAILS_KEY_SUFFIX)
            thumbnails = self._store_get(key) or []
            if image_file.name not in thumbnails:
                thumbnails.append(image_file.name)
            self._store_set(key, thumbnails)
        # now set store for the image_file and make sure it's got a size
        if image_file.size is None:
            if hasattr(image_file.storage, 'image_size'):
                image_file.size = image_file.storage.image_size(self.name)
            else:
                # This is the worst case scenario
                image = self.engine.get_image(self)
                image_file.size = self.engine.get_image_size(image)
        self._store_set(image_file.key, image_file.size)
        return True

    def store_delete(self, image_file, delete_thumbnails=True):
        if delete_thumbnails:
            key = tokey(image_file.key, THUMBNAILS_KEY_SUFFIX)
            thumbnails = self._store_get(key)
            if thumbnails:
                # Delete all thumbnail keys from store and delete the
                # ImageFiles
                for name in thumbnails:
                    thumbnail = ImageFile(name, self.storage)
                    self._store_delete(thumbnail.key)
                    thumbnail.delete()
            # Delete the thumbnails key from store
            self._store_delete(key)
        self._store_delete(image_file.key)
        return True

<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Copyright 2016 BMC Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import apachelog
import os
import sys
from log_utils import LogfileParser, parse_apache_line
from tspapi import API
from tspapi import Measurement

class ApacheLogfileParser(LogfileParser):
    def __init__(self, path=None):
        super(ApacheLogfileParser, self).__init__(path)
        log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
        self.parser = apachelog.parser(log_format)
        self.api = API()

    def send_measurements(self, measurements):
        """
        Sends measurements to standard out to be read by plugin manager

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def parse_line(self):
        """
        Parse each of the lines of the Apache HTTP server access log.
        :return:
        """
        parsed = parse_apache_line(self.parser, self.line)
        measurements = []
        user_agent = parsed['%{User-Agent}\i"']
        bytes = int(parsed['%b'])
        status_code = parsed['%>s']
        properties = {"appl_id", self.appl_id}
        # Split the line by spaces and get the request in the first value
        request = parsed['%r'].split(' ')[0]
        print("user_agent: {0}, bytes: {1}, request: {2}, status_code: {3}".format(
                user_agent, bytes, request, status_code))

        measurements.append(Measurement(
                metric='HTTP_REQUESTS',
                value=1, source=request,
                properties=properties))
        measurements.append(Measurement(
                metric='HTTP_BYTES',
                value=bytes,
                source=user_agent,
                properties=properties))
        self.send_measurements(measurements)

        if __name__ == '__main__':
            if len(sys.argv) == 2:
                parser = ApacheLogfileParser(path=sys.argv[1])
                parser.monitor_file()
            else:
                sys.stderr.write("{0}".format(os.path.basename(sys.argv[0])))
<commit_msg>Incorrect variable for app id ; fixed main identation<commit_after>#!/usr/bin/env python
#
# Copyright 2016 BMC Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import apachelog
import os
import sys
from log_utils import LogfileParser, parse_apache_line
from tspapi import API
from tspapi import Measurement

class ApacheLogfileParser(LogfileParser):
    def __init__(self, path=None):
        super(ApacheLogfileParser, self).__init__(path)
        log_format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}\i"'
        self.parser = apachelog.parser(log_format)
        self.api = API()

    def send_measurements(self, measurements):
        """
        Sends measurements to standard out to be read by plugin manager

        :param measurements:
        :return: None
        """
        self.api.measurement_create_batch(measurements)

    def parse_line(self):
        """
        Parse each of the lines of the Apache HTTP server access log.
        :return:
        """
        parsed = parse_apache_line(self.parser, self.line)
        measurements = []
        user_agent = parsed['%{User-Agent}\i"']
        bytes = int(parsed['%b'])
        status_code = parsed['%>s']
        properties = {"app_id", self.app_id}
        # Split the line by spaces and get the request in the first value
        request = parsed['%r'].split(' ')[0]
        print("user_agent: {0}, bytes: {1}, request: {2}, status_code: {3}".format(
                user_agent, bytes, request, status_code))

        measurements.append(Measurement(
                metric='HTTP_REQUESTS',
                value=1, source=request,
                properties=properties))
        measurements.append(Measurement(
                metric='HTTP_BYTES',
                value=bytes,
                source=user_agent,
                properties=properties))
        self.send_measurements(measurements)

if __name__ == '__main__':
    if len(sys.argv) == 2:
        parser = ApacheLogfileParser(path=sys.argv[1])
        parser.monitor_file()
    else:
        sys.stderr.write("usage: {0} path\n".format(os.path.basename(sys.argv[0])))
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: Frede Hundewadt <echo "ZmhAdWV4LmRrCg==" | base64 -d>
# Copyright: Frede Hundewadt <echo "ZmhAdWV4LmRrCg==" | base64 -d>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html

"""Sqlite Query Module"""

import sqlite3

from configuration import config
from models.builders.build_create_query import build_create_query
from models.builders.build_delete_query import build_delete_query
from models.builders.build_drop_query import build_drop_query
from models.builders.build_insert_query import build_insert_query
from models.builders.build_select_query import build_select_query
from models.builders.build_update_query import build_update_query

class Query:
    """
    Query Build and Execute
    """

    @staticmethod
    def build(query_type, model_def, selection=None, update=None, aggregates=None, filters=None, orderby=None):
        """
        Builds a sql query from definition

        Args:
            query_type: create(table), drop(table), insert(row), select(row), update(row), delete(row))

            model_def: table model definition
            {"name": ("name" ...), "fields": ("field" ...), "types": ("INTEGER PRIMARY KEY NOT NULL", "TEXT" ...)}

            selection: limit the result to selection

            update: fields to update
            ("field", "field" ...)

            aggregates: valid ["sum(column) AS 'expression'", "sum(column) AS 'expression'" ....]

            filters:  valid for all-, required for update- and delete query
            [("field", "operator", "value", "and/or"), (("field", "operator", "value"))]]

            orderby: asc or desc

        Returns:
            string with sql query

        """

        querytype = query_type.upper()
        if querytype not in ["CREATE", "DELETE", "DROP", "INSERT", "SELECT", "UPDATE"]:
            return "ERROR! Unsupported type: {}, {}".format(querytype, model_def["name"])

        if querytype == ["DELETE"]:
            if not filters:
                return "ERROR! Missing 'filters' for: {}, {}".format(querytype, model_def["name"])

        if querytype == ["UPDATE"]:
            if not filters or not update:
                return "ERROR! Missing 'update' or 'filters' for: {}, {}".format(querytype, model_def["name"])

        if orderby:
            orderby = orderby[1].upper()
            if not orderby == "ASC" or not orderby == "DESC":
                orderby = None

        # build init_detail table query
        if querytype == "CREATE":
            return build_create_query(model_def)

        # build delete row query
        if querytype == "DELETE":
            return build_delete_query(model_def, filters)

        # builds drop table query
        if querytype == "DROP":
            return build_drop_query(model_def)

        # build insert row query
        if querytype == "INSERT":
            return build_insert_query(model_def)

        # build all row query
        if querytype == "SELECT":
            return build_select_query(model_def, selection, aggregates, filters, orderby)

        # build update row query
        if querytype == "UPDATE":
            return build_update_query(model_def, update, filters)

    @staticmethod
    def execute(sql_query, values=None):
        """
        Execute a query and return the result
        Args:
            sql_query:
            values:
        Returns:
            list with result of the query - may be an empty list
        """
        # query types: create, drop, delete, insert, select, update
        # specifically the select and insert query has to return the result
        select = sql_query.startswith("SELECT")  # returns data
        insert = sql_query.startswith("INSERT")  # returns rowid for the last inserted record
        db = sqlite3.connect(config.DBPATH)
        with db:
            try:
                result = None
                cur = db.cursor()
                if values:
                    cur.execute(sql_query, values)
                else:
                    cur.execute(sql_query)
                db.commit()
                if select:
                    result = cur.fetchall()
                if insert:
                    result = cur.lastrowid
            except (sqlite3.OperationalError, sqlite3.ProgrammingError) as e:
                return False, e
        return True, result

    @staticmethod
    def values_to_update(values):
        """
        Moves the id field from first to last element for passing to sql update
        Args:
            values:

        Returns:
            Value list with id as the last field
        """
        work = list(values)
        rowid = work[0]
        work = work[1:]
        work.append(rowid)
        work = tuple(work)
        return work

    def exist_table(self, table):
        """
        Check database if tablename exist
        Args:
            table:

        Returns:
             bool indicating if table was found
        """
        statement = "SELECT name FROM sqlite_master WHERE type='{}' AND name='{}';".format("table", table)

        success, data = self.execute(statement)
        if data:
            return True
        return False
<commit_msg>code cleanup<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: Frede Hundewadt <echo "ZmhAdWV4LmRrCg==" | base64 -d>
# Copyright: Frede Hundewadt <echo "ZmhAdWV4LmRrCg==" | base64 -d>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html

"""Sqlite Query Module"""

import sqlite3

from configuration import config
from models.builders.build_create_query import build_create_query
from models.builders.build_delete_query import build_delete_query
from models.builders.build_drop_query import build_drop_query
from models.builders.build_insert_query import build_insert_query
from models.builders.build_select_query import build_select_query
from models.builders.build_update_query import build_update_query

__module__ = "query"

class Query:
    """
    Query Build and Execute
    """

    @staticmethod
    def build(query_type, model_def, selection=None, update=None, aggregates=None, filters=None, orderby=None):
        """
        Builds a sql query from definition

        Args:
            query_type: create(table), drop(table), insert(row), select(row), update(row), delete(row))

            model_def: table model definition
            {"name": ("name" ...), "fields": ("field" ...), "types": ("INTEGER PRIMARY KEY NOT NULL", "TEXT" ...)}

            selection: limit the result to selection

            update: fields to update
            ("field", "field" ...)

            aggregates: valid ["sum(column) AS 'expression'", "sum(column) AS 'expression'" ....]

            filters:  valid for all-, required for update- and delete query
            [("field", "operator", "value", "and/or"), (("field", "operator", "value"))]]

            orderby: asc or desc

        Returns:
            string with sql query

        """

        querytype = query_type.upper()
        if querytype not in ["CREATE", "DELETE", "DROP", "INSERT", "SELECT", "UPDATE"]:
            return "ERROR! Unsupported type: {}, {}".format(querytype, model_def["name"])

        if querytype == ["DELETE"]:
            if not filters:
                return "ERROR! Missing 'filters' for: {}, {}".format(querytype, model_def["name"])

        if querytype == ["UPDATE"]:
            if not filters or not update:
                return "ERROR! Missing 'update' or 'filters' for: {}, {}".format(querytype, model_def["name"])

        if orderby:
            orderby = orderby[1].upper()
            if not orderby == "ASC" or not orderby == "DESC":
                orderby = None

        # build init_detail table query
        if querytype == "CREATE":
            return build_create_query(model_def)

        # build delete row query
        if querytype == "DELETE":
            return build_delete_query(model_def, filters)

        # builds drop table query
        if querytype == "DROP":
            return build_drop_query(model_def)

        # build insert row query
        if querytype == "INSERT":
            return build_insert_query(model_def)

        # build all row query
        if querytype == "SELECT":
            return build_select_query(model_def, selection, aggregates, filters, orderby)

        # build update row query
        if querytype == "UPDATE":
            return build_update_query(model_def, update, filters)

    @staticmethod
    def execute(sql_query, values=None):
        """
        Execute a query and return the result
        Args:
            sql_query:
            values:
        Returns:
            list with result of the query - may be an empty list
        """
        # query types: create, drop, delete, insert, select, update
        # specifically the select and insert query has to return the result
        select = sql_query.startswith("SELECT")  # returns data
        insert = sql_query.startswith("INSERT")  # returns rowid for the last inserted record
        db = sqlite3.connect(config.DBPATH)
        with db:
            try:
                result = None
                cur = db.cursor()
                if values:
                    cur.execute(sql_query, values)
                else:
                    cur.execute(sql_query)
                db.commit()
                if select:
                    result = cur.fetchall()
                if insert:
                    result = cur.lastrowid
            except (sqlite3.OperationalError, sqlite3.ProgrammingError) as e:
                return False, e
        return True, result

    @staticmethod
    def values_to_update(values):
        """
        Moves the id field from first to last element for passing to sql update
        Args:
            values:

        Returns:
            Value list with id as the last field
        """
        work = list(values)
        rowid = work[0]
        work = work[1:]
        work.append(rowid)
        work = tuple(work)
        return work

    def exist_table(self, table):
        """
        Check database if tablename exist
        Args:
            table:

        Returns:
             bool indicating if table was found
        """
        statement = "SELECT name FROM sqlite_master WHERE type='{}' AND name='{}';".format("table", table)

        success, data = self.execute(statement)
        if data:
            return True
        return False
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2010-2012 OpenERP SA (<http://openerp.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import logging
import simplejson

import openerp
from openerp.osv import osv, fields

_logger = logging.getLogger(__name__)

class res_users(osv.Model):
    _inherit = 'res.users'

    def _auth_oauth_signin(self, cr, uid, provider, validation, params, context=None):
        # overridden to use signup method if regular oauth signin fails
        try:
            login = super(res_users, self)._auth_oauth_signin(cr, uid, provider, validation, params, context=context)

        except openerp.exceptions.AccessDenied:
            if context and context.get('no_user_creation'):
                return None
            state = simplejson.loads(params['state'])
            token = state.get('t')
            oauth_uid = validation['user_id']
            email = validation.get('email', 'provider_%d_user_%d' % (provider, oauth_uid))
            name = validation.get('name', email)
            values = {
                'name': name,
                'login': email,
                'email': email,
                'oauth_provider_id': provider,
                'oauth_uid': oauth_uid,
                'oauth_access_token': params['access_token'],
                'active': True,
            }
            _, login, _ = self.signup(cr, uid, values, token, context=context)

        return login
<commit_msg>[FIX] auth_oauth_signup: allow non-numeric OAuth User ID, for e.g. compatibility with Google OAuth<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2010-2012 OpenERP SA (<http://openerp.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import logging
import simplejson

import openerp
from openerp.osv import osv, fields

_logger = logging.getLogger(__name__)

class res_users(osv.Model):
    _inherit = 'res.users'

    def _auth_oauth_signin(self, cr, uid, provider, validation, params, context=None):
        # overridden to use signup method if regular oauth signin fails
        try:
            login = super(res_users, self)._auth_oauth_signin(cr, uid, provider, validation, params, context=context)

        except openerp.exceptions.AccessDenied:
            if context and context.get('no_user_creation'):
                return None
            state = simplejson.loads(params['state'])
            token = state.get('t')
            oauth_uid = validation['user_id']
            email = validation.get('email', 'provider_%s_user_%s' % (provider, oauth_uid))
            name = validation.get('name', email)
            values = {
                'name': name,
                'login': email,
                'email': email,
                'oauth_provider_id': provider,
                'oauth_uid': oauth_uid,
                'oauth_access_token': params['access_token'],
                'active': True,
            }
            _, login, _ = self.signup(cr, uid, values, token, context=context)

        return login
<|endoftext|>


<commit_before>import os

from testtools import TestCase
from testtools.matchers import Contains
from . import makeprefs, _temp_home
from mock import MagicMock, Mock, patch
from StringIO import StringIO
from contextlib import nested

class CommandTest(TestCase):
    def setUp(self):
        super(CommandTest, self).setUp()
        self.prefs = makeprefs()
        self.home = os.path.join('t', 'data', 'home')

    def tearDown(self):
        super(CommandTest, self).tearDown()

    def _makeit(self, *args, **kwargs):
        from lacli.main import LaCommand
        return LaCommand(*args, **kwargs)

    def _makeupload(self, *args, **kwargs):
        return Mock(upload=Mock(**kwargs))

    def test_command(self):
        assert self._makeit(Mock(), Mock(), self.prefs)

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_with_title(self, mock_stdout):
        cache = Mock(prepare=Mock(return_value='True'))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create {} -t baz'.format(self.home))
        cache.prepare.assert_called_with("baz", self.home)
        self.assertThat(mock_stdout.getvalue(),
                        Contains('archive prepared'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_exception(self, mock_stdout):
        cache = Mock(prepare=Mock(side_effect=Exception("foo")))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create {} -t baz'.format(self.home))
        self.assertThat(mock_stdout.getvalue(),
                        Contains('error: foo'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_unexist(self, mock_stdout):
        cli = self._makeit(Mock(), Mock(), self.prefs)
        cli.onecmd('archive create /tmp/doesnotexistisay')
        self.assertEqual('The specified folder does not exist.\n',
                         mock_stdout.getvalue())

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_none(self, out):
        cache = Mock(archives=Mock(return_value=[]))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertEqual('No available archives.\n', out.getvalue())

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_some(self, out):
        from lacli.adf import Archive, Meta
        meta = Meta(format='', size=None, cipher='')
        cache = Mock(archives=Mock(return_value=[Archive(
            title="foo", description='', tags=[], meta=meta)]))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertThat(out.getvalue(),
                        Contains('Prepared archives:\n1) foo'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_verbose(self, out):
        from lacli.adf import Archive, Meta
        meta = Meta(format='', size=None, cipher='')
        cache = Mock(archives=Mock(return_value=[Archive(
            title="foo", description='', tags=[], meta=meta)]))
        prefs = self.prefs
        prefs['command']['verbose'] = True
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertThat(out.getvalue(),
                        Contains('!archive'))

    def test_do_archive_list_more(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            for size in [(25, '25B'), (1024, '1KiB'), (2000000, '1MiB')]:
                from lacli.adf import Archive, Meta
                meta = Meta(format='', size=size[0], cipher='')
                cache = Mock(archives=Mock(return_value=[Archive(
                    title="foo", description='', tags=[], meta=meta)]))
                cli = self._makeit(Mock(), cache, self.prefs)
                cli.onecmd('archive create')
                self.assertThat(out.getvalue(),
                                Contains('Prepared archives:\n1) foo [//'
                                         + size[1]))

    @patch('sys.stdin', new_callable=StringIO)
    def test_loop_none(self, mock_stdin):
        cli = self._makeit(Mock(), Mock, self.prefs)
        cli.cmdloop()

    def test_do_status_error(self):
        from lacli.cache import Cache
        with _temp_home() as home:
            cli = self._makeit(Mock(), Cache(home), self.prefs)
            with patch('sys.stdout', new_callable=StringIO) as out:
                cli.onecmd('archive list')
                self.assertThat(out.getvalue(),
                                Contains('No available archives'))
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive status foobar')
            self.assertThat(out.getvalue(),
                            Contains('error: invalid value'))
        apisession = Mock()
        apisession.upload_status.side_effect = Exception('foo')
        cli = self._makeit(apisession, Cache(self.home), self.prefs)
        with nested(
            patch('sys.stdout', new_callable=StringIO),
            patch('lacli.command.urlparse'),
                ) as (out, urlparse):
            uploads = cli.archive.cache._for_adf('archives')
            urlparse.return_value = Mock(scheme='gopher', path=self.home)
            for seq, archive in enumerate(uploads.itervalues()):
                    if archive['archive'].title == 'My pending upload':
                        cli.onecmd('archive status {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('error:'))

    def test_do_status(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive status')
            self.assertThat(out.getvalue(),
                            Contains('Usage:'))

    def test_do_put_error(self):
        from lacli.cache import Cache
        with _temp_home() as home:
            cli = self._makeit(Mock(), Cache(home), self.prefs)
            with patch('sys.stdout', new_callable=StringIO) as out:
                cli.onecmd('archive upload')
                self.assertThat(out.getvalue(),
                                Contains('No such archive'))
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive upload foobar')
            self.assertThat(out.getvalue(),
                            Contains('No such archive'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            for seq, archive in enumerate(cli.archive.cache.archives()):
                if archive.title == 'My 2013 vacation':
                    cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('File /path/to/archive not found.'))

    def test_do_put_not_found(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        cli.archive.cache.links = Mock(return_value={})
        with patch('sys.stdout', new_callable=StringIO) as out:
            for seq, archive in enumerate(cli.archive.cache.archives()):
                if archive.title == 'My 2013 vacation':
                    cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(), Contains('no local copy exists'))

    def test_do_put_not_local(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='gopher', path=self.home)
                for seq, archive in enumerate(cli.archive.cache.archives()):
                    if archive.title == 'My 2013 vacation':
                        cli.onecmd('archive upload {}'.format(seq+1))
                self.assertThat(out.getvalue(), Contains('url not local'))
                urlparse.assert_called_with('file:///path/to/archive')

    def test_do_put_done(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            from lacli.cache import Cache
            upload = MagicMock()
            upload.__enter__.return_value = {
                'uri': 'http://foo.com',
                'id': '1',
                'tokens': Mock()
            }
            with patch.object(Cache, 'save_upload'):
                cli = self._makeit(Mock(upload=Mock(return_value=upload)),
                                   Cache(self.home),
                                   self.prefs,
                                   self._makeupload())
                cli.archive._var['capsule'] = 1
                with patch('lacli.command.urlparse') as urlparse:
                    urlparse.return_value = Mock(scheme='file', path=self.home)
                    archives = cli.archive.cache.archives()
                    for seq, archive in enumerate(archives):
                        if archive.title == 'My 2013 vacation':
                            cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(), Contains('done'))

    def test_do_put_exception(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            from lacli.cache import Cache
            upload = MagicMock()
            upload.__enter__.return_value = {
                'uri': 'http://foo.com',
                'id': '1',
                'tokens': Mock()
            }
            cli = self._makeit(Mock(upload=Mock(return_value=upload)),
                               Cache(self.home), self.prefs,
                               self._makeupload(side_effect=Exception))
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='file', path=self.home)
                for seq, archive in enumerate(cli.archive.cache.archives()):
                    if archive.title == 'My 2013 vacation':
                        cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('error:'))

    def test_do_restore_none(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache = Mock(archives=Mock(return_value=[]))
            cli = self._makeit(Mock(), cache, self.prefs, Mock())
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('No such archive'))
            cli.onecmd('archive restore 1')
            self.assertThat(out.getvalue(), Contains('No such archive'))
            cli.onecmd('archive restore foobar')
            self.assertThat(out.getvalue(), Contains('No such archive'))

    @patch('lacli.command.restore_archive')
    def test_do_restore(self, restore_archive):
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache = Mock(archives=Mock(return_value=[Mock(title='foo')]),
                         certs=Mock(return_value={}),
                         links=Mock(return_value={}))
            cli = self._makeit(Mock(), cache, self.prefs, Mock())
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(),
                            Contains('no matching certificate found'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.certs.return_value = {'foo': 'cert'}
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('no local copy exists'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='gopher', path=self.home)
                cli.onecmd('archive restore')
                self.assertThat(out.getvalue(), Contains('url not local'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('archive restored'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.archive._var['output_directory'] = 'foo'
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('archive restored'))
            args, kwargs = restore_archive.call_args
            a, p, cert, o, c, cb = args
            self.assertEqual('cert', cert)
            self.assertEqual('/path', p)
            self.assertEqual('foo', o)
            cb("foo")
            self.assertThat(out.getvalue(), Contains("Extracting foo"))
        with patch('sys.stdout', new_callable=StringIO) as out:
            restore_archive.side_effect = Exception("foo")
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.archive._var['output_directory'] = 'foo'
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('error: foo'))

    def test_do_list_exception(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(side_effect=Exception("foo")))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            self.assertEqual("error: foo\n", out.getvalue())

    def test_list_capsules(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(return_value=()))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            self.assertEqual("No available capsules.\n", out.getvalue())

    def test_list_capsules_some(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(return_value=({'title': 'foo', 'a': 'b'},)))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            r = '''\
Available capsules:
title     :       foo
a         :         b

'''
            self.assertEqual(r, out.getvalue())

    @patch('sys.stdin', new_callable=StringIO)
    def test_do_archive(self, mock_stdin):
        cli = self._makeit(Mock(), Mock, self.prefs)
        cli.onecmd('archive')
<commit_msg>more unit test fixes<commit_after>import os

from testtools import TestCase
from testtools.matchers import Contains
from . import makeprefs, _temp_home
from mock import MagicMock, Mock, patch
from StringIO import StringIO
from contextlib import nested

class CommandTest(TestCase):
    def setUp(self):
        super(CommandTest, self).setUp()
        self.prefs = makeprefs()
        self.home = os.path.join('t', 'data', 'home')

    def tearDown(self):
        super(CommandTest, self).tearDown()

    def _makeit(self, *args, **kwargs):
        from lacli.main import LaCommand
        return LaCommand(*args, **kwargs)

    def _makeupload(self, *args, **kwargs):
        return Mock(upload=Mock(**kwargs))

    def test_command(self):
        assert self._makeit(Mock(), Mock(), self.prefs)

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_with_title(self, mock_stdout):
        cache = Mock(prepare=Mock(return_value='True'))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create {} -t baz'.format(self.home))
        cache.prepare.assert_called_with("baz", self.home)
        self.assertThat(mock_stdout.getvalue(),
                        Contains('archive prepared'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_exception(self, mock_stdout):
        cache = Mock(prepare=Mock(side_effect=Exception("foo")))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create {} -t baz'.format(self.home))
        self.assertThat(mock_stdout.getvalue(),
                        Contains('error: foo'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_unexist(self, mock_stdout):
        cli = self._makeit(Mock(), Mock(), self.prefs)
        cli.onecmd('archive create /tmp/doesnotexistisay')
        self.assertEqual('The specified folder does not exist.\n',
                         mock_stdout.getvalue())

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_none(self, out):
        cache = Mock(archives=Mock(return_value=[]))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertEqual('No available archives.\n', out.getvalue())

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_some(self, out):
        from lacli.adf import Archive, Meta
        meta = Meta(format='', size=None, cipher='')
        cache = Mock(archives=Mock(return_value=[Archive(
            title="foo", description='', tags=[], meta=meta)]))
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertThat(out.getvalue(),
                        Contains('Prepared archives:\n1) foo'))

    @patch('sys.stdout', new_callable=StringIO)
    def test_do_archive_list_verbose(self, out):
        from lacli.adf import Archive, Meta
        meta = Meta(format='', size=None, cipher='')
        cache = Mock(archives=Mock(return_value=[Archive(
            title="foo", description='', tags=[], meta=meta)]))
        prefs = self.prefs
        prefs['command']['verbose'] = True
        cli = self._makeit(Mock(), cache, self.prefs)
        cli.onecmd('archive create')
        self.assertThat(out.getvalue(),
                        Contains('!archive'))

    def test_do_archive_list_more(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            for size in [(25, '25B'), (1024, '1KiB'), (2000000, '1MiB')]:
                from lacli.adf import Archive, Meta
                meta = Meta(format='', size=size[0], cipher='')
                cache = Mock(archives=Mock(return_value=[Archive(
                    title="foo", description='', tags=[], meta=meta)]))
                cli = self._makeit(Mock(), cache, self.prefs)
                cli.onecmd('archive create')
                self.assertThat(out.getvalue(),
                                Contains('Prepared archives:\n1) foo [//'
                                         + size[1]))

    @patch('sys.stdin', new_callable=StringIO)
    def test_loop_none(self, mock_stdin):
        cli = self._makeit(Mock(), Mock, self.prefs)
        cli.cmdloop()

    def test_do_status_error(self):
        from lacli.cache import Cache
        with _temp_home() as home:
            cli = self._makeit(Mock(), Cache(home), self.prefs)
            with patch('sys.stdout', new_callable=StringIO) as out:
                cli.onecmd('archive list')
                self.assertThat(out.getvalue(),
                                Contains('No available archives'))
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive status foobar')
            self.assertThat(out.getvalue(),
                            Contains('error: invalid value'))
        apisession = Mock()
        apisession.upload_status.side_effect = Exception('foo')
        cli = self._makeit(apisession, Cache(self.home), self.prefs)
        with nested(
            patch('sys.stdout', new_callable=StringIO),
            patch('lacli.command.urlparse'),
                ) as (out, urlparse):
            uploads = cli.archive.cache._for_adf('archives')
            urlparse.return_value = Mock(scheme='gopher', path=self.home)
            for seq, archive in enumerate(uploads.itervalues()):
                    if archive['archive'].title == 'My pending upload':
                        cli.onecmd('archive status {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('error:'))

    def test_do_status(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive status')
            self.assertThat(out.getvalue(),
                            Contains('Usage:'))

    def test_do_put_error(self):
        from lacli.cache import Cache
        with _temp_home() as home:
            cli = self._makeit(Mock(), Cache(home), self.prefs)
            with patch('sys.stdout', new_callable=StringIO) as out:
                cli.onecmd('archive upload')
                self.assertThat(out.getvalue(),
                                Contains('No such archive'))
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            cli.onecmd('archive upload foobar')
            self.assertThat(out.getvalue(),
                            Contains('error: invalid value'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            archives = cli.archive.cache._for_adf('archives')
            for seq, archive in enumerate(archives.itervalues()):
                if archive['archive'].title == 'My 2013 vacation':
                    cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('upload is already completed'))

    def test_do_put_not_found(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        cli.archive.cache.links = Mock(return_value={})
        with patch('sys.stdout', new_callable=StringIO) as out:
            for seq, archive in enumerate(cli.archive.cache.archives()):
                if archive.title == 'My 2013 vacation':
                    cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(), Contains('no local copy exists'))

    def test_do_put_not_local(self):
        from lacli.cache import Cache
        cli = self._makeit(Mock(), Cache(self.home), self.prefs)
        with patch('sys.stdout', new_callable=StringIO) as out:
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='gopher', path=self.home)
                for seq, archive in enumerate(cli.archive.cache.archives()):
                    if archive.title == 'My 2013 vacation':
                        cli.onecmd('archive upload {}'.format(seq+1))
                self.assertThat(out.getvalue(), Contains('url not local'))
                urlparse.assert_called_with('file:///path/to/archive')

    def test_do_put_done(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            from lacli.cache import Cache
            upload = MagicMock()
            upload.__enter__.return_value = {
                'uri': 'http://foo.com',
                'id': '1',
                'tokens': Mock()
            }
            with patch.object(Cache, 'save_upload'):
                cli = self._makeit(Mock(upload=Mock(return_value=upload)),
                                   Cache(self.home),
                                   self.prefs,
                                   self._makeupload())
                cli.archive._var['capsule'] = 1
                with patch('lacli.command.urlparse') as urlparse:
                    urlparse.return_value = Mock(scheme='file', path=self.home)
                    archives = cli.archive.cache.archives()
                    for seq, archive in enumerate(archives):
                        if archive.title == 'My 2013 vacation':
                            cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(), Contains('done'))

    def test_do_put_exception(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            from lacli.cache import Cache
            upload = MagicMock()
            upload.__enter__.return_value = {
                'uri': 'http://foo.com',
                'id': '1',
                'tokens': Mock()
            }
            cli = self._makeit(Mock(upload=Mock(return_value=upload)),
                               Cache(self.home), self.prefs,
                               self._makeupload(side_effect=Exception))
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='file', path=self.home)
                for seq, archive in enumerate(cli.archive.cache.archives()):
                    if archive.title == 'My 2013 vacation':
                        cli.onecmd('archive upload {}'.format(seq+1))
            self.assertThat(out.getvalue(),
                            Contains('error:'))

    def test_do_restore_none(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache = Mock(archives=Mock(return_value=[]))
            cli = self._makeit(Mock(), cache, self.prefs, Mock())
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('No such archive'))
            cli.onecmd('archive restore 1')
            self.assertThat(out.getvalue(), Contains('No such archive'))
            cli.onecmd('archive restore foobar')
            self.assertThat(out.getvalue(), Contains('No such archive'))

    @patch('lacli.command.restore_archive')
    def test_do_restore(self, restore_archive):
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache = Mock(archives=Mock(return_value=[Mock(title='foo')]),
                         certs=Mock(return_value={}),
                         links=Mock(return_value={}))
            cli = self._makeit(Mock(), cache, self.prefs, Mock())
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(),
                            Contains('no matching certificate found'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.certs.return_value = {'foo': 'cert'}
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('no local copy exists'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            with patch('lacli.command.urlparse') as urlparse:
                urlparse.return_value = Mock(scheme='gopher', path=self.home)
                cli.onecmd('archive restore')
                self.assertThat(out.getvalue(), Contains('url not local'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('archive restored'))
        with patch('sys.stdout', new_callable=StringIO) as out:
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.archive._var['output_directory'] = 'foo'
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('archive restored'))
            args, kwargs = restore_archive.call_args
            a, p, cert, o, c, cb = args
            self.assertEqual('cert', cert)
            self.assertEqual('/path', p)
            self.assertEqual('foo', o)
            cb("foo")
            self.assertThat(out.getvalue(), Contains("Extracting foo"))
        with patch('sys.stdout', new_callable=StringIO) as out:
            restore_archive.side_effect = Exception("foo")
            cache.links.return_value = {'foo': Mock(local="file:///path")}
            cli.archive._var['output_directory'] = 'foo'
            cli.onecmd('archive restore')
            self.assertThat(out.getvalue(), Contains('error: foo'))

    def test_do_list_exception(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(side_effect=Exception("foo")))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            self.assertEqual("error: foo\n", out.getvalue())

    def test_list_capsules(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(return_value=()))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            self.assertEqual("No available capsules.\n", out.getvalue())

    def test_list_capsules_some(self):
        with patch('sys.stdout', new_callable=StringIO) as out:
            s = Mock(capsules=Mock(return_value=({'title': 'foo', 'a': 'b'},)))
            cli = self._makeit(s, Mock(), self.prefs, Mock())
            cli.onecmd('capsule list')
            r = '''\
Available capsules:
title     :       foo
a         :         b

'''
            self.assertEqual(r, out.getvalue())

    @patch('sys.stdin', new_callable=StringIO)
    def test_do_archive(self, mock_stdin):
        cli = self._makeit(Mock(), Mock, self.prefs)
        cli.onecmd('archive')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import time

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

class hr_action_reason(osv.osv):
    _name = "hr.action.reason"
    _description = "Action Reason"
    _columns = {
        'name': fields.char('Reason', size=64, required=True, help='Specifies the reason for Signing In/Signing Out.'),
        'action_type': fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action's type"),
    }
    _defaults = {
        'action_type': 'sign_in',
    }

hr_action_reason()

def _employee_get(obj, cr, uid, context=None):
    ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
    return ids and ids[0] or False

class hr_attendance(osv.osv):
    _name = "hr.attendance"
    _description = "Attendance"

    def _day_compute(self, cr, uid, ids, fieldnames, args, context=None):
        res = dict.fromkeys(ids, '')
        for obj in self.browse(cr, uid, ids, context=context):
            res[obj.id] = time.strftime('%Y-%m-%d', time.strptime(obj.name, '%Y-%m-%d %H:%M:%S'))
        return res

    _columns = {
        'name': fields.datetime('Date', required=True, select=1),
        'action': fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'), ('action','Action')], 'Action', required=True),
        'action_desc': fields.many2one("hr.action.reason", "Action Reason", domain="[('action_type', '=', action)]", help='Specifies the reason for Signing In/Signing Out in case of extra hours.'),
        'employee_id': fields.many2one('hr.employee', "Employee's Name", required=True, select=True),
        'day': fields.function(_day_compute, method=True, type='char', string='Day', store=True, select=1, size=32),
    }
    _defaults = {
        'name': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), #please don't remove the lambda, if you remove it then the current time will not change
        'employee_id': _employee_get,
    }

    def _altern_si_so(self, cr, uid, ids, context=None):
        for id in ids:
            sql = '''
            SELECT action, name
            FROM hr_attendance AS att
            WHERE employee_id = (SELECT employee_id FROM hr_attendance WHERE id=%s)
            AND action IN ('sign_in','sign_out')
            AND name <= (SELECT name FROM hr_attendance WHERE id=%s)
            ORDER BY name DESC
            LIMIT 2 '''
            cr.execute(sql,(id,id))
            atts = cr.fetchall()
            if not ((len(atts)==1 and atts[0][0] == 'sign_in') or (atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1])):
                return False
        return True

    _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])]
    _order = 'name desc'

hr_attendance()

class hr_employee(osv.osv):
    _inherit = "hr.employee"
    _description = "Employee"

    def _state(self, cr, uid, ids, name, args, context=None):
        result = {}
        if not ids:
            return result
        for id in ids:
            result[id] = 'absent'
        cr.execute('SELECT hr_attendance.action, hr_attendance.employee_id \
                FROM ( \
                    SELECT MAX(name) AS name, employee_id \
                    FROM hr_attendance \
                    WHERE action in (\'sign_in\', \'sign_out\') \
                    GROUP BY employee_id \
                ) AS foo \
                LEFT JOIN hr_attendance \
                    ON (hr_attendance.employee_id = foo.employee_id \
                        AND hr_attendance.name = foo.name) \
                WHERE hr_attendance.employee_id IN %s',(tuple(ids),))
        for res in cr.fetchall():
            result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
        return result

    _columns = {
       'state': fields.function(_state, method=True, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
    }

    def _action_check(self, cr, uid, emp_id, dt=False, context=None):
        cr.execute('SELECT MAX(name) FROM hr_attendance WHERE employee_id=%s', (emp_id,))
        res = cr.fetchone()
        return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))

    def attendance_action_change(self, cr, uid, ids, type='action', context=None, dt=False, *args):
        obj_attendance = self.pool.get('hr.attendance')
        id = False
        warning_sign = 'sign'
        res = {}

        #Special case when button calls this method: type=context
        if isinstance(type, dict):
            type = type.get('type','action')
        if type == 'sign_in':
            warning_sign = "Sign In"
        elif type == 'sign_out':
            warning_sign = "Sign Out"
        for emp in self.read(cr, uid, ids, ['id'], context=context):
            if not self._action_check(cr, uid, emp['id'], dt, context):
                raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))

            res = {'action': type, 'employee_id': emp['id']}
            if dt:
                res['name'] = dt
        id = obj_attendance.create(cr, uid, res, context=context)

        if type != 'action':
            return id
        return True

hr_employee()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[FIX] hr_attendance : Correction on wizard of sign in/out [Ref: SaaS maintenance case 3896]<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import time

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

class hr_action_reason(osv.osv):
    _name = "hr.action.reason"
    _description = "Action Reason"
    _columns = {
        'name': fields.char('Reason', size=64, required=True, help='Specifies the reason for Signing In/Signing Out.'),
        'action_type': fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action's type"),
    }
    _defaults = {
        'action_type': 'sign_in',
    }

hr_action_reason()

def _employee_get(obj, cr, uid, context=None):
    ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
    return ids and ids[0] or False

class hr_attendance(osv.osv):
    _name = "hr.attendance"
    _description = "Attendance"

    def _day_compute(self, cr, uid, ids, fieldnames, args, context=None):
        res = dict.fromkeys(ids, '')
        for obj in self.browse(cr, uid, ids, context=context):
            res[obj.id] = time.strftime('%Y-%m-%d', time.strptime(obj.name, '%Y-%m-%d %H:%M:%S'))
        return res

    _columns = {
        'name': fields.datetime('Date', required=True, select=1),
        'action': fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'), ('action','Action')], 'Action', required=True),
        'action_desc': fields.many2one("hr.action.reason", "Action Reason", domain="[('action_type', '=', action)]", help='Specifies the reason for Signing In/Signing Out in case of extra hours.'),
        'employee_id': fields.many2one('hr.employee', "Employee's Name", required=True, select=True),
        'day': fields.function(_day_compute, method=True, type='char', string='Day', store=True, select=1, size=32),
    }
    _defaults = {
        'name': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), #please don't remove the lambda, if you remove it then the current time will not change
        'employee_id': _employee_get,
    }

    def _altern_si_so(self, cr, uid, ids, context=None):
        for id in ids:
            sql = '''
            SELECT action, name
            FROM hr_attendance AS att
            WHERE employee_id = (SELECT employee_id FROM hr_attendance WHERE id=%s)
            AND action IN ('sign_in','sign_out')
            AND name <= (SELECT name FROM hr_attendance WHERE id=%s)
            ORDER BY name DESC
            LIMIT 2 '''
            cr.execute(sql,(id,id))
            atts = cr.fetchall()
            if not ((len(atts)==1 and atts[0][0] == 'sign_in') or (len(atts)==2 and atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1])):
                return False
        return True

    _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])]
    _order = 'name desc'

hr_attendance()

class hr_employee(osv.osv):
    _inherit = "hr.employee"
    _description = "Employee"

    def _state(self, cr, uid, ids, name, args, context=None):
        result = {}
        if not ids:
            return result
        for id in ids:
            result[id] = 'absent'
        cr.execute('SELECT hr_attendance.action, hr_attendance.employee_id \
                FROM ( \
                    SELECT MAX(name) AS name, employee_id \
                    FROM hr_attendance \
                    WHERE action in (\'sign_in\', \'sign_out\') \
                    GROUP BY employee_id \
                ) AS foo \
                LEFT JOIN hr_attendance \
                    ON (hr_attendance.employee_id = foo.employee_id \
                        AND hr_attendance.name = foo.name) \
                WHERE hr_attendance.employee_id IN %s',(tuple(ids),))
        for res in cr.fetchall():
            result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
        return result

    _columns = {
       'state': fields.function(_state, method=True, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
    }

    def _action_check(self, cr, uid, emp_id, dt=False, context=None):
        cr.execute('SELECT MAX(name) FROM hr_attendance WHERE employee_id=%s', (emp_id,))
        res = cr.fetchone()
        return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))

    def attendance_action_change(self, cr, uid, ids, type='action', context=None, dt=False, *args):
        obj_attendance = self.pool.get('hr.attendance')
        id = False
        warning_sign = 'sign'
        res = {}

        #Special case when button calls this method: type=context
        if isinstance(type, dict):
            type = type.get('type','action')
        if type == 'sign_in':
            warning_sign = "Sign In"
        elif type == 'sign_out':
            warning_sign = "Sign Out"
        for emp in self.read(cr, uid, ids, ['id'], context=context):
            if not self._action_check(cr, uid, emp['id'], dt, context):
                raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))

            res = {'action': type, 'employee_id': emp['id']}
            if dt:
                res['name'] = dt
        id = obj_attendance.create(cr, uid, res, context=context)

        if type != 'action':
            return id
        return True

hr_employee()

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


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

import csv
from HTMLParser import HTMLParser
from optparse import make_option
import StringIO
from zipfile import ZipFile, ZipInfo

from django.core.management.base import BaseCommand, CommandError

from moocng.courses.models import Course
from moocng.courses.marks import calculate_course_mark

class Command(BaseCommand):

    help = ("create a zip bundle with csv files with students (firt_name, "
            "last_name, email)")

    option_list = BaseCommand.option_list + (
        make_option('-c', '--course',
                    action='append',
                    dest='courses',
                    default=[],
                    help='Only list this courses (can repeat this param)'),
        make_option('-f', '--filename',
                    action='store',
                    dest='filename',
                    default="",
                    help="Filename.zip to save the csv files"),
        make_option('-l', '--limit',
                    action='store',
                    dest='limit',
                    default="100",
                    help="Limit of the users that will be processed"),
    )

    def error(self, message):
        self.stderr.write("%s\n" % message.encode("ascii", "replace"))

    def message(self, message):
        self.stdout.write("%s\n" % message.encode("ascii", "replace"))

    def handle(self, *args, **options):

        if not options["filename"]:
            raise CommandError("-f filename.zip is required")

        limit = options["limit"]

        if options["courses"]:
            courses = options["courses"]
            courses = Course.objects.filter(slug__in=options["courses"])
        else:
            courses = Course.objects.all()

        if not courses:
            raise CommandError("Courses not found")

        if options["filename"].endswith(".zip"):
            self.filename = options["filename"]
        else:
            self.filename = "%s.zip" % options["filename"]

        h = HTMLParser()

        zip = ZipFile(self.filename, mode="w")

        for course in courses:
            self.message("Adding course file %s.csv" % course.slug)

            course_file = StringIO.StringIO()

            course_csv = csv.writer(course_file, quoting=csv.QUOTE_ALL)
            headers = ["email", "mark"]

            course_csv.writerow(headers)

            students = course.students.all()[:limit]

            for student in students:
                row = []
                fieldvalue = getattr(student, 'email')
                row.append(h.unescape(fieldvalue.encode("ascii", "ignore")))
                mark, mark_info = calculate_course_mark(course, student)
                row.append(mark)
                course_csv.writerow(row)

            course_fileinfo = ZipInfo("%s.csv" % course.slug)

            course_file.seek(0)

            zip.writestr(course_fileinfo, course_file.read())

            course_file.close()

        zip.close()

        self.message("Created %s file" % self.filename)
<commit_msg>Updated student marks to CSV<commit_after># -*- coding: utf-8 -*-
# Copyright 2012-2013 UNED
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import csv
from HTMLParser import HTMLParser
from optparse import make_option
import StringIO
from zipfile import ZipFile, ZipInfo

from django.core.management.base import BaseCommand, CommandError

from moocng.courses.models import Course
from moocng.courses.marks import calculate_course_mark

class Command(BaseCommand):

    help = ("create a zip bundle with csv files with students (firt_name, "
            "last_name, email)")

    option_list = BaseCommand.option_list + (
        make_option('-c', '--course',
                    action='append',
                    dest='courses',
                    default=[],
                    help='Only list this courses (can repeat this param)'),
        make_option('-f', '--filename',
                    action='store',
                    dest='filename',
                    default="",
                    help="Filename.zip to save the csv files"),
        make_option('-l', '--limit',
                    action='store',
                    dest='limit',
                    default="10000",
                    help="Limit of the users that will be processed"),
    )

    def error(self, message):
        self.stderr.write("%s\n" % message.encode("ascii", "replace"))

    def message(self, message):
        self.stdout.write("%s\n" % message.encode("ascii", "replace"))

    def handle(self, *args, **options):

        if not options["filename"]:
            raise CommandError("-f filename.zip is required")

        limit = options["limit"]

        if options["courses"]:
            courses = options["courses"]
            courses = Course.objects.filter(slug__in=options["courses"])
        else:
            courses = Course.objects.all()

        if not courses:
            raise CommandError("Courses not found")

        if options["filename"].endswith(".zip"):
            self.filename = options["filename"]
        else:
            self.filename = "%s.zip" % options["filename"]

        h = HTMLParser()

        zip = ZipFile(self.filename, mode="w")

        for course in courses:
            self.message("Adding course file %s.csv" % course.slug)

            course_file = StringIO.StringIO()

            course_csv = csv.writer(course_file, quoting=csv.QUOTE_ALL)
            headers = ["email", "mark"]

            course_csv.writerow(headers)

            students = course.students.all()[:limit]
            headers = ["first_name", "last_name", "email"]

            for student in students:
                row = []
                for field in headers:
                    fieldvalue = getattr(student, field)
                    row.append(h.unescape(fieldvalue).encode("ascii", "ignore"))
                mark, mark_info = calculate_course_mark(course, student)
                row.append(mark)
                course_csv.writerow(row)

            course_fileinfo = ZipInfo("%s.csv" % course.slug)

            course_file.seek(0)

            zip.writestr(course_fileinfo, course_file.read())

            course_file.close()

        zip.close()

        self.message("Created %s file" % self.filename)
<|endoftext|>


<commit_before>""" ESC/POS Exceptions classes """

import os

class Error(Exception):
    """ Base class for ESC/POS errors """
    def __init__(self, msg, status=None):
        Exception.__init__(self)
        self.msg = msg
        self.resultcode = 1
        if status is not None:
            self.resultcode = status

    def __str__(self):
        return self.msg

# Result/Exit codes
# 0  = success
# 10 = No Barcode type defined
# 20 = Barcode size values are out of range
# 30 = Barcode text not supplied
# 40 = Image height is too large
# 50 = No string supplied to be printed
# 60 = Invalid pin to send Cash Drawer pulse

class BarcodeTypeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 10

    def __str__(self):
        return "No Barcode type is defined"

class BarcodeSizeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 20

    def __str__(self):
        return "Barcode size is out of range"

class BarcodeCodeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 30

    def __str__(self):
        return "Code was not supplied"

class ImageSizeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 40

    def __str__(self):
        return "Image height is longer than 255px and can't be printed"

class TextError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 50

    def __str__(self):
        return "Text string must be supplied to the text() method"

class CashDrawerError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 60

    def __str__(self):
        return "Valid pin must be set to send pulse"

class NoStatusError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 70

    def __str__(self):
        return "Impossible to get status from the printer"

class TicketNotPrinted(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 80

    def __str__(self):
        return "A part of the ticket was not been printed"

class NoDeviceError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 90

    def __str__(self):
        return "Impossible to find the printer Device"

class HandleDeviceError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 100

    def __str__(self):
        return "Impossible to handle device"
<commit_msg>[IMP] hw_escpos: don't replace a USBError exception with some string<commit_after>""" ESC/POS Exceptions classes """

import os

class Error(Exception):
    """ Base class for ESC/POS errors """
    def __init__(self, msg, status=None):
        Exception.__init__(self)
        self.msg = msg
        self.resultcode = 1
        if status is not None:
            self.resultcode = status

    def __str__(self):
        return self.msg

# Result/Exit codes
# 0  = success
# 10 = No Barcode type defined
# 20 = Barcode size values are out of range
# 30 = Barcode text not supplied
# 40 = Image height is too large
# 50 = No string supplied to be printed
# 60 = Invalid pin to send Cash Drawer pulse

class BarcodeTypeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 10

    def __str__(self):
        return "No Barcode type is defined"

class BarcodeSizeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 20

    def __str__(self):
        return "Barcode size is out of range"

class BarcodeCodeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 30

    def __str__(self):
        return "Code was not supplied"

class ImageSizeError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 40

    def __str__(self):
        return "Image height is longer than 255px and can't be printed"

class TextError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 50

    def __str__(self):
        return "Text string must be supplied to the text() method"

class CashDrawerError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 60

    def __str__(self):
        return "Valid pin must be set to send pulse"

class NoStatusError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 70

    def __str__(self):
        return "Impossible to get status from the printer: " + str(self.msg)

class TicketNotPrinted(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 80

    def __str__(self):
        return "A part of the ticket was not been printed: " + str(self.msg)

class NoDeviceError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 90

    def __str__(self):
        return str(self.msg)

class HandleDeviceError(Error):
    def __init__(self, msg=""):
        Error.__init__(self, msg)
        self.msg = msg
        self.resultcode = 100

    def __str__(self):
        return str(self.msg)
<|endoftext|>