<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 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 hashlib
import itertools
import logging
import os
import re

from openerp import tools
from openerp.osv import fields,osv

_logger = logging.getLogger(__name__)

class ir_attachment(osv.osv):
    """Attachments are used to link binary files or url to any openerp document.

    External attachment storage
    ---------------------------

    The 'data' function field (_data_get,data_set) is implemented using
    _file_read, _file_write and _file_delete which can be overridden to
    implement other storage engines, shuch methods should check for other
    location pseudo uri (example: hdfs://hadoppserver)

    The default implementation is the file:dirname location that stores files
    on the local filesystem using name based on their sha1 hash
    """
    def _name_get_resname(self, cr, uid, ids, object, method, context):
        data = {}
        for attachment in self.browse(cr, uid, ids, context=context):
            model_object = attachment.res_model
            res_id = attachment.res_id
            if model_object and res_id:
                model_pool = self.pool.get(model_object)
                res = model_pool.name_get(cr,uid,[res_id],context)
                res_name = res and res[0][1] or False
                if res_name:
                    field = self._columns.get('res_name',False)
                    if field and len(res_name) > field.size:
                        res_name = res_name[:field.size-3] + '...'
                data[attachment.id] = res_name
            else:
                data[attachment.id] = False
        return data

    # 'data' field implementation
    def _full_path(self, cr, uid, location, path):
        # location = 'file:filestore'
        assert location.startswith('file:'), "Unhandled filestore location %s" % location
        location = location[5:]

        # sanitize location name and path
        location = re.sub('[.]','',location)
        location = location.strip('/\\')

        path = re.sub('[.]','',path)
        path = path.strip('/\\')
        return os.path.join(tools.config['root_path'], location, cr.dbname, path)

    def _file_read(self, cr, uid, location, fname, bin_size=False):
        full_path = self._full_path(cr, uid, location, fname)
        r = ''
        try:
            if bin_size:
                r = os.path.getsize(full_path)
            else:
                r = open(full_path,'rb').read().encode('base64')
        except IOError:
            _logger.error("_read_file reading %s",full_path)
        return r

    def _file_write(self, cr, uid, location, value):
        bin_value = value.decode('base64')
        fname = hashlib.sha1(bin_value).hexdigest()
        # scatter files across 1024 dirs
        # we use '/' in the db (even on windows)
        fname = fname[:3] + '/' + fname
        full_path = self._full_path(cr, uid, location, fname)
        try:
            dirname = os.path.dirname(full_path)
            if not os.path.isdir(dirname):
                os.makedirs(dirname)
            open(full_path,'wb').write(bin_value)
        except IOError:
            _logger.error("_file_write writing %s",full_path)
        return fname

    def _file_delete(self, cr, uid, location, fname):
        count = self.search(cr, 1, [('store_fname','=',fname)], count=True)
        if count <= 1:
            full_path = self._full_path(cr, uid, location, fname)
            try:
                os.unlink(full_path)
            except OSError:
                _logger.error("_file_delete could not unlink %s",full_path)
            except IOError:
                # Harmless and needed for race conditions
                _logger.error("_file_delete could not unlink %s",full_path)

    def _data_get(self, cr, uid, ids, name, arg, context=None):
        if context is None:
            context = {}
        result = {}
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        bin_size = context.get('bin_size')
        for attach in self.browse(cr, uid, ids, context=context):
            if location and attach.store_fname:
                result[attach.id] = self._file_read(cr, uid, location, attach.store_fname, bin_size)
            else:
                result[attach.id] = attach.db_datas
        return result

    def _data_set(self, cr, uid, id, name, value, arg, context=None):
        # We dont handle setting data to null
        if not value:
            return True
        if context is None:
            context = {}
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        file_size = len(value.decode('base64'))
        if location:
            attach = self.browse(cr, uid, id, context=context)
            if attach.store_fname:
                self._file_delete(cr, uid, location, attach.store_fname)
            fname = self._file_write(cr, uid, location, value)
            super(ir_attachment, self).write(cr, uid, [id], {'store_fname': fname, 'file_size': file_size}, context=context)
        else:
            super(ir_attachment, self).write(cr, uid, [id], {'db_datas': value, 'file_size': file_size}, context=context)
        return True

    _name = 'ir.attachment'
    _columns = {
        'name': fields.char('Attachment Name',size=256, required=True),
        'datas_fname': fields.char('File Name',size=256),
        'description': fields.text('Description'),
        'res_name': fields.function(_name_get_resname, type='char', size=128, string='Resource Name', store=True),
        'res_model': fields.char('Resource Model',size=64, readonly=True, help="The database object this attachment will be attached to"),
        'res_id': fields.integer('Resource ID', readonly=True, help="The record id this is attached to"),
        'create_date': fields.datetime('Date Created', readonly=True),
        'create_uid':  fields.many2one('res.users', 'Owner', readonly=True),
        'company_id': fields.many2one('res.company', 'Company', change_default=True),
        'type': fields.selection( [ ('url','URL'), ('binary','Binary'), ],
                'Type', help="Binary File or URL", required=True, change_default=True),
        'url': fields.char('Url', size=1024),
        # al: We keep shitty field names for backward compatibility with document
        'datas': fields.function(_data_get, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True),
        'store_fname': fields.char('Stored Filename', size=256),
        'db_datas': fields.binary('Database Data'),
        'file_size': fields.integer('File Size'),
    }

    _defaults = {
        'type': 'binary',
        'file_size': 0,
        'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c),
    }

    def _auto_init(self, cr, context=None):
        super(ir_attachment, self)._auto_init(cr, context)
        cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('ir_attachment_res_idx',))
        if not cr.fetchone():
            cr.execute('CREATE INDEX ir_attachment_res_idx ON ir_attachment (res_model, res_id)')
            cr.commit()

    def check(self, cr, uid, ids, mode, context=None, values=None):
        """Restricts the access to an ir.attachment, according to referred model
        In the 'document' module, it is overriden to relax this hard rule, since
        more complex ones apply there.
        """
        if not ids:
            return
        res_ids = {}
        if ids:
            if isinstance(ids, (int, long)):
                ids = [ids]
            cr.execute('SELECT DISTINCT res_model, res_id FROM ir_attachment WHERE id = ANY (%s)', (ids,))
            for rmod, rid in cr.fetchall():
                if not (rmod and rid):
                    continue
                res_ids.setdefault(rmod,set()).add(rid)
        if values:
            if values.get('res_model') and 'res_id' in values:
                res_ids.setdefault(values['res_model'],set()).add(values['res_id'])

        ima = self.pool.get('ir.model.access')
        for model, mids in res_ids.items():
            # ignore attachments that are not attached to a resource anymore when checking access rights
            # (resource was deleted but attachment was not)
            mids = self.pool.get(model).exists(cr, uid, mids)
            ima.check(cr, uid, model, mode)
            self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context)

    def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
        ids = super(ir_attachment, self)._search(cr, uid, args, offset=offset,
                                                 limit=limit, order=order,
                                                 context=context, count=False,
                                                 access_rights_uid=access_rights_uid)
        if not ids:
            if count:
                return 0
            return []

        # Work with a set, as list.remove() is prohibitive for large lists of documents
        # (takes 20+ seconds on a db with 100k docs during search_count()!)
        orig_ids = ids
        ids = set(ids)

        # For attachments, the permissions of the document they are attached to
        # apply, so we must remove attachments for which the user cannot access
        # the linked document.
        # Use pure SQL rather than read() as it is about 50% faster for large dbs (100k+ docs),
        # and the permissions are checked in super() and below anyway.
        cr.execute("""SELECT id, res_model, res_id FROM ir_attachment WHERE id = ANY(%s)""", (list(ids),))
        targets = cr.dictfetchall()
        model_attachments = {}
        for target_dict in targets:
            if not (target_dict['res_id'] and target_dict['res_model']):
                continue
            # model_attachments = { 'model': { 'res_id': [id1,id2] } }
            model_attachments.setdefault(target_dict['res_model'],{}).setdefault(target_dict['res_id'],set()).add(target_dict['id'])

        # To avoid multiple queries for each attachment found, checks are
        # performed in batch as much as possible.
        ima = self.pool.get('ir.model.access')
        for model, targets in model_attachments.iteritems():
            if not ima.check(cr, uid, model, 'read', False):
                # remove all corresponding attachment ids
                for attach_id in itertools.chain(*targets.values()):
                    ids.remove(attach_id)
                continue # skip ir.rule processing, these ones are out already

            # filter ids according to what access rules permit
            target_ids = targets.keys()
            allowed_ids = self.pool.get(model).search(cr, uid, [('id', 'in', target_ids)], context=context)
            disallowed_ids = set(target_ids).difference(allowed_ids)
            for res_id in disallowed_ids:
                for attach_id in targets[res_id]:
                    ids.remove(attach_id)

        # sort result according to the original sort ordering
        result = [id for id in orig_ids if id in ids]
        return len(result) if count else list(result)

    def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):
        self.check(cr, uid, ids, 'read', context=context)
        return super(ir_attachment, self).read(cr, uid, ids, fields_to_read, context, load)

    def write(self, cr, uid, ids, vals, context=None):
        self.check(cr, uid, ids, 'write', context=context, values=vals)
        if 'file_size' in vals:
            del vals['file_size']
        return super(ir_attachment, self).write(cr, uid, ids, vals, context)

    def copy(self, cr, uid, id, default=None, context=None):
        self.check(cr, uid, [id], 'write', context=context)
        return super(ir_attachment, self).copy(cr, uid, id, default, context)

    def unlink(self, cr, uid, ids, context=None):
        self.check(cr, uid, ids, 'unlink', context=context)
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        if location:
            for attach in self.browse(cr, uid, ids, context=context):
                if attach.store_fname:
                    self._file_delete(cr, uid, location, attach.store_fname)
        return super(ir_attachment, self).unlink(cr, uid, ids, context)

    def create(self, cr, uid, values, context=None):
        self.check(cr, uid, [], mode='create', context=context, values=values)
        if 'file_size' in values:
            del values['file_size']
        return super(ir_attachment, self).create(cr, uid, values, context)

    def action_get(self, cr, uid, context=None):
        return self.pool.get('ir.actions.act_window').for_xml_id(
            cr, uid, 'base', 'action_attachment', context=context)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[FIX] document: overridden ORM methods need to respect API idiosyncrasies, otherwise check() calls may fail<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 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 hashlib
import itertools
import logging
import os
import re

from openerp import tools
from openerp.osv import fields,osv

_logger = logging.getLogger(__name__)

class ir_attachment(osv.osv):
    """Attachments are used to link binary files or url to any openerp document.

    External attachment storage
    ---------------------------

    The 'data' function field (_data_get,data_set) is implemented using
    _file_read, _file_write and _file_delete which can be overridden to
    implement other storage engines, shuch methods should check for other
    location pseudo uri (example: hdfs://hadoppserver)

    The default implementation is the file:dirname location that stores files
    on the local filesystem using name based on their sha1 hash
    """
    def _name_get_resname(self, cr, uid, ids, object, method, context):
        data = {}
        for attachment in self.browse(cr, uid, ids, context=context):
            model_object = attachment.res_model
            res_id = attachment.res_id
            if model_object and res_id:
                model_pool = self.pool.get(model_object)
                res = model_pool.name_get(cr,uid,[res_id],context)
                res_name = res and res[0][1] or False
                if res_name:
                    field = self._columns.get('res_name',False)
                    if field and len(res_name) > field.size:
                        res_name = res_name[:field.size-3] + '...'
                data[attachment.id] = res_name
            else:
                data[attachment.id] = False
        return data

    # 'data' field implementation
    def _full_path(self, cr, uid, location, path):
        # location = 'file:filestore'
        assert location.startswith('file:'), "Unhandled filestore location %s" % location
        location = location[5:]

        # sanitize location name and path
        location = re.sub('[.]','',location)
        location = location.strip('/\\')

        path = re.sub('[.]','',path)
        path = path.strip('/\\')
        return os.path.join(tools.config['root_path'], location, cr.dbname, path)

    def _file_read(self, cr, uid, location, fname, bin_size=False):
        full_path = self._full_path(cr, uid, location, fname)
        r = ''
        try:
            if bin_size:
                r = os.path.getsize(full_path)
            else:
                r = open(full_path,'rb').read().encode('base64')
        except IOError:
            _logger.error("_read_file reading %s",full_path)
        return r

    def _file_write(self, cr, uid, location, value):
        bin_value = value.decode('base64')
        fname = hashlib.sha1(bin_value).hexdigest()
        # scatter files across 1024 dirs
        # we use '/' in the db (even on windows)
        fname = fname[:3] + '/' + fname
        full_path = self._full_path(cr, uid, location, fname)
        try:
            dirname = os.path.dirname(full_path)
            if not os.path.isdir(dirname):
                os.makedirs(dirname)
            open(full_path,'wb').write(bin_value)
        except IOError:
            _logger.error("_file_write writing %s",full_path)
        return fname

    def _file_delete(self, cr, uid, location, fname):
        count = self.search(cr, 1, [('store_fname','=',fname)], count=True)
        if count <= 1:
            full_path = self._full_path(cr, uid, location, fname)
            try:
                os.unlink(full_path)
            except OSError:
                _logger.error("_file_delete could not unlink %s",full_path)
            except IOError:
                # Harmless and needed for race conditions
                _logger.error("_file_delete could not unlink %s",full_path)

    def _data_get(self, cr, uid, ids, name, arg, context=None):
        if context is None:
            context = {}
        result = {}
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        bin_size = context.get('bin_size')
        for attach in self.browse(cr, uid, ids, context=context):
            if location and attach.store_fname:
                result[attach.id] = self._file_read(cr, uid, location, attach.store_fname, bin_size)
            else:
                result[attach.id] = attach.db_datas
        return result

    def _data_set(self, cr, uid, id, name, value, arg, context=None):
        # We dont handle setting data to null
        if not value:
            return True
        if context is None:
            context = {}
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        file_size = len(value.decode('base64'))
        if location:
            attach = self.browse(cr, uid, id, context=context)
            if attach.store_fname:
                self._file_delete(cr, uid, location, attach.store_fname)
            fname = self._file_write(cr, uid, location, value)
            super(ir_attachment, self).write(cr, uid, [id], {'store_fname': fname, 'file_size': file_size}, context=context)
        else:
            super(ir_attachment, self).write(cr, uid, [id], {'db_datas': value, 'file_size': file_size}, context=context)
        return True

    _name = 'ir.attachment'
    _columns = {
        'name': fields.char('Attachment Name',size=256, required=True),
        'datas_fname': fields.char('File Name',size=256),
        'description': fields.text('Description'),
        'res_name': fields.function(_name_get_resname, type='char', size=128, string='Resource Name', store=True),
        'res_model': fields.char('Resource Model',size=64, readonly=True, help="The database object this attachment will be attached to"),
        'res_id': fields.integer('Resource ID', readonly=True, help="The record id this is attached to"),
        'create_date': fields.datetime('Date Created', readonly=True),
        'create_uid':  fields.many2one('res.users', 'Owner', readonly=True),
        'company_id': fields.many2one('res.company', 'Company', change_default=True),
        'type': fields.selection( [ ('url','URL'), ('binary','Binary'), ],
                'Type', help="Binary File or URL", required=True, change_default=True),
        'url': fields.char('Url', size=1024),
        # al: We keep shitty field names for backward compatibility with document
        'datas': fields.function(_data_get, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True),
        'store_fname': fields.char('Stored Filename', size=256),
        'db_datas': fields.binary('Database Data'),
        'file_size': fields.integer('File Size'),
    }

    _defaults = {
        'type': 'binary',
        'file_size': 0,
        'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c),
    }

    def _auto_init(self, cr, context=None):
        super(ir_attachment, self)._auto_init(cr, context)
        cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('ir_attachment_res_idx',))
        if not cr.fetchone():
            cr.execute('CREATE INDEX ir_attachment_res_idx ON ir_attachment (res_model, res_id)')
            cr.commit()

    def check(self, cr, uid, ids, mode, context=None, values=None):
        """Restricts the access to an ir.attachment, according to referred model
        In the 'document' module, it is overriden to relax this hard rule, since
        more complex ones apply there.
        """
        if not ids:
            return
        res_ids = {}
        if ids:
            if isinstance(ids, (int, long)):
                ids = [ids]
            cr.execute('SELECT DISTINCT res_model, res_id FROM ir_attachment WHERE id = ANY (%s)', (ids,))
            for rmod, rid in cr.fetchall():
                if not (rmod and rid):
                    continue
                res_ids.setdefault(rmod,set()).add(rid)
        if values:
            if values.get('res_model') and 'res_id' in values:
                res_ids.setdefault(values['res_model'],set()).add(values['res_id'])

        ima = self.pool.get('ir.model.access')
        for model, mids in res_ids.items():
            # ignore attachments that are not attached to a resource anymore when checking access rights
            # (resource was deleted but attachment was not)
            mids = self.pool.get(model).exists(cr, uid, mids)
            ima.check(cr, uid, model, mode)
            self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context)

    def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
        ids = super(ir_attachment, self)._search(cr, uid, args, offset=offset,
                                                 limit=limit, order=order,
                                                 context=context, count=False,
                                                 access_rights_uid=access_rights_uid)
        if not ids:
            if count:
                return 0
            return []

        # Work with a set, as list.remove() is prohibitive for large lists of documents
        # (takes 20+ seconds on a db with 100k docs during search_count()!)
        orig_ids = ids
        ids = set(ids)

        # For attachments, the permissions of the document they are attached to
        # apply, so we must remove attachments for which the user cannot access
        # the linked document.
        # Use pure SQL rather than read() as it is about 50% faster for large dbs (100k+ docs),
        # and the permissions are checked in super() and below anyway.
        cr.execute("""SELECT id, res_model, res_id FROM ir_attachment WHERE id = ANY(%s)""", (list(ids),))
        targets = cr.dictfetchall()
        model_attachments = {}
        for target_dict in targets:
            if not (target_dict['res_id'] and target_dict['res_model']):
                continue
            # model_attachments = { 'model': { 'res_id': [id1,id2] } }
            model_attachments.setdefault(target_dict['res_model'],{}).setdefault(target_dict['res_id'],set()).add(target_dict['id'])

        # To avoid multiple queries for each attachment found, checks are
        # performed in batch as much as possible.
        ima = self.pool.get('ir.model.access')
        for model, targets in model_attachments.iteritems():
            if not ima.check(cr, uid, model, 'read', False):
                # remove all corresponding attachment ids
                for attach_id in itertools.chain(*targets.values()):
                    ids.remove(attach_id)
                continue # skip ir.rule processing, these ones are out already

            # filter ids according to what access rules permit
            target_ids = targets.keys()
            allowed_ids = self.pool.get(model).search(cr, uid, [('id', 'in', target_ids)], context=context)
            disallowed_ids = set(target_ids).difference(allowed_ids)
            for res_id in disallowed_ids:
                for attach_id in targets[res_id]:
                    ids.remove(attach_id)

        # sort result according to the original sort ordering
        result = [id for id in orig_ids if id in ids]
        return len(result) if count else list(result)

    def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):
        if isinstance(ids, (int, long)):
            ids = [ids]
        self.check(cr, uid, ids, 'read', context=context)
        return super(ir_attachment, self).read(cr, uid, ids, fields_to_read, context, load)

    def write(self, cr, uid, ids, vals, context=None):
        if isinstance(ids, (int, long)):
            ids = [ids]
        self.check(cr, uid, ids, 'write', context=context, values=vals)
        if 'file_size' in vals:
            del vals['file_size']
        return super(ir_attachment, self).write(cr, uid, ids, vals, context)

    def copy(self, cr, uid, id, default=None, context=None):
        self.check(cr, uid, [id], 'write', context=context)
        return super(ir_attachment, self).copy(cr, uid, id, default, context)

    def unlink(self, cr, uid, ids, context=None):
        if isinstance(ids, (int, long)):
            ids = [ids]
        self.check(cr, uid, ids, 'unlink', context=context)
        location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location')
        if location:
            for attach in self.browse(cr, uid, ids, context=context):
                if attach.store_fname:
                    self._file_delete(cr, uid, location, attach.store_fname)
        return super(ir_attachment, self).unlink(cr, uid, ids, context)

    def create(self, cr, uid, values, context=None):
        self.check(cr, uid, [], mode='create', context=context, values=values)
        if 'file_size' in values:
            del values['file_size']
        return super(ir_attachment, self).create(cr, uid, values, context)

    def action_get(self, cr, uid, context=None):
        return self.pool.get('ir.actions.act_window').for_xml_id(
            cr, uid, 'base', 'action_attachment', context=context)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from setuptools import setup, find_packages

setup(
    name='django-page-cms',
    test_suite = "example.test_runner.run_tests",
    version=__import__('pages').__version__,
    description='A tree based Django CMS application',
    author='Batiste Bieler',
    author_email='batiste.bieler@gmail.com',
    url='http://code.google.com/p/django-page-cms/',
    download_url='http://code.google.com/p/django-page-cms/downloads/list',
    requires=(
        'BeautifulSoup',
        'Django',
        'html5lib (>=0.10)',
        'tagging (>0.2.1)', # please use the trunk version of tagging
        'django_mptt (>0.2.1)', # please use the trunk version of django mptt
    ),
    packages=find_packages(exclude=['example', 'example.*']),
    # very important for the egg to work properly
    package_data={'pages': [
        'templates/admin/pages/page/*.html',
        'templates/admin/pages/page/widgets/*.html',
        'templates/admin/pages/page/includes/*.html',
        'templates/pages/*.html',
        'templates/pages/tests/*.html'
    ]},
    #include_package_data=True, # include package data under svn source control
    zip_safe=False,
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Framework :: Django',
        'Programming Language :: Python :: 2.3',
        'Programming Language :: JavaScript',
        'Topic :: Internet :: WWW/HTTP :: Site Management',
    ],
)
<commit_msg>Widget template were not included properly because the directory has been moved.<commit_after># -*- coding: utf-8 -*-
from setuptools import setup, find_packages

setup(
    name='django-page-cms',
    test_suite='example.test_runner.run_tests',
    version=__import__('pages').__version__,
    description='A tree based Django CMS application',
    author='Batiste Bieler',
    author_email='batiste.bieler@gmail.com',
    url='http://code.google.com/p/django-page-cms/',
    download_url='http://code.google.com/p/django-page-cms/downloads/list',
    requires=(
        'BeautifulSoup',
        'Django',
        'html5lib (>=0.10)',
        'tagging (>0.2.1)', # please use the trunk version of tagging
        'django_mptt (>0.2.1)', # please use the trunk version of django mptt
    ),
    packages=find_packages(exclude=['example', 'example.*']),
    # very important for the egg to work properly
    package_data={'pages': [
        'templates/admin/pages/page/*.html',
        'templates/admin/pages/page/widgets/*.html',
        'templates/admin/pages/page/includes/*.html',
        'templates/pages/*.html',
        'templates/pages/tests/*.html'
        'templates/pages/widgets/*.html',
    ]},
    #include_package_data=True, # include package data under svn source control
    zip_safe=False,
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Framework :: Django',
        'Programming Language :: Python :: 2.3',
        'Programming Language :: JavaScript',
        'Topic :: Internet :: WWW/HTTP :: Site Management',
    ],
)
<|endoftext|>


<commit_before>#!/usr/bin/env python

from distutils.core import setup

setup(name='protorpc-generator',
    version='1.0',
    description='ProtoRPC generator',
    package_dir = {'': 'bin'},
    packages=['rpc_generators'],
    scripts=['bin/protoc-gen-rpc', 'bin/proto2rpc'],
    install_requires=[
        'protobuf>=2.3.0',
    ],
    )
<commit_msg>Fixed protobuf dependency to >=2.4.1<commit_after>#!/usr/bin/env python

from distutils.core import setup

setup(name='protorpc-generator',
    version='1.0',
    description='ProtoRPC generator',
    package_dir = {'': 'bin'},
    packages=['rpc_generators'],
    scripts=['bin/protoc-gen-rpc', 'bin/proto2rpc'],
    install_requires=[
        'protobuf>=2.4.1',
    ],
    )
<|endoftext|>


<commit_before>import os, glob, string, shutil
import sys
sys.path.insert(0,"lib")
from distutils.core import setup
from neuroimaging import packages, __version__

def main():

    setup( name = 'neuroimaging',
           version = __version__,
           description = 'This is a neuroimaging python package',
           author = 'Various, one of whom is Jonathan Taylor',
           author_email = 'jonathan.taylor@stanford.edu',
           ext_package = 'neuroimaging',
           packages=['']+list(packages),
           package_dir = {'': 'lib'},
           url = 'http://neuroimaging.scipy.org',
           long_description =
           '''
           ''')

if __name__ == "__main__": main()
<commit_msg>use neuroimaging docstring for long description<commit_after>import os, glob, string, shutil
import sys
sys.path.insert(0,"lib")
from distutils.core import setup
from neuroimaging import packages, __version__, __doc__

def main():

    setup( name = 'neuroimaging',
           version = __version__,
           description = 'This is a neuroimaging python package',
           author = 'Various, one of whom is Jonathan Taylor',
           author_email = 'jonathan.taylor@stanford.edu',
           ext_package = 'neuroimaging',
           packages=['']+list(packages),
           package_dir = {'': 'lib'},
           url = 'http://neuroimaging.scipy.org',
           long_description = __doc__)

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


<commit_before>import asyncio
import io
import logging
import os
import zipfile

from .. import asutil
from .. import exception

logger = logging.getLogger(__name__)

expect_ok = asutil.expect_ok_closure(exception.AdjustCommandError)

stdout_options = asutil.process_stdout_options
stderr_options = asutil.process_stderr_options

# This provider MAY be "extended" by other providers.
def get_process_provider(execution_name, cmd, get_result_data=None, log_context_option=None, send_log=False):
    @asyncio.coroutine
    def get_result_data_default(work_dir):
        return {}

    get_result_data = get_result_data if get_result_data is not None else get_result_data_default

    @asyncio.coroutine
    def adjust(repo_dir, extra_adjust_parameters, adjust_result):
        nonlocal execution_name
        logger.info('Executing "{execution_name}" using (sub)process adjust provider as "{cmd}".'.format(**locals()))
        log_executable_info(cmd)
        filled_cmd = [p.format(repo_dir=repo_dir) if p.startswith("{repo_dir}") else p for p in cmd]

        # log_context = getattr(asyncio.Task.current_task(), "log_context", None)
        # if log_context_option is None:
        #     if log_context is None:
        #         env = None
        #     else:
        #         env = {
        #             "LOG_CONTEXT": asyncio.Task.current_task().log_context,
        #         }
        # else:
        #     env = None
        #     if log_context is not None:
        #         filled_cmd.append(log_context_option)
        #         filled_cmd.append(log_context)
        env = None
        stdout = None
        try:
            stdout = yield from expect_ok(
                cmd=filled_cmd,
                desc="Adjust subprocess failed.",
                cwd=repo_dir,
                env=env,
                stdout=stdout_options["lines"] if send_log else stdout_options["ignore"],
                stderr=stderr_options["stdout"] if send_log else stderr_options["log_on_error"],
            )
        except exception.CommandError as e:
            logger.error('Adjust subprocess failed, exited code "{e.exit_code}"'.format(**locals()))
            raise

        logger.info("Adjust subprocess exited OK!")

        adjust_result_data = {}
        # TODO adjust_result_data["stdout"] = stdout
        logger.info("PME output:")
        logger.info(stdout)
        adjust_result_data["adjustType"] = execution_name
        adjust_result_data["resultData"] = yield from get_result_data(repo_dir)
        return adjust_result_data

    return adjust

#
# Utility
#

def log_executable_info(cmd):
    first = True
    for c in cmd:
        if c.endswith(".jar"):
            manifest = {}
            try:
                with zipfile.ZipFile(c) as z:
                    with z.open("META-INF/MANIFEST.MF") as bf:
                        f = io.TextIOWrapper(bf)
                        raw_lines = f.readlines()
                        previous_k = None
                        for line in raw_lines:
                            if line.startswith(" "):
                                assert previous_k is not None
                                manifest[previous_k] += line.strip()
                            elif line == "\n":
                                pass
                            else:
                                k, v = line.rstrip().split(":", 1)
                                manifest[k] = v.lstrip()
                                previous_k = k
            except FileNotFoundError:
                pass
            except KeyError:
                pass
            else:
                basename = os.path.basename(c)
                title = manifest.get("Implementation-Title", "Unknown")
                version = manifest.get("Implementation-Version", "Unknown")
                logger.info("Adjust provider jar: {basename}, {title}, {version}".format(**locals()))
<commit_msg>Make log format more readable<commit_after>import asyncio
import io
import logging
import os
import zipfile

from .. import asutil
from .. import exception

logger = logging.getLogger(__name__)

expect_ok = asutil.expect_ok_closure(exception.AdjustCommandError)

stdout_options = asutil.process_stdout_options
stderr_options = asutil.process_stderr_options

# This provider MAY be "extended" by other providers.
def get_process_provider(execution_name, cmd, get_result_data=None, log_context_option=None, send_log=False):
    @asyncio.coroutine
    def get_result_data_default(work_dir):
        return {}

    get_result_data = get_result_data if get_result_data is not None else get_result_data_default

    @asyncio.coroutine
    def adjust(repo_dir, extra_adjust_parameters, adjust_result):
        nonlocal execution_name
        logger.info('Executing "{execution_name}" using (sub)process adjust provider as "{cmd}".'.format(**locals()))
        log_executable_info(cmd)
        filled_cmd = [p.format(repo_dir=repo_dir) if p.startswith("{repo_dir}") else p for p in cmd]

        # log_context = getattr(asyncio.Task.current_task(), "log_context", None)
        # if log_context_option is None:
        #     if log_context is None:
        #         env = None
        #     else:
        #         env = {
        #             "LOG_CONTEXT": asyncio.Task.current_task().log_context,
        #         }
        # else:
        #     env = None
        #     if log_context is not None:
        #         filled_cmd.append(log_context_option)
        #         filled_cmd.append(log_context)
        env = None
        stdout = None
        try:
            stdout = yield from expect_ok(
                cmd=filled_cmd,
                desc="Adjust subprocess failed.",
                cwd=repo_dir,
                env=env,
                stdout=stdout_options["lines"] if send_log else stdout_options["ignore"],
                stderr=stderr_options["stdout"] if send_log else stderr_options["log_on_error"],
            )
        except exception.CommandError as e:
            logger.error('Adjust subprocess failed, exited code "{e.exit_code}"'.format(**locals()))
            raise

        logger.info("Adjust subprocess exited OK!")

        adjust_result_data = {}
        # TODO adjust_result_data["stdout"] = stdout
        if stdout:
            logger.info("Output:")
            logger.info('\n'.join(stdout))
        else:
            logger.info("No Output")

        adjust_result_data["adjustType"] = execution_name
        adjust_result_data["resultData"] = yield from get_result_data(repo_dir)
        return adjust_result_data

    return adjust

#
# Utility
#

def log_executable_info(cmd):
    first = True
    for c in cmd:
        if c.endswith(".jar"):
            manifest = {}
            try:
                with zipfile.ZipFile(c) as z:
                    with z.open("META-INF/MANIFEST.MF") as bf:
                        f = io.TextIOWrapper(bf)
                        raw_lines = f.readlines()
                        previous_k = None
                        for line in raw_lines:
                            if line.startswith(" "):
                                assert previous_k is not None
                                manifest[previous_k] += line.strip()
                            elif line == "\n":
                                pass
                            else:
                                k, v = line.rstrip().split(":", 1)
                                manifest[k] = v.lstrip()
                                previous_k = k
            except FileNotFoundError:
                pass
            except KeyError:
                pass
            else:
                basename = os.path.basename(c)
                title = manifest.get("Implementation-Title", "Unknown")
                version = manifest.get("Implementation-Version", "Unknown")
                logger.info("Adjust provider jar: {basename}, {title}, {version}".format(**locals()))
<|endoftext|>


<commit_before>import os
import codecs

from setuptools import setup, find_packages

import slackviewer

def read(filename):
    """Read and return `filename` in root dir of project and return string"""
    here = os.path.abspath(os.path.dirname(__file__))
    return codecs.open(os.path.join(here, filename), 'r').read()

install_requires = read("requirements.txt").split()
long_description = read('README.md')

setup(
    name="slack-export-viewer",
    version=slackviewer.__version__,
    url='https://github.com/hfaran/slack-export-viewer',
    license='MIT License',
    author='Hamza Faran',
    author_email='hamzafaran@outlook.com',
    description=('Slack Export Archive Viewer'),
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=find_packages(),
    install_requires=install_requires,
    entry_points={'console_scripts': [
        'slack-export-viewer = slackviewer.main:main',
        'slack-export-viewer-cli = slackviewer.cli:cli'
    ]},
    include_package_data=True,
    # https://github.com/mitsuhiko/flask/issues/1562
    zip_safe=False,
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Environment :: Console',
        'Environment :: Web Environment',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
    ],
)
<commit_msg>Use UTF-8 encoding for setup.py read()<commit_after>import os
import codecs

from setuptools import setup, find_packages

import slackviewer

def read(filename):
    """Read and return `filename` in root dir of project and return string"""
    here = os.path.abspath(os.path.dirname(__file__))
    return codecs.open(os.path.join(here, filename), 'r', encoding='UTF-8').read()

install_requires = read("requirements.txt").split()
long_description = read('README.md')

setup(
    name="slack-export-viewer",
    version=slackviewer.__version__,
    url='https://github.com/hfaran/slack-export-viewer',
    license='MIT License',
    author='Hamza Faran',
    author_email='hamzafaran@outlook.com',
    description=('Slack Export Archive Viewer'),
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=find_packages(),
    install_requires=install_requires,
    entry_points={'console_scripts': [
        'slack-export-viewer = slackviewer.main:main',
        'slack-export-viewer-cli = slackviewer.cli:cli'
    ]},
    include_package_data=True,
    # https://github.com/mitsuhiko/flask/issues/1562
    zip_safe=False,
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Environment :: Console',
        'Environment :: Web Environment',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
    ],
)
<|endoftext|>


<commit_before>"""Classes to wrap cached response objects"""
from datetime import datetime, timedelta, timezone
from logging import getLogger
from typing import TYPE_CHECKING, List, Optional, Tuple, Union

from attr import define, field
from requests import Response as OriginalResponse
from requests.cookies import RequestsCookieJar
from requests.structures import CaseInsensitiveDict

from ..cache_control import ExpirationTime, get_expiration_datetime
from . import CachedHTTPResponse, CachedRequest

DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z'  # Format used for __str__ only
DO_NOT_CACHE = 0

# Make a slotted copy of requests.Response to subclass
Response = define(slots=True)(OriginalResponse)
HeaderList = List[Tuple[str, str]]

logger = getLogger(__name__)

@define(auto_attribs=False)
class CachedResponse(Response):  # type: ignore
    """A serializable dataclass that emulates :py:class:`requests.Response`. Public attributes and
    methods on CachedResponse objects will behave the same as those from the original response, but
    with different internals optimized for serialization.

    This means doing some pre- and post-initialization steps common to all serializers, such as
    breaking nested objects down into their basic attributes and lazily re-initializing them, which
    saves a bit of memory and deserialization steps when those objects aren't accessed.
    """

    _content: bytes = field(default=None)
    url: str = field(default=None)
    status_code: int = field(default=0)
    cookies: RequestsCookieJar = field(factory=RequestsCookieJar)
    created_at: datetime = field(factory=datetime.utcnow)
    elapsed: timedelta = field(factory=timedelta)
    expires: Optional[datetime] = field(default=None)
    encoding: str = field(default=None)
    headers: CaseInsensitiveDict = field(factory=dict)
    history: List['CachedResponse'] = field(factory=list)
    reason: str = field(default=None)
    request: CachedRequest = field(factory=CachedRequest)
    raw: CachedHTTPResponse = field(factory=CachedHTTPResponse, repr=False)

    def __attrs_post_init__(self):
        """Re-initialize raw response body after deserialization"""
        if self.raw._body is None and self._content is not None:
            self.raw.reset(self._content)

    @classmethod
    def from_response(cls, original_response: OriginalResponse, **kwargs):
        """Create a CachedResponse based on an original response object"""
        obj = cls(**kwargs)

        # Copy basic attributes
        for k in Response.__attrs__:
            setattr(obj, k, getattr(original_response, k, None))

        # Store request and raw response
        obj.request = CachedRequest.from_request(original_response.request)
        obj.raw = CachedHTTPResponse.from_response(original_response)

        # Store response body, which will have been read & decoded by requests.Response by now
        obj._content = original_response.content

        # Copy redirect history, if any; avoid recursion by not copying redirects of redirects
        obj.history = []
        if not obj.is_redirect:
            for redirect in original_response.history:
                obj.history.append(cls.from_response(redirect))

        return obj

    @property
    def _content_consumed(self):
        """For compatibility with Response; will always be True for a cached response"""
        return True

    @_content_consumed.setter
    def _content_consumed(self, value):
        pass

    @property
    def from_cache(self) -> bool:
        return True

    @property
    def is_expired(self) -> bool:
        """Determine if this cached response is expired"""
        return self.expires is not None and datetime.utcnow() >= self.expires

    def revalidate(self, expire_after: ExpirationTime) -> bool:
        """Set a new expiration for this response, and determine if it is now expired"""
        self.expires = get_expiration_datetime(expire_after)
        return self.is_expired

    def reset(self):
        if self.raw:
            self.raw.reset()

    @property
    def size(self) -> int:
        """Get the size of the response body in bytes"""
        return len(self.content) if self.content else 0

    def __str__(self):
        return (
            f'request: {self.request}, response: {self.status_code} '
            f'({format_file_size(self.size)}), created: {format_datetime(self.created_at)}, '
            f'expires: {format_datetime(self.expires)} ({"stale" if self.is_expired else "fresh"})'
        )

def format_datetime(value: Optional[datetime]) -> str:
    """Get a formatted datetime string in the local time zone"""
    if not value:
        return "N/A"
    if value.tzinfo is None:
        value = value.replace(tzinfo=timezone.utc)
    return value.astimezone().strftime(DATETIME_FORMAT)

def format_file_size(n_bytes: int) -> str:
    """Convert a file size in bytes into a human-readable format"""
    filesize = float(n_bytes or 0)

    def _format(unit):
        return f'{int(filesize)} {unit}' if unit == 'bytes' else f'{filesize:.2f} {unit}'

    for unit in ['bytes', 'KiB', 'MiB', 'GiB']:
        if filesize < 1024 or unit == 'GiB':
            return _format(unit)
        filesize /= 1024

    if TYPE_CHECKING:
        return _format(unit)

def set_response_defaults(
    response: Union[OriginalResponse, CachedResponse]
) -> Union[OriginalResponse, CachedResponse]:
    """Set some default CachedResponse values on a requests.Response object, so they can be
    expected to always be present
    """
    if not isinstance(response, CachedResponse):
        response.created_at = None  # type: ignore
        response.expires = None  # type: ignore
        response.from_cache = False  # type: ignore
        response.is_expired = False  # type: ignore
    return response
<commit_msg>Make CachedResponse a non-slotted class to allow client code to set arbitrary attributes on it<commit_after>"""Classes to wrap cached response objects"""
from datetime import datetime, timedelta, timezone
from logging import getLogger
from typing import TYPE_CHECKING, List, Optional, Tuple, Union

from attr import define, field
from requests import PreparedRequest, Response
from requests.cookies import RequestsCookieJar
from requests.structures import CaseInsensitiveDict

from ..cache_control import ExpirationTime, get_expiration_datetime
from . import CachedHTTPResponse, CachedRequest

DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z'  # Format used for __str__ only
HeaderList = List[Tuple[str, str]]
logger = getLogger(__name__)

@define(auto_attribs=False, slots=False)
class CachedResponse(Response):
    """A serializable dataclass that emulates :py:class:`requests.Response`. Public attributes and
    methods on CachedResponse objects will behave the same as those from the original response, but
    with different internals optimized for serialization.

    This means doing some pre- and post-initialization steps common to all serializers, such as
    breaking nested objects down into their basic attributes and lazily re-initializing them, which
    saves a bit of memory and deserialization steps when those objects aren't accessed.
    """

    _content: bytes = field(default=None)
    url: str = field(default=None)
    status_code: int = field(default=0)
    cookies: RequestsCookieJar = field(factory=RequestsCookieJar)
    created_at: datetime = field(factory=datetime.utcnow)
    elapsed: timedelta = field(factory=timedelta)
    expires: Optional[datetime] = field(default=None)
    encoding: str = field(default=None)
    headers: CaseInsensitiveDict = field(factory=dict)
    history: List['CachedResponse'] = field(factory=list)
    reason: str = field(default=None)
    request: CachedRequest = field(factory=CachedRequest)
    raw: CachedHTTPResponse = field(factory=CachedHTTPResponse, repr=False)

    def __attrs_post_init__(self):
        """Re-initialize raw response body after deserialization"""
        if self.raw._body is None and self._content is not None:
            self.raw.reset(self._content)

    @classmethod
    def from_response(cls, original_response: Response, **kwargs):
        """Create a CachedResponse based on an original response object"""
        obj = cls(**kwargs)

        # Copy basic attributes
        for k in Response.__attrs__:
            setattr(obj, k, getattr(original_response, k, None))

        # Store request and raw response
        obj.request = CachedRequest.from_request(original_response.request)
        obj.raw = CachedHTTPResponse.from_response(original_response)

        # Store response body, which will have been read & decoded by requests.Response by now
        obj._content = original_response.content

        # Copy redirect history, if any; avoid recursion by not copying redirects of redirects
        obj.history = []
        if not obj.is_redirect:
            for redirect in original_response.history:
                obj.history.append(cls.from_response(redirect))

        return obj

    @property
    def _content_consumed(self):
        """For compatibility with Response; will always be True for a cached response"""
        return True

    @_content_consumed.setter
    def _content_consumed(self, value):
        pass

    @property
    def from_cache(self) -> bool:
        return True

    @property
    def is_expired(self) -> bool:
        """Determine if this cached response is expired"""
        return self.expires is not None and datetime.utcnow() >= self.expires

    def revalidate(self, expire_after: ExpirationTime) -> bool:
        """Set a new expiration for this response, and determine if it is now expired"""
        self.expires = get_expiration_datetime(expire_after)
        return self.is_expired

    def reset(self):
        if self.raw:
            self.raw.reset()

    @property
    def size(self) -> int:
        """Get the size of the response body in bytes"""
        return len(self.content) if self.content else 0

    def __str__(self):
        return (
            f'request: {self.request}, response: {self.status_code} '
            f'({format_file_size(self.size)}), created: {format_datetime(self.created_at)}, '
            f'expires: {format_datetime(self.expires)} ({"stale" if self.is_expired else "fresh"})'
        )

def format_datetime(value: Optional[datetime]) -> str:
    """Get a formatted datetime string in the local time zone"""
    if not value:
        return "N/A"
    if value.tzinfo is None:
        value = value.replace(tzinfo=timezone.utc)
    return value.astimezone().strftime(DATETIME_FORMAT)

def format_file_size(n_bytes: int) -> str:
    """Convert a file size in bytes into a human-readable format"""
    filesize = float(n_bytes or 0)

    def _format(unit):
        return f'{int(filesize)} {unit}' if unit == 'bytes' else f'{filesize:.2f} {unit}'

    for unit in ['bytes', 'KiB', 'MiB', 'GiB']:
        if filesize < 1024 or unit == 'GiB':
            return _format(unit)
        filesize /= 1024

    if TYPE_CHECKING:
        return _format(unit)

def set_response_defaults(response: Union[Response, CachedResponse]) -> Union[Response, CachedResponse]:
    """Set some default CachedResponse values on a requests.Response object, so they can be
    expected to always be present
    """
    if not isinstance(response, CachedResponse):
        response.created_at = None  # type: ignore
        response.expires = None  # type: ignore
        response.from_cache = False  # type: ignore
        response.is_expired = False  # type: ignore
    return response
<|endoftext|>


<commit_before>import os
import sys
from setuptools import setup
from setuptools.command.test import test as TestCommand

test_args = [
    '-n 0',
    '--verbose',
    '--capture=sys',
    '--log-level=INFO',
    '--log-cli-level=INFO',
    '--log-file-level=INFO',
    '--no-flaky-report',
    '--timeout=300',
    '--cov-report=html',
    '--cov-report=term',
    '--cov-report=xml',
    '--cov=slm_lab/agent',
    '--cov=slm_lab/env',
    '--cov=slm_lab/experiment',
    '--cov=slm_lab/lib',
    '--cov=slm_lab/spec',
    '--ignore=test/agent/net',
    'test',
]

class PyTest(TestCommand):
    user_options = [('pytest-args=', 'a', 'Arguments to pass to py.test')]

    def initialize_options(self):
        os.environ['PY_ENV'] = 'test'
        TestCommand.initialize_options(self)
        self.pytest_args = test_args

    def run_tests(self):
        import pytest
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

setup(
    name='slm_lab',
    version='2.1.2',
    description='Modular Deep Reinforcement Learning framework in PyTorch.',
    long_description='https://github.com/kengz/slm_lab',
    keywords='SLM Lab',
    url='https://github.com/kengz/slm_lab',
    author='kengz,lgraesser',
    author_email='kengzwl@gmail.com',
    license='MIT',
    packages=[],
    zip_safe=False,
    include_package_data=True,
    dependency_links=[],
    extras_require={
        'dev': [],
        'docs': [],
        'testing': []
    },
    classifiers=[],
    test_suite='test',
    cmdclass={'test': PyTest},
)
<commit_msg>coverage<commit_after>import os
import sys
from setuptools import setup
from setuptools.command.test import test as TestCommand

test_args = [
    '-n 0',
    '--verbose',
    '--capture=sys',
    '--log-level=INFO',
    '--log-cli-level=INFO',
    '--log-file-level=INFO',
    '--no-flaky-report',
    '--timeout=300',
    '--cov-report=html',
    '--cov-report=term',
    '--cov-report=xml',
    '--cov=slm_lab',
    '--ignore=test/agent/net',
    'test',
]

class PyTest(TestCommand):
    user_options = [('pytest-args=', 'a', 'Arguments to pass to py.test')]

    def initialize_options(self):
        os.environ['PY_ENV'] = 'test'
        TestCommand.initialize_options(self)
        self.pytest_args = test_args

    def run_tests(self):
        import pytest
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

setup(
    name='slm_lab',
    version='2.1.2',
    description='Modular Deep Reinforcement Learning framework in PyTorch.',
    long_description='https://github.com/kengz/slm_lab',
    keywords='SLM Lab',
    url='https://github.com/kengz/slm_lab',
    author='kengz,lgraesser',
    author_email='kengzwl@gmail.com',
    license='MIT',
    packages=[],
    zip_safe=False,
    include_package_data=True,
    dependency_links=[],
    extras_require={
        'dev': [],
        'docs': [],
        'testing': []
    },
    classifiers=[],
    test_suite='test',
    cmdclass={'test': PyTest},
)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2019 GEM Foundation
#
# OpenQuake 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.
#
# OpenQuake 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 OpenQuake. If not, see <http://www.gnu.org/licenses/>.

import os
import re
import shutil
import logging
import tempfile
import unittest
import sys

import numpy

from openquake.calculators import base
from openquake.baselib import datastore, general
from openquake.commonlib import readinput, oqvalidation

NOT_DARWIN = sys.platform != 'darwin'

class DifferentFiles(Exception):
    pass

def strip_calc_id(fname):
    name = os.path.basename(fname)
    return re.sub(r'_\d+\.', '.', name)

def columns(line):
    data = []
    if ',' in line:  # csv file
        for column in line.split(','):
            try:
                floats = list(map(float, column.split(' ')))
            except ValueError:  # skip header
                pass
            else:
                data.append(numpy.array(floats))
    else:  # txt file
        for column in line.split(' '):
            try:
                data.append(float(column))
            except ValueError:
                pass  # ignore nonfloats
    return data

class CalculatorTestCase(unittest.TestCase):
    OVERWRITE_EXPECTED = False
    edir = None  # will be set to a temporary directory

    @classmethod
    def setUpClass(cls):
        cls.duration = general.AccumDict()

    def get_calc(self, testfile, job_ini, **kw):
        """
        Return the outputs of the calculation as a dictionary
        """
        self.testdir = os.path.dirname(testfile) if os.path.isfile(testfile) \
            else testfile
        inis = [os.path.join(self.testdir, ini) for ini in job_ini.split(',')]
        params = readinput.get_params(inis, **kw)

        oqvalidation.OqParam.calculation_mode.validator.choices = tuple(
            base.calculators)
        oq = oqvalidation.OqParam(**params)
        oq.validate()
        # change this when debugging the test
        return base.calculators(oq)

    def run_calc(self, testfile, job_ini, **kw):
        """
        Return the outputs of the calculation as a dictionary
        """
        inis = job_ini.split(',')
        assert len(inis) in (1, 2), inis
        self.calc = self.get_calc(testfile, inis[0], **kw)
        self.edir = tempfile.mkdtemp()
        with self.calc._monitor:
            result = self.calc.run(export_dir=self.edir)
        duration = {inis[0]: self.calc._monitor.duration}
        if len(inis) == 2:
            hc_id = self.calc.datastore.calc_id
            calc = self.get_calc(
                testfile, inis[1], hazard_calculation_id=str(hc_id), **kw)
            with calc._monitor:
                exported = calc.run(export_dir=self.edir)
                result.update(exported)
            duration[inis[1]] = calc._monitor.duration
            self.calc = calc

        # reopen datastore, since some tests need to export from it
        dstore = datastore.read(self.calc.datastore.calc_id)
        self.calc.datastore = dstore
        self.__class__.duration += duration
        return result

    def execute(self, testfile, job_ini):
        """
        Return the result of the calculation without exporting it
        """
        self.calc = self.get_calc(testfile, job_ini)
        self.calc.pre_execute()
        return self.calc.execute()

    def practicallyEqual(self, line1, line2, delta):
        """
        Compare lines containing numbers up to the given delta
        """
        columns1 = columns(line1)
        columns2 = columns(line2)
        for c1, c2 in zip(columns1, columns2):
            numpy.testing.assert_allclose(c1, c2, atol=delta, rtol=delta)

    def assertEqualFiles(
            self, fname1, fname2, make_comparable=lambda lines: lines,
            delta=None, lastline=None):
        """
        Make sure the expected and actual files have the same content.
        `make_comparable` is a function processing the lines of the
        files to make them comparable. By default it does nothing,
        but in some tests a sorting function is passed, because some
        files can be equal only up to the ordering.
        """
        expected = os.path.abspath(os.path.join(self.testdir, fname1))
        if not os.path.exists(expected) and self.OVERWRITE_EXPECTED:
            expected_dir = os.path.dirname(expected)
            if not os.path.exists(expected_dir):
                os.makedirs(expected_dir)
            open(expected, 'w').write('')
        actual = os.path.abspath(
            os.path.join(self.calc.oqparam.export_dir, fname2))
        expected_lines = make_comparable(open(expected).readlines())
        actual_lines = make_comparable(open(actual).readlines()[:lastline])
        try:
            self.assertEqual(len(expected_lines), len(actual_lines))
            for exp, got in zip(expected_lines, actual_lines):
                if delta:
                    self.practicallyEqual(exp, got, delta)
                else:
                    self.assertEqual(exp, got)
        except AssertionError:
            if self.OVERWRITE_EXPECTED:
                # use this path when the expected outputs have changed
                # for a good reason
                logging.info('overriding %s', expected)
                open(expected, 'w').write(''.join(actual_lines))
            else:
                # normally raise an exception
                raise DifferentFiles('%s %s' % (expected, actual))

    def assertGot(self, expected_content, fname):
        """
        Make sure the content of the exported file is the expected one
        """
        with open(os.path.join(self.calc.oqparam.export_dir, fname)) as actual:
            self.assertEqual(expected_content, actual.read())

    def assertEventsByRlz(self, events_by_rlz):
        """
        Check the distribution of the events by realization index
        """
        n_events = numpy.zeros(self.calc.R, int)
        dic = general.group_array(self.calc.datastore['events'].value, 'rlz')
        for rlzi, events in dic.items():
            n_events[rlzi] = len(events)
        numpy.testing.assert_equal(n_events, events_by_rlz)

    def run(self, result=None):
        res = super().run(result)
        if hasattr(res, 'errors'):
            issues = len(res.errors) + len(res.failures)
        elif getattr(res, '_excinfo'):  # with pytest
            issues = len(res._excinfo)
        else:
            issues = 0
        # remove temporary dir only for success
        if self.edir and not issues:
            shutil.rmtree(self.edir)
        return res

    @classmethod
    def tearDownClass(cls):
        print('durations =', cls.duration)
<commit_msg>[skip hazardlib]<commit_after># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2019 GEM Foundation
#
# OpenQuake 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.
#
# OpenQuake 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 OpenQuake. If not, see <http://www.gnu.org/licenses/>.

import os
import re
import shutil
import logging
import tempfile
import unittest
import sys

import numpy

from openquake.calculators import base
from openquake.baselib import datastore, general
from openquake.commonlib import readinput, oqvalidation

NOT_DARWIN = sys.platform != 'darwin'

class DifferentFiles(Exception):
    pass

def strip_calc_id(fname):
    name = os.path.basename(fname)
    return re.sub(r'_\d+\.', '.', name)

def columns(line):
    data = []
    if ',' in line:  # csv file
        for column in line.split(','):
            try:
                floats = list(map(float, column.split(' ')))
            except ValueError:  # skip header
                pass
            else:
                data.append(numpy.array(floats))
    else:  # txt file
        for column in line.split(' '):
            try:
                data.append(float(column))
            except ValueError:
                pass  # ignore nonfloats
    return data

class CalculatorTestCase(unittest.TestCase):
    OVERWRITE_EXPECTED = False
    edir = None  # will be set to a temporary directory

    @classmethod
    def setUpClass(cls):
        cls.duration = general.AccumDict()

    def get_calc(self, testfile, job_ini, **kw):
        """
        Return the outputs of the calculation as a dictionary
        """
        self.testdir = os.path.dirname(testfile) if os.path.isfile(testfile) \
            else testfile
        inis = [os.path.join(self.testdir, ini) for ini in job_ini.split(',')]
        params = readinput.get_params(inis, **kw)

        oqvalidation.OqParam.calculation_mode.validator.choices = tuple(
            base.calculators)
        oq = oqvalidation.OqParam(**params)
        oq.validate()
        # change this when debugging the test
        return base.calculators(oq)

    def run_calc(self, testfile, job_ini, **kw):
        """
        Return the outputs of the calculation as a dictionary
        """
        inis = job_ini.split(',')
        assert len(inis) in (1, 2), inis
        self.calc = self.get_calc(testfile, inis[0], **kw)
        self.edir = tempfile.mkdtemp()
        with self.calc._monitor:
            result = self.calc.run(export_dir=self.edir)
        duration = {inis[0]: self.calc._monitor.duration}
        if len(inis) == 2:
            hc_id = self.calc.datastore.calc_id
            calc = self.get_calc(
                testfile, inis[1], hazard_calculation_id=str(hc_id), **kw)
            with calc._monitor:
                exported = calc.run(export_dir=self.edir)
                result.update(exported)
            duration[inis[1]] = calc._monitor.duration
            self.calc = calc

        # reopen datastore, since some tests need to export from it
        dstore = datastore.read(self.calc.datastore.calc_id)
        self.calc.datastore = dstore
        self.__class__.duration += duration
        return result

    def execute(self, testfile, job_ini):
        """
        Return the result of the calculation without exporting it
        """
        self.calc = self.get_calc(testfile, job_ini)
        self.calc.pre_execute()
        return self.calc.execute()

    def practicallyEqual(self, line1, line2, delta):
        """
        Compare lines containing numbers up to the given delta
        """
        columns1 = columns(line1)
        columns2 = columns(line2)
        for c1, c2 in zip(columns1, columns2):
            numpy.testing.assert_allclose(c1, c2, atol=delta, rtol=delta)

    def assertEqualFiles(
            self, fname1, fname2, make_comparable=lambda lines: lines,
            delta=None, lastline=None):
        """
        Make sure the expected and actual files have the same content.
        `make_comparable` is a function processing the lines of the
        files to make them comparable. By default it does nothing,
        but in some tests a sorting function is passed, because some
        files can be equal only up to the ordering.
        """
        expected = os.path.abspath(os.path.join(self.testdir, fname1))
        if not os.path.exists(expected) and self.OVERWRITE_EXPECTED:
            expected_dir = os.path.dirname(expected)
            if not os.path.exists(expected_dir):
                os.makedirs(expected_dir)
            open(expected, 'w').write('')
        actual = os.path.abspath(
            os.path.join(self.calc.oqparam.export_dir, fname2))
        expected_lines = [line for line in open(expected)
                          if not line.startswith('#')]
        actual_lines = [line for line in open(actual).readlines()[:lastline]
                        if not line.startswith('#')]
        try:
            self.assertEqual(len(expected_lines), len(actual_lines))
            for exp, got in zip(make_comparable(expected_lines),
                                make_comparable(actual_lines)):
                if delta:
                    self.practicallyEqual(exp, got, delta)
                else:
                    self.assertEqual(exp, got)
        except AssertionError:
            if self.OVERWRITE_EXPECTED:
                # use this path when the expected outputs have changed
                # for a good reason
                logging.info('overriding %s', expected)
                open(expected, 'w').write(''.join(actual_lines))
            else:
                # normally raise an exception
                raise DifferentFiles('%s %s' % (expected, actual))

    def assertGot(self, expected_content, fname):
        """
        Make sure the content of the exported file is the expected one
        """
        with open(os.path.join(self.calc.oqparam.export_dir, fname)) as actual:
            self.assertEqual(expected_content, actual.read())

    def assertEventsByRlz(self, events_by_rlz):
        """
        Check the distribution of the events by realization index
        """
        n_events = numpy.zeros(self.calc.R, int)
        dic = general.group_array(self.calc.datastore['events'].value, 'rlz')
        for rlzi, events in dic.items():
            n_events[rlzi] = len(events)
        numpy.testing.assert_equal(n_events, events_by_rlz)

    def run(self, result=None):
        res = super().run(result)
        if hasattr(res, 'errors'):
            issues = len(res.errors) + len(res.failures)
        elif getattr(res, '_excinfo'):  # with pytest
            issues = len(res._excinfo)
        else:
            issues = 0
        # remove temporary dir only for success
        if self.edir and not issues:
            shutil.rmtree(self.edir)
        return res

    @classmethod
    def tearDownClass(cls):
        print('durations =', cls.duration)
<|endoftext|>


<commit_before>from distutils.core import setup

setup(
    name='PyCyc',
    version='0.0.9',
    author='Eli Bogart',
    author_email='elb87@cornell.edu',
    packages=['pycyc','pycyc.test'],
    description='Python interface to Pathway Tools',
    long_description=open('README.txt').read()
    )
<commit_msg>update version number; add license, url<commit_after>from distutils.core import setup

setup(
    name='PyCyc',
    version='0.0.10',
    author='Eli Bogart',
    author_email='elb87@cornell.edu',
    packages=['pycyc','pycyc.test'],
    url='https://github.com/ebogart/PyCyc',
    license='LICENSE.txt',
    description='Python interface to Pathway Tools',
    long_description=open('README.txt').read()
    )
<|endoftext|>


<commit_before>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2014, GEM Foundation

#  OpenQuake 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.

#  OpenQuake 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 Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

import os
import sys
import time
import signal
import threading

import celery.task.control

from openquake.engine import logs
from openquake.engine.utils import config, general

class MasterKilled(KeyboardInterrupt):
    """
    Exception raised when a job is killed manually or aborted
    by the `openquake.engine.engine.CeleryNodeMonitor`.
    """
    registered_handlers = False  # set when the signal handlers are registered

    @classmethod
    def handle_signal(cls, signum, _stack):
        """
        When a SIGTERM or a SIGABRT is received, raise the MasterKilled
        exception with an appropriate error message.

        :param int signum: the number of the received signal
        :param _stack: the current frame object, ignored
        """
        if signum == signal.SIGTERM:
            msg = 'The openquake master process was killed manually'
        elif signum == signal.SIGABRT:
            msg = ('The openquake master process was killed by the '
                   'CeleryNodeMonitor because some node failed')
        else:
            msg = 'This should never happen'
        raise cls(msg)

    @classmethod
    def register_handlers(cls):
        """
        Register the signal handlers for SIGTERM and SIGABRT
        if they were not registered before.
        """
        if not cls.registered_handlers:  # called only once
            cls.registered_handlers = True
            signal.signal(signal.SIGTERM, cls.handle_signal)
            signal.signal(signal.SIGABRT, cls.handle_signal)

class CeleryNodeMonitor(object):
    """
    Context manager wrapping a block of code with a monitor thread
    checking that the celery nodes are accessible. The check is
    performed periodically by pinging the nodes. If some node fail,
    for instance due to an out of memory error, a SIGABRT signal
    is sent to the master process.

    :param float interval:
        polling interval in seconds
    :param bool no_distribute:
        if True, the CeleryNodeMonitor will do nothing at all
    """
    def __init__(self, no_distribute, interval):
        self.interval = interval
        self.no_distribute = no_distribute
        self.job_running = True
        self.live_nodes = None  # set of live worker nodes
        self.th = None
        MasterKilled.register_handlers()

    def __enter__(self):
        if self.no_distribute:
            return self  # do nothing
        self.live_nodes = set(celery.task.control.inspect().ping() or {})
        if not self.live_nodes:
            print >> sys.stderr, "No live compute nodes, aborting calculation"
            sys.exit(2)
        self.th = threading.Thread(None, self.check_nodes)
        self.th.start()
        return self

    def __exit__(self, etype, exc, tb):
        self.job_running = False
        if self.th:
            self.th.join()

    def check_nodes(self):
        """
        Check that the expected celery nodes are all up. The loop
        continues until the main thread keeps running.
        """
        while self.job_is_running(sleep=self.interval):
            live_nodes = set(celery.task.control.inspect().ping() or {})
            if live_nodes < self.live_nodes:
                dead_nodes = list(self.live_nodes - live_nodes)
                logs.LOG.critical(
                    'Cluster nodes not accessible: %s', dead_nodes)
                terminate = general.str2bool(
                    config.get('celery', 'terminate_job_when_celery_is_down'))
                if terminate:
                    os.kill(os.getpid(), signal.SIGABRT)  # commit suicide

    def job_is_running(self, sleep):
        """
        Check for 100 times during the sleep interval if the flag
        self.job_running becomes false and then exit.
        """
        for _ in range(100):
            if not self.job_running:
                break
            time.sleep(sleep / 100.)
        return self.job_running
<commit_msg>Small fix<commit_after>#  -*- coding: utf-8 -*-
#  vim: tabstop=4 shiftwidth=4 softtabstop=4

#  Copyright (c) 2014, GEM Foundation

#  OpenQuake 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.

#  OpenQuake 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 Affero General Public License
#  along with OpenQuake.  If not, see <http://www.gnu.org/licenses/>.

import os
import sys
import time
import signal
import threading

import celery.task.control

from openquake.engine import logs
from openquake.engine.utils import config, general

class MasterKilled(KeyboardInterrupt):
    """
    Exception raised when a job is killed manually or aborted
    by the `openquake.engine.engine.CeleryNodeMonitor`.
    """
    registered_handlers = False  # set when the signal handlers are registered

    @classmethod
    def handle_signal(cls, signum, _stack):
        """
        When a SIGTERM or a SIGABRT is received, raise the MasterKilled
        exception with an appropriate error message.

        :param int signum: the number of the received signal
        :param _stack: the current frame object, ignored
        """
        if signum == signal.SIGTERM:
            msg = 'The openquake master process was killed manually'
        elif signum == signal.SIGABRT:
            msg = ('The openquake master process was killed by the '
                   'CeleryNodeMonitor because some node failed')
        else:
            msg = 'This should never happen'
        raise cls(msg)

    @classmethod
    def register_handlers(cls):
        """
        Register the signal handlers for SIGTERM and SIGABRT
        if they were not registered before.
        """
        if not cls.registered_handlers:  # called only once
            signal.signal(signal.SIGTERM, cls.handle_signal)
            signal.signal(signal.SIGABRT, cls.handle_signal)
            cls.registered_handlers = True

class CeleryNodeMonitor(object):
    """
    Context manager wrapping a block of code with a monitor thread
    checking that the celery nodes are accessible. The check is
    performed periodically by pinging the nodes. If some node fail,
    for instance due to an out of memory error, a SIGABRT signal
    is sent to the master process.

    :param float interval:
        polling interval in seconds
    :param bool no_distribute:
        if True, the CeleryNodeMonitor will do nothing at all
    """
    def __init__(self, no_distribute, interval):
        self.interval = interval
        self.no_distribute = no_distribute
        self.job_running = True
        self.live_nodes = None  # set of live worker nodes
        self.th = None
        MasterKilled.register_handlers()

    def __enter__(self):
        if self.no_distribute:
            return self  # do nothing
        self.live_nodes = set(celery.task.control.inspect().ping() or {})
        if not self.live_nodes:
            print >> sys.stderr, "No live compute nodes, aborting calculation"
            sys.exit(2)
        self.th = threading.Thread(None, self.check_nodes)
        self.th.start()
        return self

    def __exit__(self, etype, exc, tb):
        self.job_running = False
        if self.th:
            self.th.join()

    def check_nodes(self):
        """
        Check that the expected celery nodes are all up. The loop
        continues until the main thread keeps running.
        """
        while self.job_is_running(sleep=self.interval):
            live_nodes = set(celery.task.control.inspect().ping() or {})
            if live_nodes < self.live_nodes:
                dead_nodes = list(self.live_nodes - live_nodes)
                logs.LOG.critical(
                    'Cluster nodes not accessible: %s', dead_nodes)
                terminate = general.str2bool(
                    config.get('celery', 'terminate_job_when_celery_is_down'))
                if terminate:
                    os.kill(os.getpid(), signal.SIGABRT)  # commit suicide

    def job_is_running(self, sleep):
        """
        Check for 100 times during the sleep interval if the flag
        self.job_running becomes false and then exit.
        """
        for _ in range(100):
            if not self.job_running:
                break
            time.sleep(sleep / 100.)
        return self.job_running
<|endoftext|>


<commit_before>#!/usr/bin/env python
import os
import sys
from distutils.core import setup, Extension
import glob

from runspade import VERSION

#if os.name != "posix":
#	import py2exe
try:
	import bdist_mpkg
except:
	# This is not a mac
	pass

if sys.platform == "win32":
    ext = Extension("tlslite.utils.win32prng",
                    sources=["tlslite/utils/win32prng.c"],
                    libraries=["advapi32"])
    exts = [ext]
else:
    exts = None

if os.name == "posix":
	#if sys.platform != "darwin":
		setup(name='SPADE',
		version=VERSION,
		description='Smart Python multi-Agent Development Environment',
		author='Javi Palanca, Miguel Escriva, Gustavo Aranda',
		author_email='jpalanca@dsic.upv.es',
		url='http://gti-ia.dsic.upv.es/projects/magentix/',
		package_dir={'spade': 'libspade'},
		packages=['spade', 'xmpp', 'xmppd', 'tlslite', 'tlslite.utils', 'tlslite.integration'],
		scripts=['gspade.py', 'spade.py',"tlslite/scripts/tls.py", "tlslite/scripts/tlsdb.py"],
		data_files=[
			('/etc/spade',['etc/spade.xml']),
			('/etc/spade',['etc/xmppd.xml']),
			('/usr/share/spade',['usr/share/spade/rma.glade']),
			('/usr/share/doc/spade',['readme.txt']),
			('/usr/share/doc/spade/',['doc/api.tar.gz']),
			#('/usr/share/spade/jabberd',['usr/share/spade/jabberd/jabberd','usr/share/spade/jabberd/jabber.xml']),
			#('/usr/share/spade/jabberd/libs',glob.glob('usr/share/spade/jabberd/libs/*.so')),
			#('/usr/share/spade/jabberd/spool',['usr/share/spade/jabberd/spool/.spool'])
		]
		)

else:
	setup(name='SPADE',
	version=VERSION,
	description='Smart Python multi-Agent Development Environment',
	author='Javi Palanca, Miguel Escriva, Gustavo Aranda',
	author_email='jpalanca@dsic.upv.es',
	url='http://gti-ia.dsic.upv.es/projects/magentix/',
	package_dir={'spade': 'libspade'},
	packages=['spade', 'xmpp', 'xmppd', 'tlslite', 'tlslite.utils', 'tlslite.integration'],
	#scripts=['spade-rma.py', 'runspade.py'],
	console=['gspade.py', 'spade.py','configure.py',"tlslite/scripts/tls.py", "tlslite/scripts/tlsdb.py"],
	data_files=[
		('etc',[]),
		('usr/share/spade',['usr/share/spade/rma.glade']),
		('.',['readme.txt']),
		#('doc/private',glob.glob('doc/api/private/*')),
		#('doc/public',glob.glob('doc/api/public/*')),
		#('doc',['doc/api/index.html','doc/api/epydoc.css']),
		#('usr/share/spade/jabberd',['usr/share/spade/jabberd/jabberd.exe']),
		#('usr/share/spade/jabberd/libs',glob.glob('usr/share/spade/jabberd/libs/*.dll')),
		#('usr/share/spade/jabberd/spool',[])
		('usr/share/spade/xmppd/spool',[])
	],
        ext_modules=exts
	)

<commit_msg>packaging<commit_after>#!/usr/bin/env python
import os
import sys
from distutils.core import setup, Extension
import glob

from spade import VERSION

#if os.name != "posix":
#	import py2exe
try:
	import bdist_mpkg
except:
	# This is not a mac
	pass

if sys.platform == "win32":
    ext = Extension("tlslite.utils.win32prng",
                    sources=["tlslite/utils/win32prng.c"],
                    libraries=["advapi32"])
    exts = [ext]
else:
    exts = None

if os.name == "posix":
	#if sys.platform != "darwin":
		setup(name='SPADE',
		version=VERSION,
		description='Smart Python multi-Agent Development Environment',
		author='Javi Palanca, Miguel Escriva, Gustavo Aranda',
		author_email='jpalanca@dsic.upv.es',
		url='http://gti-ia.dsic.upv.es/projects/magentix/',
		package_dir={'spade': 'libspade'},
		packages=['spade', 'xmpp', 'xmppd', 'tlslite', 'tlslite.utils', 'tlslite.integration'],
		scripts=['gspade.py', 'spade.py',"tlslite/scripts/tls.py", "tlslite/scripts/tlsdb.py"],
		data_files=[
			('/etc/spade',['etc/spade.xml']),
			('/etc/spade',['etc/xmppd.xml']),
			('/usr/share/spade',['usr/share/spade/rma.glade']),
			('/usr/share/doc/spade',['readme.txt']),
			('/usr/share/doc/spade/',['doc/api.tar.gz']),
			#('/usr/share/spade/jabberd',['usr/share/spade/jabberd/jabberd','usr/share/spade/jabberd/jabber.xml']),
			#('/usr/share/spade/jabberd/libs',glob.glob('usr/share/spade/jabberd/libs/*.so')),
			#('/usr/share/spade/jabberd/spool',['usr/share/spade/jabberd/spool/.spool'])
		]
		)

else:
	setup(name='SPADE',
	version=VERSION,
	description='Smart Python multi-Agent Development Environment',
	author='Javi Palanca, Miguel Escriva, Gustavo Aranda',
	author_email='jpalanca@dsic.upv.es',
	url='http://gti-ia.dsic.upv.es/projects/magentix/',
	package_dir={'spade': 'libspade'},
	packages=['spade', 'xmpp', 'xmppd', 'tlslite', 'tlslite.utils', 'tlslite.integration'],
	#scripts=['spade-rma.py', 'runspade.py'],
	console=['gspade.py', 'spade.py','configure.py',"tlslite/scripts/tls.py", "tlslite/scripts/tlsdb.py"],
	data_files=[
		('etc',[]),
		('usr/share/spade',['usr/share/spade/rma.glade']),
		('.',['readme.txt']),
		#('doc/private',glob.glob('doc/api/private/*')),
		#('doc/public',glob.glob('doc/api/public/*')),
		#('doc',['doc/api/index.html','doc/api/epydoc.css']),
		#('usr/share/spade/jabberd',['usr/share/spade/jabberd/jabberd.exe']),
		#('usr/share/spade/jabberd/libs',glob.glob('usr/share/spade/jabberd/libs/*.dll')),
		#('usr/share/spade/jabberd/spool',[])
		('usr/share/spade/xmppd/spool',[])
	],
        ext_modules=exts
	)

<|endoftext|>