<commit_before># -*- coding: utf-8 -*-

import traceback

from ckan.lib.helpers import json
from ckanext.harvest.model import HarvestObject, HarvestObjectExtra
from ckanext.harvest.harvesters import HarvesterBase
import ckanext.geocat.metadata as md
import ckanext.geocat.xml_loader as loader
from ckan.logic import get_action, NotFound
from ckan.logic.schema import default_create_package_schema
from ckan.lib.navl.validators import ignore
import ckan.plugins.toolkit as tk
from ckan import model
from ckan.model import Session
import uuid

import logging
log = logging.getLogger(__name__)

class GeocatHarvester(HarvesterBase):
    '''
    The harvester for geocat
    '''

    HARVEST_USER = 'harvest'

    def info(self):
        return {
            'name': 'geocat_harvester',
            'title': 'Geocat harvester',
            'description': (
                'Harvests metadata from geocat (CSW)'
            ),
            'form_config_interface': 'Text'
        }

    def _set_config(self, config_str):
        if config_str:
            self.config = json.loads(config_str)
        else:
            self.config = {}

        if 'user' not in self.config:
            self.config['user'] = self.HARVEST_USER

        if 'delete_missing_datasets' not in self.config:
            self.config['delete_missing_datasets'] = False

        log.debug('Using config: %r' % self.config)

    def _find_existing_package(self, package_dict):
        package_show_context = {'model': model, 'session': Session,
                                'ignore_auth': True}

        user = tk.get_action('get_site_user')({'ignore_auth': True}, {})
        package_show_context.update({'user': user['name']})

        param = 'identifier:%s' % package_dict['identifier']
        result = tk.get_action('package_search')(package_show_context,
                                                 {'fq': param})
        try:
            return result['results'][0]
        except (KeyError, IndexError, TypeError):
            raise NotFound

    def gather_stage(self, harvest_job):
        log.debug('In GeocatHarvester gather_stage')

        try:
            self._set_config(harvest_job.source.config)

            if 'organization' not in self.config:
                context = {
                    'model': model,
                    'session': Session,
                    'ignore_auth': True
                }
                source_dataset = get_action('package_show')(
                    context, {'id': harvest_job.source_id})
                self.config['organization'] = source_dataset.get(
                    'organization').get('name')
        except GeocatConfigError, e:
            self._save_gather_error(
                'Config value missing: %s' % str(e),
                harvest_job
            )
            return []

        csw_url = None
        harvest_obj_ids = []
        gathered_dataset_identifiers = []

        try:
            csw_url = harvest_job.source.url.rstrip('/')
            csw = md.CswHelper(url=csw_url)

            cql = self.config.get('cql', None)
            if cql is None:
                cql = "keyword = 'opendata.swiss'"

            log.debug("CQL query: %s" % cql)
            for record_id in csw.get_id_by_search(cql=cql):
                harvest_obj = HarvestObject(
                    guid=record_id,
                    job=harvest_job
                )
                harvest_obj.save()
                harvest_obj_ids.append(harvest_obj.id)
                gathered_dataset_identifiers.append('%s@%s' % (
                    record_id,
                    self.config['organization']
                ))

            log.debug('IDs: %r' % harvest_obj_ids)
        except Exception, e:
            self._save_gather_error(
                'Unable to get content for URL: %s: %s / %s'
                % (csw_url, str(e), traceback.format_exc()),
                harvest_job
            )
            return []

        if self.config['delete_missing_datasets']:
            delete_ids = self._check_for_deleted_datasets(
                harvest_job, gathered_dataset_identifiers
            )
            log.debug('delete_ids: %r' % delete_ids)
            harvest_obj_ids.extend(delete_ids)

        return harvest_obj_ids

    def fetch_stage(self, harvest_object):
        log.debug('In GeocatHarvester fetch_stage')
        self._set_config(harvest_object.job.source.config)

        if not harvest_object:
            log.error('No harvest object received')
            self._save_object_error(
                'No harvest object received',
                harvest_object
            )
            return False

        csw_url = harvest_object.source.url.rstrip('/')
        csw = None
        try:
            csw = md.CswHelper(url=csw_url)
            xml = csw.get_by_id(harvest_object.guid)
            harvest_object.content = xml
            harvest_object.save()
            log.debug('successfully processed ' + harvest_object.guid)
            return True
        except Exception, e:
            response = '-'
            if csw and hasattr(csw.catalog, 'response'):
                response = csw.catalog.response

            self._save_object_error(
                (
                    'Unable to get content for package: %s: %r: %r / %s' %
                    (
                        harvest_object.guid,
                        e,
                        response,
                        traceback.format_exc()
                    )
                ),
                harvest_object
            )
            return False

    def import_stage(self, harvest_object):  # noqa
        log.debug('In GeocatHarvester import_stage')
        self._set_config(harvest_object.job.source.config)

        if not harvest_object:
            log.error('No harvest object received')
            self._save_object_error(
                'No harvest object received',
                harvest_object
            )
            return False

        # check if dataset must be deleted
        import_action = self._get_object_extra(harvest_object, 'import_action')
        if import_action and import_action == 'delete':
            log.debug('import action: %s' % import_action)
            harvest_object.current = False
            return self._delete_dataset({'id': harvest_object.guid})

        try:
            if 'organization' not in self.config:
                context = {
                    'model': model,
                    'session': Session,
                    'ignore_auth': True
                }
                source_dataset = get_action('package_show')(
                    context, {'id': harvest_object.source.id})
                self.config['organization'] = source_dataset.get(
                    'organization').get('name')

            xml_elem = loader.from_string(harvest_object.content)
            dataset_metadata = md.GeocatDcatDatasetMetadata()
            dist_metadata = md.GeocatDcatDistributionMetadata()

            pkg_dict = dataset_metadata.get_metadata(xml_elem)
            dist_list = dist_metadata.get_metadata(xml_elem)

            for dist in dist_list:
                if not dist.get('rights'):
                    dist['rights'] = self.config.get(
                        'rights',
                        'NonCommercialNotAllowed-CommercialNotAllowed-ReferenceRequired'  # noqa
                    )

            pkg_dict['identifier'] = (
                '%s@%s'
                % (pkg_dict['identifier'], self.config['organization'])
            )

            # geocat returns see_alsos as UUID, check if there are
            # datasets from the same organization as the harvester
            existing_see_alsos = []
            for linked_uuid in pkg_dict['see_alsos']:
                try:
                    identifier = '%s@%s' % (
                        linked_uuid,
                        self.config['organization']
                    )
                    check_dict = {'identifier': identifier}
                    self._find_existing_package(check_dict)
                    existing_see_alsos.append({'dataset_identifier': identifier})  # noqa
                except NotFound:
                    continue
            pkg_dict['see_alsos'] = existing_see_alsos

            pkg_dict['owner_org'] = self.config['organization']
            pkg_dict['resources'] = dist_list
            pkg_dict['name'] = self._gen_new_name(pkg_dict['title']['de'])

            # legal basis
            legal_basis_url = self.config.get('legal_basis_url', None)
            if legal_basis_url:
                pkg_dict['relations'].append({
                    'url': legal_basis_url,
                    'label': 'legal_basis'
                })

            log.debug('package dict: %s' % pkg_dict)

            # Change default schema
            schema = default_create_package_schema()
            schema['__junk'] = [ignore]

            package_context = {
                'ignore_auth': True,
                'user': self.config['user'],
                'schema': schema,
            }
            try:
                existing = self._find_existing_package(pkg_dict)
                log.debug(
                    "Existing package found, updating %s..." % existing['id']
                )
                pkg_dict['name'] = existing['name']
                pkg_dict['id'] = existing['id']
                updated_pkg = get_action('package_update')(
                    package_context, pkg_dict)
                harvest_object.current = True
                harvest_object.package_id = updated_pkg['id']
                harvest_object.save()
                log.debug("Updated PKG: %s" % updated_pkg)
            except NotFound:
                log.debug("No package found, create a new one!")

                # generate an id to reference it in the harvest_object
                pkg_dict['id'] = unicode(uuid.uuid4())

                log.info('Package with GUID %s does not exist, '
                         'let\'s create it' % harvest_object.guid)

                harvest_object.current = True
                harvest_object.package_id = pkg_dict['id']
                harvest_object.add()

                model.Session.execute(
                    'SET CONSTRAINTS harvest_object_package_id_fkey DEFERRED')
                model.Session.flush()

                created_pkg = get_action('package_create')(
                    package_context, pkg_dict)

                log.debug("Created PKG: %s" % created_pkg)

            Session.commit()
            return True

        except Exception, e:
            self._save_object_error(
                (
                    'Exception in import stage: %r / %s'
                    % (e, traceback.format_exc())
                ),
                harvest_object
            )
            return False

    def _create_new_context(self):
        # get the site user
        site_user = tk.get_action('get_site_user')(
            {'model': model, 'ignore_auth': True}, {})
        context = {
            'model': model,
            'session': Session,
            'user': site_user['name'],
        }
        return context

    def _get_existing_package_names(self, harvest_job):
        context = self._create_new_context()
        n = 500
        page = 1
        existing_package_names = []
        while True:
            search_params = {
                'fq': 'harvest_source_id:"{0}"'.format(harvest_job.source_id),
                'rows': n,
                'start': n * (page - 1),
            }
            try:
                existing_packages = get_action('package_search')(
                    context, search_params
                )
                if len(existing_packages['results']):
                    existing_package_names.extend(
                        [pkg['name'] for pkg in existing_packages['results']]
                    )
                    page = page + 1
                else:
                    break
            except NotFound:
                if page == 1:
                    log.debug('Could not find pkges for source %s'
                              % harvest_job.source_id)
        log.info('Found %d packages for source %s' %
                 (len(existing_package_names), harvest_job.source_id))
        return existing_package_names

    def _get_package_names_from_identifiers(self, package_identifiers):
        package_names = []
        for identifier in package_identifiers:
            pkg = {'identifier': identifier}
            try:
                existing_package = self._find_existing_package(pkg)
                package_names.append(existing_package['name'])
            except NotFound:
                continue

        return package_names

    def _check_for_deleted_datasets(self, harvest_job,
                                    gathered_dataset_identifiers):
        existing_package_names = self._get_existing_package_names(
            harvest_job
        )
        gathered_existing_package_names = self._get_package_names_from_identifiers(  # noqa
            gathered_dataset_identifiers
        )
        delete_names = list(set(existing_package_names) -
                            set(gathered_existing_package_names))
        # gather delete harvest ids
        delete_ids = []

        for package_name in delete_names:
            log.debug(
                'Dataset `%s` has been deleted at the source' %
                package_name)

            if self.config['delete_missing_datasets']:
                log.info('Add `%s` for deletion', package_name)

                obj = HarvestObject(
                    guid=package_name,
                    job=harvest_job,
                    extras=[HarvestObjectExtra(key='import_action',
                                               value='delete')]
                )
                obj.save()
                log.debug('adding ' + obj.guid + ' to the queue')

                delete_ids.append(obj.id)
        return delete_ids

    def _delete_dataset(self, package_dict):
        log.debug('deleting dataset %s' % package_dict['id'])
        context = self._create_new_context()
        get_action('dataset_purge')(
            context.copy(),
            package_dict
        )
        return True

    def _get_object_extra(self, harvest_object, key):
        for extra in harvest_object.extras:
            if extra.key == key:
                return extra.value
        return None

class GeocatConfigError(Exception):
    pass
<commit_msg>Use update schema for updating<commit_after># -*- coding: utf-8 -*-

import traceback

from ckan.lib.helpers import json
from ckanext.harvest.model import HarvestObject, HarvestObjectExtra
from ckanext.harvest.harvesters import HarvesterBase
import ckanext.geocat.metadata as md
import ckanext.geocat.xml_loader as loader
from ckan.logic import get_action, NotFound
from ckan.logic.schema import default_update_package_schema,\
    default_create_package_schema
from ckan.lib.navl.validators import ignore
import ckan.plugins.toolkit as tk
from ckan import model
from ckan.model import Session
import uuid

import logging
log = logging.getLogger(__name__)

class GeocatHarvester(HarvesterBase):
    '''
    The harvester for geocat
    '''

    HARVEST_USER = 'harvest'

    def info(self):
        return {
            'name': 'geocat_harvester',
            'title': 'Geocat harvester',
            'description': (
                'Harvests metadata from geocat (CSW)'
            ),
            'form_config_interface': 'Text'
        }

    def _set_config(self, config_str):
        if config_str:
            self.config = json.loads(config_str)
        else:
            self.config = {}

        if 'user' not in self.config:
            self.config['user'] = self.HARVEST_USER

        if 'delete_missing_datasets' not in self.config:
            self.config['delete_missing_datasets'] = False

        log.debug('Using config: %r' % self.config)

    def _find_existing_package(self, package_dict):
        package_show_context = {'model': model, 'session': Session,
                                'ignore_auth': True}

        user = tk.get_action('get_site_user')({'ignore_auth': True}, {})
        package_show_context.update({'user': user['name']})

        param = 'identifier:%s' % package_dict['identifier']
        result = tk.get_action('package_search')(package_show_context,
                                                 {'fq': param})
        try:
            return result['results'][0]
        except (KeyError, IndexError, TypeError):
            raise NotFound

    def gather_stage(self, harvest_job):
        log.debug('In GeocatHarvester gather_stage')

        try:
            self._set_config(harvest_job.source.config)

            if 'organization' not in self.config:
                context = {
                    'model': model,
                    'session': Session,
                    'ignore_auth': True
                }
                source_dataset = get_action('package_show')(
                    context, {'id': harvest_job.source_id})
                self.config['organization'] = source_dataset.get(
                    'organization').get('name')
        except GeocatConfigError, e:
            self._save_gather_error(
                'Config value missing: %s' % str(e),
                harvest_job
            )
            return []

        csw_url = None
        harvest_obj_ids = []
        gathered_dataset_identifiers = []

        try:
            csw_url = harvest_job.source.url.rstrip('/')
            csw = md.CswHelper(url=csw_url)

            cql = self.config.get('cql', None)
            if cql is None:
                cql = "keyword = 'opendata.swiss'"

            log.debug("CQL query: %s" % cql)
            for record_id in csw.get_id_by_search(cql=cql):
                harvest_obj = HarvestObject(
                    guid=record_id,
                    job=harvest_job
                )
                harvest_obj.save()
                harvest_obj_ids.append(harvest_obj.id)
                gathered_dataset_identifiers.append('%s@%s' % (
                    record_id,
                    self.config['organization']
                ))

            log.debug('IDs: %r' % harvest_obj_ids)
        except Exception, e:
            self._save_gather_error(
                'Unable to get content for URL: %s: %s / %s'
                % (csw_url, str(e), traceback.format_exc()),
                harvest_job
            )
            return []

        if self.config['delete_missing_datasets']:
            delete_ids = self._check_for_deleted_datasets(
                harvest_job, gathered_dataset_identifiers
            )
            log.debug('delete_ids: %r' % delete_ids)
            harvest_obj_ids.extend(delete_ids)

        return harvest_obj_ids

    def fetch_stage(self, harvest_object):
        log.debug('In GeocatHarvester fetch_stage')
        self._set_config(harvest_object.job.source.config)

        if not harvest_object:
            log.error('No harvest object received')
            self._save_object_error(
                'No harvest object received',
                harvest_object
            )
            return False

        csw_url = harvest_object.source.url.rstrip('/')
        csw = None
        try:
            csw = md.CswHelper(url=csw_url)
            xml = csw.get_by_id(harvest_object.guid)
            harvest_object.content = xml
            harvest_object.save()
            log.debug('successfully processed ' + harvest_object.guid)
            return True
        except Exception, e:
            response = '-'
            if csw and hasattr(csw.catalog, 'response'):
                response = csw.catalog.response

            self._save_object_error(
                (
                    'Unable to get content for package: %s: %r: %r / %s' %
                    (
                        harvest_object.guid,
                        e,
                        response,
                        traceback.format_exc()
                    )
                ),
                harvest_object
            )
            return False

    def import_stage(self, harvest_object):  # noqa
        log.debug('In GeocatHarvester import_stage')
        self._set_config(harvest_object.job.source.config)

        if not harvest_object:
            log.error('No harvest object received')
            self._save_object_error(
                'No harvest object received',
                harvest_object
            )
            return False

        # check if dataset must be deleted
        import_action = self._get_object_extra(harvest_object, 'import_action')
        if import_action and import_action == 'delete':
            log.debug('import action: %s' % import_action)
            harvest_object.current = False
            return self._delete_dataset({'id': harvest_object.guid})

        try:
            if 'organization' not in self.config:
                context = {
                    'model': model,
                    'session': Session,
                    'ignore_auth': True
                }
                source_dataset = get_action('package_show')(
                    context, {'id': harvest_object.source.id})
                self.config['organization'] = source_dataset.get(
                    'organization').get('name')

            xml_elem = loader.from_string(harvest_object.content)
            dataset_metadata = md.GeocatDcatDatasetMetadata()
            dist_metadata = md.GeocatDcatDistributionMetadata()

            pkg_dict = dataset_metadata.get_metadata(xml_elem)
            dist_list = dist_metadata.get_metadata(xml_elem)

            for dist in dist_list:
                if not dist.get('rights'):
                    dist['rights'] = self.config.get(
                        'rights',
                        'NonCommercialNotAllowed-CommercialNotAllowed-ReferenceRequired'  # noqa
                    )

            pkg_dict['identifier'] = (
                '%s@%s'
                % (pkg_dict['identifier'], self.config['organization'])
            )

            # geocat returns see_alsos as UUID, check if there are
            # datasets from the same organization as the harvester
            existing_see_alsos = []
            for linked_uuid in pkg_dict['see_alsos']:
                try:
                    identifier = '%s@%s' % (
                        linked_uuid,
                        self.config['organization']
                    )
                    check_dict = {'identifier': identifier}
                    self._find_existing_package(check_dict)
                    existing_see_alsos.append({'dataset_identifier': identifier})  # noqa
                except NotFound:
                    continue
            pkg_dict['see_alsos'] = existing_see_alsos

            pkg_dict['owner_org'] = self.config['organization']
            pkg_dict['resources'] = dist_list
            pkg_dict['name'] = self._gen_new_name(pkg_dict['title']['de'])

            # legal basis
            legal_basis_url = self.config.get('legal_basis_url', None)
            if legal_basis_url:
                pkg_dict['relations'].append({
                    'url': legal_basis_url,
                    'label': 'legal_basis'
                })

            log.debug('package dict: %s' % pkg_dict)

            package_context = {
                'ignore_auth': True,
                'user': self.config['user'],
            }
            try:
                # Change default schema to ignore lists of dicts, which
                # are stored in the '__junk' field
                schema = default_update_package_schema()
                schema['__junk'] = [ignore]

                package_context['schema'] = schema

                existing = self._find_existing_package(pkg_dict)
                log.debug(
                    "Existing package found, updating %s..." % existing['id']
                )
                pkg_dict['name'] = existing['name']
                pkg_dict['id'] = existing['id']
                updated_pkg = get_action('package_update')(
                    package_context, pkg_dict)
                harvest_object.current = True
                harvest_object.package_id = updated_pkg['id']
                harvest_object.save()
                log.debug("Updated PKG: %s" % updated_pkg)
            except NotFound:
                # Change default schema to ignore lists of dicts, which
                # are stored in the '__junk' field
                schema = default_create_package_schema()
                schema['__junk'] = [ignore]

                package_context['schema'] = schema

                log.debug("No package found, create a new one!")

                # generate an id to reference it in the harvest_object
                pkg_dict['id'] = unicode(uuid.uuid4())

                log.info('Package with GUID %s does not exist, '
                         'let\'s create it' % harvest_object.guid)

                harvest_object.current = True
                harvest_object.package_id = pkg_dict['id']
                harvest_object.add()

                model.Session.execute(
                    'SET CONSTRAINTS harvest_object_package_id_fkey DEFERRED')
                model.Session.flush()

                created_pkg = get_action('package_create')(
                    package_context, pkg_dict)

                log.debug("Created PKG: %s" % created_pkg)

            Session.commit()
            return True

        except Exception, e:
            self._save_object_error(
                (
                    'Exception in import stage: %r / %s'
                    % (e, traceback.format_exc())
                ),
                harvest_object
            )
            return False

    def _create_new_context(self):
        # get the site user
        site_user = tk.get_action('get_site_user')(
            {'model': model, 'ignore_auth': True}, {})
        context = {
            'model': model,
            'session': Session,
            'user': site_user['name'],
        }
        return context

    def _get_existing_package_names(self, harvest_job):
        context = self._create_new_context()
        n = 500
        page = 1
        existing_package_names = []
        while True:
            search_params = {
                'fq': 'harvest_source_id:"{0}"'.format(harvest_job.source_id),
                'rows': n,
                'start': n * (page - 1),
            }
            try:
                existing_packages = get_action('package_search')(
                    context, search_params
                )
                if len(existing_packages['results']):
                    existing_package_names.extend(
                        [pkg['name'] for pkg in existing_packages['results']]
                    )
                    page = page + 1
                else:
                    break
            except NotFound:
                if page == 1:
                    log.debug('Could not find pkges for source %s'
                              % harvest_job.source_id)
        log.info('Found %d packages for source %s' %
                 (len(existing_package_names), harvest_job.source_id))
        return existing_package_names

    def _get_package_names_from_identifiers(self, package_identifiers):
        package_names = []
        for identifier in package_identifiers:
            pkg = {'identifier': identifier}
            try:
                existing_package = self._find_existing_package(pkg)
                package_names.append(existing_package['name'])
            except NotFound:
                continue

        return package_names

    def _check_for_deleted_datasets(self, harvest_job,
                                    gathered_dataset_identifiers):
        existing_package_names = self._get_existing_package_names(
            harvest_job
        )
        gathered_existing_package_names = self._get_package_names_from_identifiers(  # noqa
            gathered_dataset_identifiers
        )
        delete_names = list(set(existing_package_names) -
                            set(gathered_existing_package_names))
        # gather delete harvest ids
        delete_ids = []

        for package_name in delete_names:
            log.debug(
                'Dataset `%s` has been deleted at the source' %
                package_name)

            if self.config['delete_missing_datasets']:
                log.info('Add `%s` for deletion', package_name)

                obj = HarvestObject(
                    guid=package_name,
                    job=harvest_job,
                    extras=[HarvestObjectExtra(key='import_action',
                                               value='delete')]
                )
                obj.save()
                log.debug('adding ' + obj.guid + ' to the queue')

                delete_ids.append(obj.id)
        return delete_ids

    def _delete_dataset(self, package_dict):
        log.debug('deleting dataset %s' % package_dict['id'])
        context = self._create_new_context()
        get_action('dataset_purge')(
            context.copy(),
            package_dict
        )
        return True

    def _get_object_extra(self, harvest_object, key):
        for extra in harvest_object.extras:
            if extra.key == key:
                return extra.value
        return None

class GeocatConfigError(Exception):
    pass
<|endoftext|>


<commit_before># accepts 0,1, or 2 arguments. If a string starting with a number is handed in, it is assumed to be a subdirectory of the current directory to run on. If not specified, the newest build is used. Any other string is taken as the branch name for this test (or treated as mainline). Order of the arguments does not matter.
# for questions: Timo Heister

import xml.etree.ElementTree as ET
import glob
import sys
from datetime import datetime
import subprocess

class Group:
    def __init__(self, name):
        self.name = name
        self.n_tests = 0
        self.n_fail = 0
        self.fail = []
        self.fail_text = {}

class Revision:
    def __init__(self):
        self.groups = {}
        self.number = -1
        self.name = ''
        self.n_tests = 0
        self.n_fail = 0

branch=''
args=sys.argv
args.pop(0)

dirname=""
while len(args)>0:
    if args[0].startswith("20"): #I hope this script is not used in the year 2100
        dirname=args[0].replace('/','')
    else:
        branch=args[0].replace('/','')+'/'
    args.pop(0)

if len(glob.glob(dirname+'/Update.xml'))>0:
    #new format
    tree = ET.parse(dirname+'/Update.xml')
    name = tree.getroot().find('BuildName').text
    number = tree.getroot().find('Revision').text
    date = datetime.strptime(dirname,"%Y%m%d-%H%M")
else:
    #old format
    tree = ET.parse(dirname+'/Notes.xml')
    name = tree.getroot().attrib['BuildName']
    number = name.split('-')[-1]
    number = number[1:]
    date = datetime.strptime(dirname,"%Y%m%d-%H%M")

print "Revision: %s"%number
print "Date: %s"%(date.strftime("%Y %j  %F  %U-%w"))
#print "Id:  %s"%name
id = subprocess.check_output(["id","-un"])+'@'+subprocess.check_output(["hostname"])
id=id.replace('\n','')
print "Id:  %s"%id

#now Test.xml:
tree = ET.parse(dirname+'/Test.xml')
root = tree.getroot()
testing = root.find('Testing')

for test in testing.findall("Test"):
    status = test.attrib['Status']
    fail=False
    if status=="failed": fail=True
    name = test.find('Name').text

    if fail:
        print "%s  3   %s%s"%(date,branch,name)
    else:
        print "%s   +  %s%s"%(date,branch,name)

<commit_msg>grouping and repeat header<commit_after># accepts 0,1, or 2 arguments. If a string starting with a number is handed in, it is assumed to be a subdirectory of the current directory to run on. If not specified, the newest build is used. Any other string is taken as the branch name for this test (or treated as mainline). Order of the arguments does not matter.
# for questions: Timo Heister

import xml.etree.ElementTree as ET
import glob
import sys
from datetime import datetime
import subprocess

class Group:
    def __init__(self, name):
        self.name = name
        self.n_tests = 0
        self.n_fail = 0
        self.fail = []
        self.fail_text = {}

class Revision:
    def __init__(self):
        self.groups = {}
        self.number = -1
        self.name = ''
        self.n_tests = 0
        self.n_fail = 0

branch=''
args=sys.argv
args.pop(0)

dirname=""
while len(args)>0:
    if args[0].startswith("20"): #I hope this script is not used in the year 2100
        dirname=args[0].replace('/','')
    else:
        branch=args[0].replace('/','')+'/'
    args.pop(0)

if len(glob.glob(dirname+'/Update.xml'))>0:
    #new format
    tree = ET.parse(dirname+'/Update.xml')
    name = tree.getroot().find('BuildName').text
    number = tree.getroot().find('Revision').text
    date = datetime.strptime(dirname,"%Y%m%d-%H%M")
else:
    #old format
    tree = ET.parse(dirname+'/Notes.xml')
    name = tree.getroot().attrib['BuildName']
    number = name.split('-')[-1]
    number = number[1:]
    date = datetime.strptime(dirname,"%Y%m%d-%H%M")

header = "Revision: %s"%number + "\n"
header += "Date: %s"%(date.strftime("%Y %j  %F  %U-%w")) + '\n'
id = subprocess.check_output(["id","-un"])+'@'+subprocess.check_output(["hostname"])
id=id.replace('\n','')
header += "Id:  %s"%id

#now Test.xml:
tree = ET.parse(dirname+'/Test.xml')
root = tree.getroot()
testing = root.find('Testing')

tests={}

for test in testing.findall("Test"):
    status = test.attrib['Status']
    fail=False
    if status=="failed": fail=True
    name = test.find('Name').text
    group = name.split('/')[0]

    if fail:
        line = "%s  3   %s%s"%(date,branch,name)
    else:
        line = "%s   +  %s%s"%(date,branch,name)

    if group not in tests: tests[group]=[]
    tests[group].append( line )

for g in sorted(tests):
    group = tests[g]
    print header
    for l in group:
        print l

<|endoftext|>


<commit_before>'''
Harvester for OAI-PMH interfaces.
'''
#pylint: disable-msg=E1101,E0611,F0401
import logging
import json
import unicodedata
import string
import urllib2

from ckan.model import Session, Package, Group
from ckan import model

from ckanext.harvest.harvesters.base import HarvesterBase
from ckan.lib.munge import  munge_tag
from ckanext.harvest.model import HarvestObject
from ckan.model.authz import setup_default_user_roles

import oaipmh.client
from oaipmh.metadata import MetadataRegistry, oai_dc_reader
from oaipmh.error import NoSetHierarchyError

log = logging.getLogger(__name__)

class OAIPMHHarvester(HarvesterBase):
    '''
    OAI-PMH Harvester for ckanext-harvester.
    '''

    config = None

    def _set_config(self, config_str):
        '''Set the configuration string.
        '''
        if config_str:
            self.config = json.loads(config_str)
        else:
            self.config = {}

    def info(self):
        '''
        Return information about this harvester.
        '''
        return {
                'name': 'OAI-PMH',
                'title': 'OAI-PMH',
                'description': 'A server which has a OAI-PMH interface available.'
                }

    def gather_stage(self, harvest_job):
        '''
        The gather stage will recieve a HarvestJob object and will be
        responsible for:
            - gathering all the necessary objects to fetch on a later.
              stage (e.g. for a CSW server, perform a GetRecords request)
            - creating the necessary HarvestObjects in the database, specifying
              the guid and a reference to its source and job.
            - creating and storing any suitable HarvestGatherErrors that may
              occur.
            - returning a list with all the ids of the created HarvestObjects.

        :param harvest_job: HarvestJob object
        :returns: A list of HarvestObject ids
        '''
        self._set_config(harvest_job.source.config)
        sets = []
        harvest_objs = []
        registry = MetadataRegistry()
        registry.registerReader('oai_dc', oai_dc_reader)
        client = oaipmh.client.Client(harvest_job.source.url, registry)
        try:
            identifier = client.identify()
        except urllib2.URLError:
            self._save_gather_error('Could not gather anything from %s!' %
                                    harvest_job.source.url, harvest_job)
            return None
        domain = identifier.repositoryName()
        group = Group.by_name(domain)
        if not group:
            group = Group(name=domain, description=domain)
        query = self.config['query'] if 'query' in self.config else ''
        try:
            for set in client.listSets():
                identifier, name, _ = set
                if 'query' in self.config:
                    if query in name:
                        sets.append((identifier, name))
                else:
                    sets.append((identifier, name))
        except NoSetHierarchyError:
            sets.append(('1', 'Default'))
            self._save_gather_error('Could not fetch sets!', harvest_job)

        for set_id, set_name in sets:
            harvest_obj = HarvestObject(job=harvest_job)
            harvest_obj.content = json.dumps(
                                             {
                                              'set': set_id, \
                                              'set_name': set_name, \
                                              'domain': domain
                                              }
                                             )
            harvest_obj.save()
            harvest_objs.append(harvest_obj.id)
        model.repo.commit()
        return harvest_objs

    def fetch_stage(self, harvest_object):
        '''
        The fetch stage will receive a HarvestObject object and will be
        responsible for:
            - getting the contents of the remote object (e.g. for a CSW server,
              perform a GetRecordById request).
            - saving the content in the provided HarvestObject.
            - creating and storing any suitable HarvestObjectErrors that may
              occur.
            - returning True if everything went as expected, False otherwise.

        :param harvest_object: HarvestObject object
        :returns: True if everything went right, False if errors were found
        '''
        sets = json.loads(harvest_object.content)
        registry = MetadataRegistry()
        registry.registerReader('oai_dc', oai_dc_reader)
        client = oaipmh.client.Client(harvest_object.job.source.url, registry)
        records = []
        recs = []
        try:
            recs = client.listRecords(metadataPrefix='oai_dc', set=sets['set'])
        except:
            pass
        for rec in recs:
            header, metadata, _ = rec
            if metadata:
                records.append((header.identifier(), metadata.getMap(), None))
        if len(records):
            sets['records'] = records
            harvest_object.content = json.dumps(sets)
        else:
            self._save_object_error('Could not find any records for set %s!' %
                                    sets['set'], harvest_object)
            return False
        return True

    def import_stage(self, harvest_object):
        '''
        The import stage will receive a HarvestObject object and will be
        responsible for:
            - performing any necessary action with the fetched object (e.g
              create a CKAN package).
              Note: if this stage creates or updates a package, a reference
              to the package must be added to the HarvestObject.
              Additionally, the HarvestObject must be flagged as current.
            - creating the HarvestObject - Package relation (if necessary)
            - creating and storing any suitable HarvestObjectErrors that may
              occur.
            - returning True if everything went as expected, False otherwise.

        :param harvest_object: HarvestObject object
        :returns: True if everything went right, False if errors were found
        '''
        model.repo.new_revision()
        master_data = json.loads(harvest_object.content)
        domain = master_data['domain']
        group = Group.get(domain)
        if not group:
            group = Group(name=domain, description=domain)
        if 'records' in master_data:
            records = master_data['records']
            set_name = master_data['set_name']
            for rec in records:
                identifier, metadata, _ = rec
                if metadata:
                    name = metadata['title'][0] if len(metadata['title'])\
                                                else identifier
                    title = name
                    norm_title = unicodedata.normalize('NFKD', name)\
                                 .encode('ASCII', 'ignore')\
                                 .lower().replace(' ', '_')[:35]
                    slug = ''.join(e for e in norm_title
                                    if e in string.ascii_letters + '_')
                    name = slug
                    creator = metadata['creator'][0]\
                                if len(metadata['creator']) else ''
                    description = metadata['description'][0]\
                                if len(metadata['description']) else ''
                    pkg = Package.by_name(name)
                    if not pkg:
                        pkg = Package(name=name, title=title)
                    extras = {}
                    for met in metadata.items():
                        key, value = met
                        if len(value) > 0:
                            if key == 'subject' or key == 'type':
                                for tag in value:
                                    if tag:
                                        tag = munge_tag(tag[:100])
                                        tag_obj = model.Tag.by_name(tag)
                                        if not tag_obj:
                                            tag_obj = model.Tag(name=tag)
                                        if tag_obj:
                                            pkgtag = model.PackageTag(
                                                                  tag=tag_obj,
                                                                  package=pkg)
                                            Session.add(tag_obj)
                                            Session.add(pkgtag)
                            else:
                                extras[key] = ' '.join(value)
                    pkg.author = creator
                    pkg.title = title
                    pkg.notes = description
                    pkg.extras = extras
                    pkg.url = \
                    "%s?verb=GetRecord&identifier=%s&metadataPrefix=oai_dc"\
                                % (harvest_object.job.source.url, identifier)
                    pkg.save()
                    harvest_object.package_id = pkg.id
                    Session.add(harvest_object)
                    setup_default_user_roles(pkg)
                    url = ''
                    for ids in metadata['identifier']:
                        if ids.startswith('http://'):
                            url = ids
                    title = metadata['title'][0] if len(metadata['title'])\
                                                    else ''
                    description = metadata['description'][0]\
                                    if len(metadata['description']) else ''
                    if url != '':
                        pkg.add_resource(url,
                                         description=description,
                                         name=title,
                                         format='html' if url.startswith('http://') else '')
                    group.add_package_by_name(pkg.name)
                    subg_name = "%s - %s" % (domain, set_name)
                    subgroup = Group.by_name(subg_name)
                    if not subgroup:
                        subgroup = Group(name=subg_name, description=subg_name)
                    subgroup.add_package_by_name(pkg.name)
                    Session.add(group)
                    Session.add(subgroup)
                    setup_default_user_roles(group)
                    setup_default_user_roles(subgroup)
            model.repo.commit()
        else:
            self._save_object_error('Could not receive any objects from fetch!'
                                    , harvest_object, stage='Import')
            return False
        return True
<commit_msg>Save original metadata record.<commit_after>'''
Harvester for OAI-PMH interfaces.
'''
#pylint: disable-msg=E1101,E0611,F0401
import logging
import json
import unicodedata
import string
import urllib2
import datetime

from ckan.model import Session, Package, Group
from ckan import model

from ckanext.harvest.harvesters.base import HarvesterBase
from ckan.lib.munge import  munge_tag
from ckanext.harvest.model import HarvestObject
from ckan.model.authz import setup_default_user_roles
from ckan.controllers.storage import BUCKET, get_ofs
from ckan.lib import helpers as h
from pylons import config

import oaipmh.client
from oaipmh.metadata import MetadataRegistry, oai_dc_reader
from oaipmh.error import NoSetHierarchyError

log = logging.getLogger(__name__)

class OAIPMHHarvester(HarvesterBase):
    '''
    OAI-PMH Harvester for ckanext-harvester.
    '''

    config = None

    def _set_config(self, config_str):
        '''Set the configuration string.
        '''
        if config_str:
            self.config = json.loads(config_str)
        else:
            self.config = {}

    def info(self):
        '''
        Return information about this harvester.
        '''
        return {
                'name': 'OAI-PMH',
                'title': 'OAI-PMH',
                'description': 'A server which has a OAI-PMH interface available.'
                }

    def gather_stage(self, harvest_job):
        '''
        The gather stage will recieve a HarvestJob object and will be
        responsible for:
            - gathering all the necessary objects to fetch on a later.
              stage (e.g. for a CSW server, perform a GetRecords request)
            - creating the necessary HarvestObjects in the database, specifying
              the guid and a reference to its source and job.
            - creating and storing any suitable HarvestGatherErrors that may
              occur.
            - returning a list with all the ids of the created HarvestObjects.

        :param harvest_job: HarvestJob object
        :returns: A list of HarvestObject ids
        '''
        self._set_config(harvest_job.source.config)
        sets = []
        harvest_objs = []
        registry = MetadataRegistry()
        registry.registerReader('oai_dc', oai_dc_reader)
        client = oaipmh.client.Client(harvest_job.source.url, registry)
        try:
            identifier = client.identify()
        except urllib2.URLError:
            self._save_gather_error('Could not gather anything from %s!' %
                                    harvest_job.source.url, harvest_job)
            return None
        domain = identifier.repositoryName()
        group = Group.by_name(domain)
        if not group:
            group = Group(name=domain, description=domain)
        query = self.config['query'] if 'query' in self.config else ''
        try:
            for set in client.listSets():
                identifier, name, _ = set
                if 'query' in self.config:
                    if query in name:
                        sets.append((identifier, name))
                else:
                    sets.append((identifier, name))
        except NoSetHierarchyError:
            sets.append(('1', 'Default'))
            self._save_gather_error('Could not fetch sets!', harvest_job)

        for set_id, set_name in sets:
            harvest_obj = HarvestObject(job=harvest_job)
            harvest_obj.content = json.dumps(
                                             {
                                              'set': set_id, \
                                              'set_name': set_name, \
                                              'domain': domain
                                              }
                                             )
            harvest_obj.save()
            harvest_objs.append(harvest_obj.id)
        model.repo.commit()
        return harvest_objs

    def fetch_stage(self, harvest_object):
        '''
        The fetch stage will receive a HarvestObject object and will be
        responsible for:
            - getting the contents of the remote object (e.g. for a CSW server,
              perform a GetRecordById request).
            - saving the content in the provided HarvestObject.
            - creating and storing any suitable HarvestObjectErrors that may
              occur.
            - returning True if everything went as expected, False otherwise.

        :param harvest_object: HarvestObject object
        :returns: True if everything went right, False if errors were found
        '''
        sets = json.loads(harvest_object.content)
        registry = MetadataRegistry()
        registry.registerReader('oai_dc', oai_dc_reader)
        client = oaipmh.client.Client(harvest_object.job.source.url, registry)
        records = []
        recs = []
        try:
            recs = client.listRecords(metadataPrefix='oai_dc', set=sets['set'])
        except:
            pass
        for rec in recs:
            header, metadata, _ = rec
            if metadata:
                records.append((header.identifier(), metadata.getMap(), None))
        if len(records):
            sets['records'] = records
            harvest_object.content = json.dumps(sets)
        else:
            self._save_object_error('Could not find any records for set %s!' %
                                    sets['set'], harvest_object)
            return False
        return True

    def import_stage(self, harvest_object):
        '''
        The import stage will receive a HarvestObject object and will be
        responsible for:
            - performing any necessary action with the fetched object (e.g
              create a CKAN package).
              Note: if this stage creates or updates a package, a reference
              to the package must be added to the HarvestObject.
              Additionally, the HarvestObject must be flagged as current.
            - creating the HarvestObject - Package relation (if necessary)
            - creating and storing any suitable HarvestObjectErrors that may
              occur.
            - returning True if everything went as expected, False otherwise.

        :param harvest_object: HarvestObject object
        :returns: True if everything went right, False if errors were found
        '''
        model.repo.new_revision()
        master_data = json.loads(harvest_object.content)
        domain = master_data['domain']
        group = Group.get(domain)
        if not group:
            group = Group(name=domain, description=domain)
        if 'records' in master_data:
            records = master_data['records']
            set_name = master_data['set_name']
            for rec in records:
                identifier, metadata, _ = rec
                if metadata:
                    name = metadata['title'][0] if len(metadata['title'])\
                                                else identifier
                    title = name
                    norm_title = unicodedata.normalize('NFKD', name)\
                                 .encode('ASCII', 'ignore')\
                                 .lower().replace(' ', '_')[:35]
                    slug = ''.join(e for e in norm_title
                                    if e in string.ascii_letters + '_')
                    name = slug
                    creator = metadata['creator'][0]\
                                if len(metadata['creator']) else ''
                    description = metadata['description'][0]\
                                if len(metadata['description']) else ''
                    pkg = Package.by_name(name)
                    if not pkg:
                        pkg = Package(name=name, title=title)
                    extras = {}
                    for met in metadata.items():
                        key, value = met
                        if len(value) > 0:
                            if key == 'subject' or key == 'type':
                                for tag in value:
                                    if tag:
                                        tag = munge_tag(tag[:100])
                                        tag_obj = model.Tag.by_name(tag)
                                        if not tag_obj:
                                            tag_obj = model.Tag(name=tag)
                                        if tag_obj:
                                            pkgtag = model.PackageTag(
                                                                  tag=tag_obj,
                                                                  package=pkg)
                                            Session.add(tag_obj)
                                            Session.add(pkgtag)
                            elif key != 'title':
                                extras[key] = ' '.join(value)
                    pkg.author = creator
                    pkg.title = title
                    pkg.notes = description
                    pkg.extras = extras
                    pkg.url = \
                    "%s?verb=GetRecord&identifier=%s&metadataPrefix=oai_dc"\
                                % (harvest_object.job.source.url, identifier)
                    pkg.save()
                    ofs = get_ofs()
                    nowstr = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
                    label = "%s/%s.xml" % (\
                        nowstr,
                        identifier)
                    ofs.put_stream(BUCKET, label, urllib2.urlopen(pkg.url), {})
                    fileurl = config.get('ckan.site_url') + h.url_for('storage_file', label=label)
                    pkg.add_resource(url=fileurl, description="Original metadata record",
                             format="xml", size=len(f))
                    harvest_object.package_id = pkg.id
                    Session.add(harvest_object)
                    setup_default_user_roles(pkg)
                    url = ''
                    for ids in metadata['identifier']:
                        if ids.startswith('http://'):
                            url = ids
                    title = metadata['title'][0] if len(metadata['title'])\
                                                    else ''
                    description = metadata['description'][0]\
                                    if len(metadata['description']) else ''
                    if url != '':
                        pkg.add_resource(url,
                                         description=description,
                                         name=title,
                                         format='html' if url.startswith('http://') else '')
                    group.add_package_by_name(pkg.name)
                    subg_name = "%s - %s" % (domain, set_name)
                    subgroup = Group.by_name(subg_name)
                    if not subgroup:
                        subgroup = Group(name=subg_name, description=subg_name)
                    subgroup.add_package_by_name(pkg.name)
                    Session.add(group)
                    Session.add(subgroup)
                    setup_default_user_roles(group)
                    setup_default_user_roles(subgroup)
            model.repo.commit()
        else:
            self._save_object_error('Could not receive any objects from fetch!'
                                    , harvest_object, stage='Import')
            return False
        return True
<|endoftext|>


<commit_before>"""Tests for the drudges with explicit one-half spin."""

import pytest
from sympy import IndexedBase, symbols, Rational, KroneckerDelta, Integer

from drudge import (
    CR, AN, UP, DOWN, SpinOneHalfGenDrudge, SpinOneHalfPartHoleDrudge,
    RestrictedPartHoleDrudge
)

def test_up_down_enum_symbs():
    """Test the desired mathematical properties of enumeration symbols."""

    for i in [UP, DOWN]:
        assert KroneckerDelta(i, i) == 1

    assert KroneckerDelta(UP, DOWN) == 0
    assert KroneckerDelta(DOWN, UP) == 0

    sigma = symbols('sigma')
    for i in [UP, DOWN]:
        assert KroneckerDelta(i, sigma) != 0
        assert KroneckerDelta(sigma, i) != 0

@pytest.fixture(scope='module')
def genmb(spark_ctx):
    """The fixture with a general spin one-half drudge."""
    return SpinOneHalfGenDrudge(spark_ctx)

def test_spin_one_half_general_drudge_has_properties(genmb):
    """Test the basic properties of the drudge."""

    dr = genmb

    assert dr.spin_vals == [UP, DOWN]
    assert dr.orig_ham.n_terms == 2 + 4
    assert dr.ham.n_terms == 2 + 3

def test_restricted_hf_theory(genmb):
    """Test the derivation of restricted HF theory."""

    dr = genmb
    p = dr.names

    c_dag = p.c_dag
    c_ = p.c_
    a, b, c, d = p.L_dumms[:4]
    alpha = symbols('alpha')

    # Concrete summation.
    rot = dr.sum(
        (alpha, [UP, DOWN]), Rational(1, 2) * c_dag[a, alpha] * c_[b, alpha]
    )

    comm = (dr.ham | rot).simplify()

    # Restricted theory has same density for spin up and down.
    rho = IndexedBase('rho')
    res = comm.eval_vev(lambda op1, op2, _: (
        rho[op2.indices[1], op1.indices[1]]
        if op1.indices[0] == CR and op2.indices[0] == AN
           and op1.indices[2] == op2.indices[2]
        else 0
    )).simplify()

    # The expected result.
    t = dr.one_body
    u = dr.two_body

    f = IndexedBase('f')
    expected = dr.einst(rho[b, c] * f[c, a] - f[b, c] * rho[c, a])
    expected = expected.subst(f[a, b], dr.einst(
        t[a, b] +
        2 * u[a, c, b, d] * rho[d, c] - u[c, a, b, d] * rho[d, c]
    ))
    expected = expected.simplify()

    assert res == expected

@pytest.fixture(scope='module')
def parthole(spark_ctx):
    """The fixture with a particle-hole spin one-half drudge."""
    return SpinOneHalfPartHoleDrudge(spark_ctx)

def test_spin_one_half_particle_hole_drudge_has_basic_properties(parthole):
    """Test basic properties of spin one-half particle-hole drudge."""

    dr = parthole
    p = dr.names

    assert dr.orig_ham.n_terms == 8 + 4 * 2 ** 4

    ham_terms = dr.ham.local_terms
    # Numbers are from the old PySLATA code.
    assert len([i for i in ham_terms if len(i.vecs) == 2]) == 8
    assert len([i for i in ham_terms if len(i.vecs) == 4]) == 36
    assert dr.ham.n_terms == 8 + 36

@pytest.fixture(scope='module')
def restricted_parthole(spark_ctx):
    """The fixture with a restricted particle-hole drudge."""
    return RestrictedPartHoleDrudge(spark_ctx)

def test_restricted_parthole_drudge_has_good_hamiltonian(restricted_parthole):
    """Test Hamiltonian of restricted particle-hole drudge.

    Here the original Hamiltonian is going to be compared with the Hamiltonian
    written in terms of the unitary group generators.
    """

    dr = restricted_parthole
    p = dr.names

    e_ = p.e_
    h = dr.one_body
    v = dr.two_body
    half = Rational(1, 2)
    orbs = tuple(dr.orb_ranges)
    p, q, r, s = symbols('p q r s')

    expected_ham = dr.sum(
        (p, orbs), (q, orbs), h[p, q] * e_[p, q]
    ) + dr.sum(
        (p, orbs), (q, orbs), (r, orbs), (s, orbs),
        half * v[p, r, q, s] * (
            e_[p, q] * e_[r, s] - KroneckerDelta(q, r) * e_[p, s]
        )
    )
    assert (dr.orig_ham - expected_ham).simplify() == 0

def test_restricted_parthole_drudge_simplification(restricted_parthole):
    """Test simplification in restricted particle-hole drudge.

    The purpose of this test is mostly on testing the correct resolution of
    ranges of constants up and down.
    """

    dr = restricted_parthole
    p = dr.names
    a = p.a
    sigma = dr.spin_dumms[0]

    op1 = dr.sum(p.c_[a, UP])
    op2 = dr.sum(p.c_dag[a, UP])
    res_concr = (op1 * op2 + op2 * op1).simplify()

    op1 = dr.sum((sigma, dr.spin_range), p.c_[a, sigma])
    res_abstr = (op1 * op2 + op2 * op1).simplify()

    for i in [res_concr, res_abstr]:
        assert (i - Integer(1)).simplify() == 0
<commit_msg>Fix test after the update of subtraction<commit_after>"""Tests for the drudges with explicit one-half spin."""

import pytest
from sympy import IndexedBase, symbols, Rational, KroneckerDelta, Integer

from drudge import (
    CR, AN, UP, DOWN, SpinOneHalfGenDrudge, SpinOneHalfPartHoleDrudge,
    RestrictedPartHoleDrudge
)

def test_up_down_enum_symbs():
    """Test the desired mathematical properties of enumeration symbols."""

    for i in [UP, DOWN]:
        assert KroneckerDelta(i, i) == 1

    assert KroneckerDelta(UP, DOWN) == 0
    assert KroneckerDelta(DOWN, UP) == 0

    sigma = symbols('sigma')
    for i in [UP, DOWN]:
        assert KroneckerDelta(i, sigma) != 0
        assert KroneckerDelta(sigma, i) != 0

@pytest.fixture(scope='module')
def genmb(spark_ctx):
    """The fixture with a general spin one-half drudge."""
    return SpinOneHalfGenDrudge(spark_ctx)

def test_spin_one_half_general_drudge_has_properties(genmb):
    """Test the basic properties of the drudge."""

    dr = genmb

    assert dr.spin_vals == [UP, DOWN]
    assert dr.orig_ham.n_terms == 2 + 4
    assert dr.ham.n_terms == 2 + 3

def test_restricted_hf_theory(genmb):
    """Test the derivation of restricted HF theory."""

    dr = genmb
    p = dr.names

    c_dag = p.c_dag
    c_ = p.c_
    a, b, c, d = p.L_dumms[:4]
    alpha = symbols('alpha')

    # Concrete summation.
    rot = dr.sum(
        (alpha, [UP, DOWN]), Rational(1, 2) * c_dag[a, alpha] * c_[b, alpha]
    )

    comm = (dr.ham | rot).simplify()

    # Restricted theory has same density for spin up and down.
    rho = IndexedBase('rho')
    res = comm.eval_vev(lambda op1, op2, _: (
        rho[op2.indices[1], op1.indices[1]]
        if op1.indices[0] == CR and op2.indices[0] == AN
           and op1.indices[2] == op2.indices[2]
        else 0
    )).simplify()

    # The expected result.
    t = dr.one_body
    u = dr.two_body

    f = IndexedBase('f')
    expected = dr.einst(rho[b, c] * f[c, a] - f[b, c] * rho[c, a])
    expected = expected.subst(f[a, b], dr.einst(
        t[a, b] +
        2 * u[a, c, b, d] * rho[d, c] - u[c, a, b, d] * rho[d, c]
    ))
    expected = expected.simplify()

    assert res == expected

@pytest.fixture(scope='module')
def parthole(spark_ctx):
    """The fixture with a particle-hole spin one-half drudge."""
    return SpinOneHalfPartHoleDrudge(spark_ctx)

def test_spin_one_half_particle_hole_drudge_has_basic_properties(parthole):
    """Test basic properties of spin one-half particle-hole drudge."""

    dr = parthole
    p = dr.names

    assert dr.orig_ham.n_terms == 8 + 4 * 2 ** 4

    ham_terms = dr.ham.local_terms
    # Numbers are from the old PySLATA code.
    assert len([i for i in ham_terms if len(i.vecs) == 2]) == 8
    assert len([i for i in ham_terms if len(i.vecs) == 4]) == 36
    assert dr.ham.n_terms == 8 + 36

@pytest.fixture(scope='module')
def restricted_parthole(spark_ctx):
    """The fixture with a restricted particle-hole drudge."""
    return RestrictedPartHoleDrudge(spark_ctx)

def test_restricted_parthole_drudge_has_good_hamiltonian(restricted_parthole):
    """Test Hamiltonian of restricted particle-hole drudge.

    Here the original Hamiltonian is going to be compared with the Hamiltonian
    written in terms of the unitary group generators.
    """

    dr = restricted_parthole
    p = dr.names

    e_ = p.e_
    h = dr.one_body
    v = dr.two_body
    half = Rational(1, 2)
    orbs = tuple(dr.orb_ranges)
    p, q, r, s = symbols('p q r s')

    expected_ham = (dr.sum(
        (p, orbs), (q, orbs), h[p, q] * e_[p, q]
    ) + dr.sum(
        (p, orbs), (q, orbs), (r, orbs), (s, orbs),
        half * v[p, r, q, s] * (
            e_[p, q] * e_[r, s] - KroneckerDelta(q, r) * e_[p, s]
        )
    )).simplify()

    assert (dr.orig_ham - expected_ham).simplify() == 0

def test_restricted_parthole_drudge_simplification(restricted_parthole):
    """Test simplification in restricted particle-hole drudge.

    The purpose of this test is mostly on testing the correct resolution of
    ranges of constants up and down.
    """

    dr = restricted_parthole
    p = dr.names
    a = p.a
    sigma = dr.spin_dumms[0]

    op1 = dr.sum(p.c_[a, UP])
    op2 = dr.sum(p.c_dag[a, UP])
    res_concr = (op1 * op2 + op2 * op1).simplify()

    op1 = dr.sum((sigma, dr.spin_range), p.c_[a, sigma])
    res_abstr = (op1 * op2 + op2 * op1).simplify()

    for i in [res_concr, res_abstr]:
        assert (i - Integer(1)).simplify() == 0
<|endoftext|>


<commit_before>from __future__ import division

import numpy as np

from pgmpy.models import BayesianModel
from pgmpy.factors import LinearGaussianCPD

class LinearGaussianBayesianNetwork(BayesianModel):
    """
    A Linear Gaussain Bayesian Network is a Bayesian Network, all
    of whose variables are continuous, and where all of the CPDs
    are linear Gaussians.

    An important result is that the linear Gaussian Bayesian Networks
    are an alternative representation for the class of multivariate
    Gaussian distributions.
    """
    def __init__(self, ebunch=None):
        super(LinearGaussianBayesianNetwork, self).__init__()

        self._jgd = None
<commit_msg>added LGBN.add_cpds<commit_after>from __future__ import division

import numpy as np

from pgmpy.models import BayesianModel
from pgmpy.factors import LinearGaussianCPD

class LinearGaussianBayesianNetwork(BayesianModel):
    """
    A Linear Gaussain Bayesian Network is a Bayesian Network, all
    of whose variables are continuous, and where all of the CPDs
    are linear Gaussians.

    An important result is that the linear Gaussian Bayesian Networks
    are an alternative representation for the class of multivariate
    Gaussian distributions.
    """
    def __init__(self, ebunch=None):
        super(LinearGaussianBayesianNetwork, self).__init__(ebunch)

        self._jgd = None

    def add_cpds(self, *cpds):
        """
        Add linear Gaussian CPD (Conditional Probability Distribution)
        to the Bayesian Model.

        Parameters
        ----------
        cpds  :  instances of LinearGaussianCPD
            List of LinearGaussianCPDs which will be associated with the model

        Examples
        --------
        >>> from pgmpy.models import LinearGaussianBayesianNetwork
        >>> from pgmpy.factors import LinearGaussianCPD
        >>> model = LinearGaussianBayesianNetwork([('x1', 'x2'), ('x2', 'x3')])
        >>> cpd1 = LinearGaussianCPD('x1', 1, 4)
        >>> cpd2 = LinearGaussianCPD('x2', -5, 4, ['x1'], [0.5])
        >>> cpd3 = LinearGaussianCPD('x3', 4, 3, ['x2'], [-1])
        >>> model.add_cpds(cpd1, cpd2, cpd3)
        >>> for cpd in model.cpds:
                print(cpd)

        P(x1) = N(1; 4)
        P(x2| x1) = N(0.5*x1_mu); -5)
        P(x3| x2) = N(-1*x2_mu); 4)

        """
        for cpd in cpds:
            if not isinstance(cpd, LinearGaussianCPD):
                raise ValueError('Only LinearGaussianCPD can be added.')

            if set(cpd.variables) - set(cpd.variables).intersection(
                    set(self.nodes())):
                raise ValueError('CPD defined on variable not in the model', cpd)

            for prev_cpd_index in range(len(self.cpds)):
                if self.cpds[prev_cpd_index].variable == cpd.variable:
                    logging.warning("Replacing existing CPD for {var}".format(var=cpd.variable))
                    self.cpds[prev_cpd_index] = cpd
                    break
            else:
                self.cpds.append(cpd)
<|endoftext|>


<commit_before>#vim: set encoding=utf-8
"""Atomic components; probably shouldn't use these directly"""
import string

from pyparsing import CaselessLiteral, Optional, Regex, Suppress, Word, OneOrMore

from regparser.grammar.utils import Marker, SuffixMarker, WordBoundaries

lower_p = (
    Suppress("(")
    + Regex(r"[ivx]{1}|[a-hj-uwyz]{1,2}").setResultsName("p1")
    + Suppress(")"))
digit_p = (
    Suppress("(")
    + Word(string.digits).setResultsName("p2")
    + Suppress(")"))
roman_p = (
    Suppress("(")
    + Word("ivxlcdm").setResultsName("p3") +
    Suppress(")"))
upper_p = (
    Suppress("(")
    + Word(string.ascii_uppercase).setResultsName("p4")
    + Suppress(")"))

em_digit_p = (
    Suppress(Regex(r"\(<E[^>]*>"))
    + Word(string.digits).setResultsName("p5")
    + Suppress("</E>)"))
em_roman_p = (
    Suppress(Regex(r"\(<E[^>]*>"))
    + Word("ivxlcdm").setResultsName("p5")
    + Suppress("</E>)"))

# Allow a plaintext version of italic paragraph markers
plaintext_level5_p = (
    Suppress("(")
    + Word(string.digits).setResultsName("plaintext_p5")
    + Suppress(")"))
plaintext_level6_p = (
    Suppress("(")
    + Word("ivxlcdm").setResultsName("plaintext_p6")
    + Suppress(")"))

# Leave whitespace; if there's a space we assume the comment is broken
em_digit_c = ("." + Regex(r"<E[^>]*>")
              + Word(string.digits).setResultsName("c4").leaveWhitespace())
upper_c = "." + Word(string.ascii_uppercase).setResultsName(
    'c3').leaveWhitespace()
roman_c = "." + Word("ivxlcdm").setResultsName('c2').leaveWhitespace()
digit_c = "-" + Word(string.digits).setResultsName('c1').leaveWhitespace()

upper_roman_a = Word("IVXLCDM").setResultsName('a1')
upper_a = "." + Word(string.ascii_uppercase).setResultsName(
    'a2').leaveWhitespace()
digit_a = "." + Word(string.digits).setResultsName('a3').leaveWhitespace()

part = Word(string.digits).setResultsName("part")

section = Word(string.digits).setResultsName("section")

appendix = Regex(r"[A-Z]+[0-9]*\b").setResultsName("appendix")
appendix_digit = Word(string.digits).setResultsName("appendix_digit")

subpart = Word(string.ascii_uppercase).setResultsName("subpart")

section_marker = Suppress(Regex(u"§|Section|section"))
sections_marker = Suppress(Regex(u"§§|Sections|sections"))

# Most of these markers could be SuffixMarkers (which arise due to errors in
# the regulation text). We'll wait until we see explicit examples before
# converting them though, to limit false matches
paragraph_marker = Marker("paragraph")
paragraphs_marker = SuffixMarker("paragraphs")

part_marker = Marker("part")
parts_marker = Marker("parts")

subpart_marker = Marker("subpart")

comment_marker = (
    (Marker("comment")
     | Marker("commentary")
     | (Marker("official") + Marker("interpretations"))
     | (Marker("supplement") + Suppress(WordBoundaries("I"))))
    + Optional(Marker("of") | Marker("to")))
comments_marker = Marker("comments")

appendix_marker = Marker("appendix")
appendices_marker = Marker("appendices")

conj_phrases = (
    (Suppress(",") + Optional(Marker("and") | Marker("or")))
    | Marker("and")
    | Marker("or")
    | (Marker("except") + Marker("for"))
    | Suppress("-")
    | WordBoundaries(CaselessLiteral("through")).setResultsName("through"))

title = Word(string.digits).setResultsName("cfr_title")
<commit_msg>Remove unnecessary import<commit_after>#vim: set encoding=utf-8
"""Atomic components; probably shouldn't use these directly"""
import string

from pyparsing import CaselessLiteral, Optional, Regex, Suppress, Word

from regparser.grammar.utils import Marker, SuffixMarker, WordBoundaries

lower_p = (
    Suppress("(")
    + Regex(r"[ivx]{1}|[a-hj-uwyz]{1,2}").setResultsName("p1")
    + Suppress(")"))
digit_p = (
    Suppress("(")
    + Word(string.digits).setResultsName("p2")
    + Suppress(")"))
roman_p = (
    Suppress("(")
    + Word("ivxlcdm").setResultsName("p3") +
    Suppress(")"))
upper_p = (
    Suppress("(")
    + Word(string.ascii_uppercase).setResultsName("p4")
    + Suppress(")"))

em_digit_p = (
    Suppress(Regex(r"\(<E[^>]*>"))
    + Word(string.digits).setResultsName("p5")
    + Suppress("</E>)"))
em_roman_p = (
    Suppress(Regex(r"\(<E[^>]*>"))
    + Word("ivxlcdm").setResultsName("p5")
    + Suppress("</E>)"))

# Allow a plaintext version of italic paragraph markers
plaintext_level5_p = (
    Suppress("(")
    + Word(string.digits).setResultsName("plaintext_p5")
    + Suppress(")"))
plaintext_level6_p = (
    Suppress("(")
    + Word("ivxlcdm").setResultsName("plaintext_p6")
    + Suppress(")"))

# Leave whitespace; if there's a space we assume the comment is broken
em_digit_c = ("." + Regex(r"<E[^>]*>")
              + Word(string.digits).setResultsName("c4").leaveWhitespace())
upper_c = "." + Word(string.ascii_uppercase).setResultsName(
    'c3').leaveWhitespace()
roman_c = "." + Word("ivxlcdm").setResultsName('c2').leaveWhitespace()
digit_c = "-" + Word(string.digits).setResultsName('c1').leaveWhitespace()

upper_roman_a = Word("IVXLCDM").setResultsName('a1')
upper_a = "." + Word(string.ascii_uppercase).setResultsName(
    'a2').leaveWhitespace()
digit_a = "." + Word(string.digits).setResultsName('a3').leaveWhitespace()

part = Word(string.digits).setResultsName("part")

section = Word(string.digits).setResultsName("section")

appendix = Regex(r"[A-Z]+[0-9]*\b").setResultsName("appendix")
appendix_digit = Word(string.digits).setResultsName("appendix_digit")

subpart = Word(string.ascii_uppercase).setResultsName("subpart")

section_marker = Suppress(Regex(u"§|Section|section"))
sections_marker = Suppress(Regex(u"§§|Sections|sections"))

# Most of these markers could be SuffixMarkers (which arise due to errors in
# the regulation text). We'll wait until we see explicit examples before
# converting them though, to limit false matches
paragraph_marker = Marker("paragraph")
paragraphs_marker = SuffixMarker("paragraphs")

part_marker = Marker("part")
parts_marker = Marker("parts")

subpart_marker = Marker("subpart")

comment_marker = (
    (Marker("comment")
     | Marker("commentary")
     | (Marker("official") + Marker("interpretations"))
     | (Marker("supplement") + Suppress(WordBoundaries("I"))))
    + Optional(Marker("of") | Marker("to")))
comments_marker = Marker("comments")

appendix_marker = Marker("appendix")
appendices_marker = Marker("appendices")

conj_phrases = (
    (Suppress(",") + Optional(Marker("and") | Marker("or")))
    | Marker("and")
    | Marker("or")
    | (Marker("except") + Marker("for"))
    | Suppress("-")
    | WordBoundaries(CaselessLiteral("through")).setResultsName("through"))

title = Word(string.digits).setResultsName("cfr_title")
<|endoftext|>


<commit_before>import os

import sublime
from sublime_plugin import WindowCommand

from ..git_command import GitCommand
from ...common import util
from ..ui_mixins.input_panel import show_single_line_input_panel

NO_REPO_MESSAGE = ("It looks like you haven't initialized Git in this directory.  "
                   "Would you like to?")
REPO_PATH_PROMPT = "Enter root path of new git repo:"
CONFIRM_REINITIALIZE = ("It looks like Git is already initialized here.  "
                        "Would you like to re-initialize?")
NAME_MESSAGE = "Enter your first and last name:"
EMAIL_MESSAGE = "Enter your email address:"
NO_CONFIG_MESSAGE = ("It looks like you haven't configured Git yet.  Would you "
                     "like to enter your name and email for Git to use?")
RECLONE_CANT_BE_DONE = ("It looks like Git is already initialized here.  "
                        "You can not re-clone")
GIT_URL = "Enter git url:"

views_with_offer_made = set()

class GsOfferInit(WindowCommand, GitCommand):

    """
    If a git command fails indicating no git repo was found, this
    command will ask the user whether they'd like to init a new repo.

    Offer only once per session for a given view.
    """

    def run(self):
        if self.savvy_settings.get("disable_git_init_prompt"):
            return

        active_view_id = self.window.active_view().id()
        if active_view_id not in views_with_offer_made and sublime.ok_cancel_dialog(NO_REPO_MESSAGE):
            self.window.run_command("gs_init")
        else:
            views_with_offer_made.add(active_view_id)

class GsInit(WindowCommand, GitCommand):

    """
    If the active Sublime window has folders added to the project (or if Sublime was
    opened from the terminal with something like `subl .`), initialize a new Git repo
    at that location.  If that directory cannot be determined, use the open file's
    directory.  If there is no open file, prompt the user for the directory to use.

    If the selected directory has previosly been initialized with Git, prompt the user
    to confirm a re-initialize before proceeding.
    """

    def run(self):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        git_root = self.find_working_dir()

        if git_root and os.path.exists(os.path.join(git_root, ".git")):
            if sublime.ok_cancel_dialog(CONFIRM_REINITIALIZE):
                self.on_done(git_root, re_init=True)
            return

        show_single_line_input_panel(REPO_PATH_PROMPT, git_root, self.on_done, None, None)

    def on_done(self, path, re_init=False):
        self.git("init", working_dir=path)
        self.window.status_message("{word_start}nitialized repo successfully.".format(
            word_start="Re-i" if re_init else "I"))
        util.view.refresh_gitsavvy(self.window.active_view())

class GsClone(WindowCommand, GitCommand):

    """
    If the active Sublime window has folders added to the project (or if Sublime was
    opened from the terminal with something like `subl .`), initialize a new Git repo
    at that location.  If that directory cannot be determined, use the open file's
    directory.  If there is no open file, prompt the user for the directory to use.

    If the selected directory has previously been initialized with Git, prompt the user
    to confirm a re-initialize before proceeding.
    """

    def run(self, recursive=False):
        self.recursive = recursive
        show_single_line_input_panel(GIT_URL, '', self.on_enter_url, None, None)

    def on_enter_url(self, url):
        self.git_url = url
        self.suggested_git_root = self.find_suggested_git_root()
        show_single_line_input_panel(REPO_PATH_PROMPT, self.suggested_git_root, self.on_enter_directory, None, None)

    def find_suggested_git_root(self):
        folder = self.find_working_dir()
        project = self.project_name_from_url(self.git_url)
        if folder:
            if not os.path.exists(os.path.join(folder, project, ".git")):
                return os.path.join(folder, project)
            else:
                parent = os.path.dirname(folder)
                return os.path.join(parent, project)
        return ""

    def on_enter_directory(self, path):
        self.suggested_git_root = os.path.expanduser(path)  # handle ~/%HOME%
        if self.suggested_git_root and os.path.exists(os.path.join(self.suggested_git_root, ".git")):
            sublime.ok_cancel_dialog(RECLONE_CANT_BE_DONE)
            return

        sublime.set_timeout_async(self.do_clone, 0)

    def do_clone(self):
        self.window.status_message("Start cloning {}".format(self.git_url))
        self.git(
            "clone",
            "--recursive" if self.recursive else None,
            self.git_url,
            self.suggested_git_root,
            working_dir='.')
        self.window.status_message("Cloned repo successfully.")
        self.open_folder()
        util.view.refresh_gitsavvy(self.window.active_view())

    def open_folder(self):
        # taken from
        # https://github.com/rosshemsley/iOpener/blob/a35117a201290b63b53ba6372dbf8bbfc68f28b9/i_opener.py#L203-L205
        sublime.run_command("new_window")
        project_data = dict(folders=[dict(follow_symlinks=True, path=self.suggested_git_root)])
        sublime.active_window().set_project_data(project_data)

class GsSetupUserCommand(WindowCommand, GitCommand):

    """
    Set user's name and email address in global Git config.
    """

    def run(self):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        if sublime.ok_cancel_dialog(NO_CONFIG_MESSAGE):
            self.get_name()

    def get_name(self):
        show_single_line_input_panel(NAME_MESSAGE, "", self.on_done_name, None, None)

    def on_done_name(self, name):
        self.git("config", "--global", "user.name", "{}".format(name))
        self.get_email()

    def get_email(self):
        show_single_line_input_panel(EMAIL_MESSAGE, "", self.on_done_email, None, None)

    def on_done_email(self, email):
        self.git("config", "--global", "user.email", "{}".format(email))
<commit_msg>Do not pass defaults down to `show_single_line_input_panel`<commit_after>import os

import sublime
from sublime_plugin import WindowCommand

from ..git_command import GitCommand
from ...common import util
from ..ui_mixins.input_panel import show_single_line_input_panel

NO_REPO_MESSAGE = ("It looks like you haven't initialized Git in this directory.  "
                   "Would you like to?")
REPO_PATH_PROMPT = "Enter root path of new git repo:"
CONFIRM_REINITIALIZE = ("It looks like Git is already initialized here.  "
                        "Would you like to re-initialize?")
NAME_MESSAGE = "Enter your first and last name:"
EMAIL_MESSAGE = "Enter your email address:"
NO_CONFIG_MESSAGE = ("It looks like you haven't configured Git yet.  Would you "
                     "like to enter your name and email for Git to use?")
RECLONE_CANT_BE_DONE = ("It looks like Git is already initialized here.  "
                        "You can not re-clone")
GIT_URL = "Enter git url:"

views_with_offer_made = set()

class GsOfferInit(WindowCommand, GitCommand):

    """
    If a git command fails indicating no git repo was found, this
    command will ask the user whether they'd like to init a new repo.

    Offer only once per session for a given view.
    """

    def run(self):
        if self.savvy_settings.get("disable_git_init_prompt"):
            return

        active_view_id = self.window.active_view().id()
        if active_view_id not in views_with_offer_made and sublime.ok_cancel_dialog(NO_REPO_MESSAGE):
            self.window.run_command("gs_init")
        else:
            views_with_offer_made.add(active_view_id)

class GsInit(WindowCommand, GitCommand):

    """
    If the active Sublime window has folders added to the project (or if Sublime was
    opened from the terminal with something like `subl .`), initialize a new Git repo
    at that location.  If that directory cannot be determined, use the open file's
    directory.  If there is no open file, prompt the user for the directory to use.

    If the selected directory has previosly been initialized with Git, prompt the user
    to confirm a re-initialize before proceeding.
    """

    def run(self):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        git_root = self.find_working_dir()

        if git_root and os.path.exists(os.path.join(git_root, ".git")):
            if sublime.ok_cancel_dialog(CONFIRM_REINITIALIZE):
                self.on_done(git_root, re_init=True)
            return

        show_single_line_input_panel(REPO_PATH_PROMPT, git_root, self.on_done, None, None)

    def on_done(self, path, re_init=False):
        self.git("init", working_dir=path)
        self.window.status_message("{word_start}nitialized repo successfully.".format(
            word_start="Re-i" if re_init else "I"))
        util.view.refresh_gitsavvy(self.window.active_view())

class GsClone(WindowCommand, GitCommand):

    """
    If the active Sublime window has folders added to the project (or if Sublime was
    opened from the terminal with something like `subl .`), initialize a new Git repo
    at that location.  If that directory cannot be determined, use the open file's
    directory.  If there is no open file, prompt the user for the directory to use.

    If the selected directory has previously been initialized with Git, prompt the user
    to confirm a re-initialize before proceeding.
    """

    def run(self, recursive=False):
        self.recursive = recursive
        show_single_line_input_panel(GIT_URL, '', self.on_enter_url, None, None)

    def on_enter_url(self, url):
        self.git_url = url
        self.suggested_git_root = self.find_suggested_git_root()
        show_single_line_input_panel(REPO_PATH_PROMPT, self.suggested_git_root, self.on_enter_directory, None, None)

    def find_suggested_git_root(self):
        folder = self.find_working_dir()
        project = self.project_name_from_url(self.git_url)
        if folder:
            if not os.path.exists(os.path.join(folder, project, ".git")):
                return os.path.join(folder, project)
            else:
                parent = os.path.dirname(folder)
                return os.path.join(parent, project)
        return ""

    def on_enter_directory(self, path):
        self.suggested_git_root = os.path.expanduser(path)  # handle ~/%HOME%
        if self.suggested_git_root and os.path.exists(os.path.join(self.suggested_git_root, ".git")):
            sublime.ok_cancel_dialog(RECLONE_CANT_BE_DONE)
            return

        sublime.set_timeout_async(self.do_clone, 0)

    def do_clone(self):
        self.window.status_message("Start cloning {}".format(self.git_url))
        self.git(
            "clone",
            "--recursive" if self.recursive else None,
            self.git_url,
            self.suggested_git_root,
            working_dir='.')
        self.window.status_message("Cloned repo successfully.")
        self.open_folder()
        util.view.refresh_gitsavvy(self.window.active_view())

    def open_folder(self):
        # taken from
        # https://github.com/rosshemsley/iOpener/blob/a35117a201290b63b53ba6372dbf8bbfc68f28b9/i_opener.py#L203-L205
        sublime.run_command("new_window")
        project_data = dict(folders=[dict(follow_symlinks=True, path=self.suggested_git_root)])
        sublime.active_window().set_project_data(project_data)

class GsSetupUserCommand(WindowCommand, GitCommand):

    """
    Set user's name and email address in global Git config.
    """

    def run(self):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        if sublime.ok_cancel_dialog(NO_CONFIG_MESSAGE):
            self.get_name()

    def get_name(self):
        show_single_line_input_panel(NAME_MESSAGE, "", self.on_done_name)

    def on_done_name(self, name):
        self.git("config", "--global", "user.name", "{}".format(name))
        self.get_email()

    def get_email(self):
        show_single_line_input_panel(EMAIL_MESSAGE, "", self.on_done_email)

    def on_done_email(self, email):
        self.git("config", "--global", "user.email", "{}".format(email))
<|endoftext|>


<commit_before>
# coding: utf8
from __future__ import (unicode_literals, print_function,
                        absolute_import, division)

'''
Fonctions utilitaires
'''
from flask import jsonify,  Response, current_app
import json
from functools import wraps
from flask_sqlalchemy import SQLAlchemy
from werkzeug.datastructures import Headers

from geoalchemy2.shape import to_shape, from_shape
from geojson import Feature

from geoalchemy2 import Geometry

db = SQLAlchemy()

class serializableModel(db.Model):
    __abstract__ = True

    def as_dict(self, recursif=False):
        return {column.key: getattr(self, column.key)
                if not isinstance(column.type, (db.Date, db.DateTime))
                else str(getattr(self, column.key))
                for column in self.__table__.columns  if not isinstance(column.type, Geometry)}

class serializableGeoModel(serializableModel, db.Model):
    __abstract__ = True

    def as_geofeature(self, geoCol, idCol):
        geometry = to_shape(getattr(self, geoCol))
        feature = Feature(
                id=getattr(self, idCol),
                geometry=geometry,
                properties= {column.key: getattr(self, column.key)
                        if not isinstance(column.type, (db.Date, db.DateTime))
                        else str(getattr(self, column.key))
                        for column in self.__table__.columns  if not isinstance(column.type, Geometry) }
            )
        return feature

def json_resp(fn):
    '''
    Décorateur transformant le résultat renvoyé par une vue
    en objet JSON
    '''
    @wraps(fn)
    def _json_resp(*args, **kwargs):
        res = fn(*args, **kwargs)
        if isinstance(res, tuple):
            res, status = res
        else:
            status = 200
        return Response(json.dumps(res),
                status=status, mimetype='application/json')
    return _json_resp

def csv_resp(fn):
    '''
    Décorateur transformant le résultat renvoyé en un fichier csv
    '''
    @wraps(fn)
    def _csv_resp(*args, **kwargs):
        res = fn(*args, **kwargs)
        filename, data, columns, separator = res
        outdata =  [separator.join(columns)]

        headers = Headers()
        headers.add('Content-Type', 'text/plain')
        headers.add('Content-Disposition', 'attachment', filename='export_%s.csv'%filename)

        for o in data:
            outdata.append(separator.join('"%s"'%(o.get(i), '')[o.get(i) == None] for i in columns))

        out = '\r\n'.join(outdata)
        return Response(out, headers=headers)
    return _csv_resp
<commit_msg>Ajout de la récursivité dans la sérialisation dun modele<commit_after>
# coding: utf8
from __future__ import (unicode_literals, print_function,
                        absolute_import, division)

'''
Fonctions utilitaires
'''
from flask import jsonify,  Response, current_app
import json
from functools import wraps
from flask_sqlalchemy import SQLAlchemy
from werkzeug.datastructures import Headers

from sqlalchemy import inspect
from sqlalchemy.orm import class_mapper, ColumnProperty, RelationshipProperty

from geoalchemy2.shape import to_shape, from_shape
from geojson import Feature

from geoalchemy2 import Geometry

db = SQLAlchemy()

class serializableModel(db.Model):
    __abstract__ = True
    def as_dict(self, recursif=False):
        obj={}
        for prop in class_mapper(self.__class__).iterate_properties:
            if isinstance(prop, ColumnProperty)  :
                column = self.__table__.columns[prop.key]
                if isinstance(column.type, (db.Date, db.DateTime)) :
                    obj[prop.key] =str(getattr(self, prop.key))
                elif not isinstance(column.type, Geometry) :
                    obj[prop.key] =getattr(self, prop.key)
            if ((isinstance(prop,RelationshipProperty)) and (recursif)):
                obj[prop.key] = [d.as_dict(recursif) for d in getattr(self, prop.key)]

        return obj

class serializableGeoModel(serializableModel):
    __abstract__ = True

    def as_geofeature(self, geoCol, idCol, recursif=False):
        geometry = to_shape(getattr(self, geoCol))
        feature = Feature(
                id=getattr(self, idCol),
                geometry=geometry,
                properties=self.as_dict(recursif)
            )
        return feature

def json_resp(fn):
    '''
    Décorateur transformant le résultat renvoyé par une vue
    en objet JSON
    '''
    @wraps(fn)
    def _json_resp(*args, **kwargs):
        res = fn(*args, **kwargs)
        if isinstance(res, tuple):
            res, status = res
        else:
            status = 200
        return Response(json.dumps(res),
                status=status, mimetype='application/json')
    return _json_resp

def csv_resp(fn):
    '''
    Décorateur transformant le résultat renvoyé en un fichier csv
    '''
    @wraps(fn)
    def _csv_resp(*args, **kwargs):
        res = fn(*args, **kwargs)
        filename, data, columns, separator = res
        outdata =  [separator.join(columns)]

        headers = Headers()
        headers.add('Content-Type', 'text/plain')
        headers.add('Content-Disposition', 'attachment', filename='export_%s.csv'%filename)

        for o in data:
            outdata.append(separator.join('"%s"'%(o.get(i), '')[o.get(i) == None] for i in columns))

        out = '\r\n'.join(outdata)
        return Response(out, headers=headers)
    return _csv_resp
<|endoftext|>