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

# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# this file is part of 'RAX-AutoScaler'
#
# Copyright 2014 Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import os
import pyrax
import sys
import pyrax.exceptions as pexc
from termcolor import colored
import ConfigParser
import subprocess
import datetime
import json
import requests
import logging

def get_logger():
    """This function instantiate the logger.

    :return: logger

    """
    logger = logging.getLogger(__name__)
    return logger

def check_file(fname):
    """This function checks if file exists and is readable.

      :param fname: file name
      :returns: file name with absolute path

    """
    file_abspath = os.path.abspath(fname)
    if os.path.isfile(file_abspath) and os.access(file_abspath, os.R_OK):
        return file_abspath
    else:
        preDefinedPath = '/etc/rax-autoscaler/'+fname
        # Check in /etc/rax-autoscaler/config path
        if os.path.isfile(preDefinedPath):
            if os.access(preDefinedPath, os.R_OK):
                return preDefinedPath
    # Either file is missing or is not readable
    return

def get_config(config_file):
    """This function read and returns jsons configuration data

      :param config_file: json configuration file name
      :returns: json data

    """
    logger = get_logger()
    logger.info("Loading config file: '%s'" % config_file)
    try:
        json_data = open(config_file)
        data = json.load(json_data)
        return data
    except Exception, e:
        logger.error("Error: " + str(e))

    return None

def get_machine_uuid():
    """This function uses subprocess to get node uuid and cached it for future use

      :returns: server uuid
                None

    """
    logger = get_logger()
    server_uptime = None
    cache_uptime = None
    cache_file = '.uuid.cache'
    uuid = None
    cache_content = [None] * 2

    try:
        uptime_file = open('/proc/uptime')
        contents = uptime_file.read().split()
        uptime_file.close()
        server_uptime = str(int(float(contents[0])))
    except Exception, e:
        logger.warning("Unable to get uptime")
        logger.debug('%s' % str(e))
        pass

    if server_uptime is None:
        logger.debug("Failed to get server uptime")
    else:
        logger.debug("Checking if cache file '%s' already exists" % cache_file)
        cache_file = check_file(cache_file)
        if cache_file is not None:
            logger.info("Getting uptime and node id from cache file")
            cache_content = None
            try:
                rfh = open(cache_file, 'r').read()
                cache_content = rfh.split('\n')
            except:
                logger.warning("Unable to read a file '%s' in '%s'"
                               % (cache_file, '/etc/rax-autoscaler'))
                pass

            if (not cache_content[0] or cache_content[0] is None
                    or not cache_content[1] or cache_content[1] is None):
                logger.warning("Cache file is corrupted, failed to"
                               " read the content")
            else:
                try:
                    if int(cache_content[0]) < int(server_uptime):
                        uuid = cache_content[1]
                    else:
                        logger.warning("Invalid uptime found in cache file")
                        logger.debug("uptime: %s cache uptime: %s"
                                     % (server_uptime, cache_content[0]))
                except:
                    logger.warning("Invalid content found in cache file")
                    pass

        if uuid is None:
            logger.info('Launching xenstore query to get server uuid')
            try:
                name = subprocess.Popen(['xenstore-read name'], shell=True,
                                        stdout=subprocess.PIPE
                                        ).communicate()[0]
                id = name.strip()
                uuid = id[9:]
            except Exception, e:
                logger.error("Error: " + str(e))
                return None

            if server_uptime is not None:
                cache_file = '.uuid.cache'
                # Check if file exists in cwd
                if os.path.isfile(cache_file) is False:
                    if os.path.isdir('/etc/rax-autoscaler') is True:
                        cache_file = '/etc/rax-autoscaler/.uuid.cache'

                logger.info("Creating cache file '%s'" % cache_file)
                try:
                    wfh = open(cache_file, 'w')
                    wfh.write(server_uptime)
                    wfh.write('\n')
                    wfh.write(uuid)
                    wfh.close()
                except Exception, e:
                    logger.warning("Unable to create a file '%s': '%s'"
                                   % (cache_file, str(e)))
                    pass

    return uuid

def get_user_value(args, config, key):
    """This function returns value associated with the key if its available in
       user arguments else in json config file.

      :param args: user arguments
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    value = None
    try:
        if args[key] is None:
            value = config['auth'][key.lower()]
        else:
            value = args[key]
    except:
            logger.error("Invalid config, '" + key +
                         "' key not found in authentication section")

    return value

def get_group_value(config, group, key):
    """This function returns value in autoscale_groups section associated with
       provided key.

    :type config: object
      :param group: group name
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    try:
        value = config['autoscale_groups'][group][key]
        if value is not None:
            return value
    except:
        logger.error("Error: unable to get value for key '" + key +
                     "' from group '" + group + "'")

    return None

def get_webhook_value(config, group, key):
    """This function returns value in webhooks section of json file which is
       associated with provided key.

      :param group: group name
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    try:
        value = config['autoscale_groups'][group]['webhooks'][key]
        if value is not None:
            return value
    except:
        logger.warning("Unable to find value for key: '%s' in group '%s'"
                       % (key, group))

    return None

def webhook_call(config_data, group, policy, key):
    """This function makes webhook calls.

      :param config_data: json configuration data
      :param group: group name
      :param policy: policy type
      :param key: key name

    """
    logger = get_logger()

    logger.info('Launching %s webhook call' % key)
    try:
        urls = get_webhook_value(config_data, group, policy)[key]
    except (KeyError, TypeError):
        logger.error('Webhook urls for %s cannot be found in config' % key)
        return None

    try:
        group_config = config_data['autoscale_groups'][group]
        data = json.dumps({
            'group_id': group_config['group_id'],
            'scale_up_policy': group_config['scale_up_policy'],
            'scale_down_policy': group_config['scale_down_policy'],
            'check_type': group_config['check_type'],
            'metric_name': group_config['metric_name'],
            'scale_up_threshold': group_config['scale_up_threshold'],
            'scale_down_threshold': group_config['scale_down_threshold']
        })
    except KeyError as error:
        logger.error('Cannot build webhook data. invalid key: %s' % error)
        return None

    for url in urls:
        logger.info("Sending POST request to url: '%s'" % url)
        try:
            response = requests.post(url, json=data)
            logger.info("Received status code %d from url: '%s'"
                        % (response.status_code, url))
        except Exception, e:
            logger.warning(str(e))

    return None
<commit_msg>Fixes: added inline comments.<commit_after># -*- coding: utf-8 -*-

# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# this file is part of 'RAX-AutoScaler'
#
# Copyright 2014 Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import os
import pyrax
import sys
import pyrax.exceptions as pexc
from termcolor import colored
import ConfigParser
import subprocess
import datetime
import json
import requests
import logging

def get_logger():
    """This function instantiate the logger.

    :return: logger

    """
    logger = logging.getLogger(__name__)
    return logger

def check_file(fname):
    """This function checks if file exists and is readable.

      :param fname: file name
      :returns: file name with absolute path

    """
    file_abspath = os.path.abspath(fname)
    if os.path.isfile(file_abspath) and os.access(file_abspath, os.R_OK):
        return file_abspath
    else:
        preDefinedPath = '/etc/rax-autoscaler/'+fname
        # Check in /etc/rax-autoscaler/config path
        if os.path.isfile(preDefinedPath):
            if os.access(preDefinedPath, os.R_OK):
                return preDefinedPath
    # Either file is missing or is not readable
    return

def get_config(config_file):
    """This function read and returns jsons configuration data

      :param config_file: json configuration file name
      :returns: json data

    """
    logger = get_logger()
    logger.info("Loading config file: '%s'" % config_file)
    try:
        json_data = open(config_file)
        data = json.load(json_data)
        return data
    except Exception, e:
        logger.error("Error: " + str(e))

    return None

def get_machine_uuid():
    """This function uses subprocess to get node uuid and cached it for future use

      :returns: server uuid
                None

    """
    logger = get_logger()
    server_uptime = None
    cache_uptime = None
    cache_file = '.uuid.cache'
    uuid = None
    cache_content = [None] * 2

    # Getting machine uptime.
    try:
        uptime_file = open('/proc/uptime')
        contents = uptime_file.read().split()
        uptime_file.close()
        server_uptime = str(int(float(contents[0])))
    except Exception, e:
        logger.warning("Unable to get uptime")
        logger.debug('%s' % str(e))
        pass

    if server_uptime is None:
        logger.debug("Failed to get server uptime")
    else:
        logger.debug("server uptime: %s" % server_uptime)
        logger.debug("Checking if cache file '%s' already exists" % cache_file)
        # Check if cache file already exists.
        cache_file = check_file(cache_file)
        if cache_file is not None:
            logger.info("Getting uptime and node id from cache file")
            cache_content = None
            try:
                rfh = open(cache_file, 'r').read()
                cache_content = rfh.split('\n')
            except:
                logger.warning("Unable to read a file '%s' in '%s'"
                               % (cache_file, '/etc/rax-autoscaler'))
                pass

            # Cache file should contain two lines, uptime & uuid.
            if (not cache_content[0] or cache_content[0] is None
                    or not cache_content[1] or cache_content[1] is None):
                logger.warning("Cache file is corrupted, failed to"
                               " read the content")
            else:
                # Compare uptime in cache file with server uptime.
                # Line one of cache file expected to be uptime in sec.
                try:
                    if int(cache_content[0]) < int(server_uptime):
                        uuid = cache_content[1]
                    else:
                        logger.warning("Invalid uptime found in cache file")
                        logger.debug("uptime: %s cache uptime: %s"
                                     % (server_uptime, cache_content[0]))
                except:
                    logger.warning("Invalid content found in cache file")
                    pass

        if uuid is None:
            logger.info('Launching xenstore query to get server uuid')
            try:
                name = subprocess.Popen(['xenstore-read name'], shell=True,
                                        stdout=subprocess.PIPE
                                        ).communicate()[0]
                id = name.strip()
                uuid = id[9:]
            except Exception, e:
                logger.error("Error: " + str(e))
                return None

            if server_uptime is not None:
                cache_file = '.uuid.cache'
                # Check if file exists in cwd
                if os.path.isfile(cache_file) is False:
                    if os.path.isdir('/etc/rax-autoscaler') is True:
                        cache_file = '/etc/rax-autoscaler/.uuid.cache'

                logger.info("Creating cache file '%s'" % cache_file)
                try:
                    wfh = open(cache_file, 'w')
                    wfh.write(server_uptime)
                    wfh.write('\n')
                    wfh.write(uuid)
                    wfh.close()
                except Exception, e:
                    logger.warning("Unable to create a file '%s': '%s'"
                                   % (cache_file, str(e)))
                    pass

    return uuid

def get_user_value(args, config, key):
    """This function returns value associated with the key if its available in
       user arguments else in json config file.

      :param args: user arguments
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    value = None
    try:
        if args[key] is None:
            value = config['auth'][key.lower()]
        else:
            value = args[key]
    except:
            logger.error("Invalid config, '" + key +
                         "' key not found in authentication section")

    return value

def get_group_value(config, group, key):
    """This function returns value in autoscale_groups section associated with
       provided key.

    :type config: object
      :param group: group name
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    try:
        value = config['autoscale_groups'][group][key]
        if value is not None:
            return value
    except:
        logger.error("Error: unable to get value for key '" + key +
                     "' from group '" + group + "'")

    return None

def get_webhook_value(config, group, key):
    """This function returns value in webhooks section of json file which is
       associated with provided key.

      :param group: group name
      :param config: json configuration data
      :param key: key name
      :returns: value associated with key

    """
    logger = get_logger()
    try:
        value = config['autoscale_groups'][group]['webhooks'][key]
        if value is not None:
            return value
    except:
        logger.warning("Unable to find value for key: '%s' in group '%s'"
                       % (key, group))

    return None

def webhook_call(config_data, group, policy, key):
    """This function makes webhook calls.

      :param config_data: json configuration data
      :param group: group name
      :param policy: policy type
      :param key: key name

    """
    logger = get_logger()

    logger.info('Launching %s webhook call' % key)
    try:
        urls = get_webhook_value(config_data, group, policy)[key]
    except (KeyError, TypeError):
        logger.error('Webhook urls for %s cannot be found in config' % key)
        return None

    try:
        group_config = config_data['autoscale_groups'][group]
        data = json.dumps({
            'group_id': group_config['group_id'],
            'scale_up_policy': group_config['scale_up_policy'],
            'scale_down_policy': group_config['scale_down_policy'],
            'check_type': group_config['check_type'],
            'metric_name': group_config['metric_name'],
            'scale_up_threshold': group_config['scale_up_threshold'],
            'scale_down_threshold': group_config['scale_down_threshold']
        })
    except KeyError as error:
        logger.error('Cannot build webhook data. invalid key: %s' % error)
        return None

    for url in urls:
        logger.info("Sending POST request to url: '%s'" % url)
        try:
            response = requests.post(url, json=data)
            logger.info("Received status code %d from url: '%s'"
                        % (response.status_code, url))
        except Exception, e:
            logger.warning(str(e))

    return None
<|endoftext|>


<commit_before># various CORE services that implement functions for web-servers
#
# Copyright (C) 2014 Robert Wuttke <robert@benocs.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import os

from core.service import CoreService, addservice
from core.misc.utils import *

from core.services import utility

class Lighttpd(BaseContentService):
    _name = "Lighttpd"
    _configs = ("/etc/lighttpd/lighttpd.conf",)
    _dirs = (("/etc/lighttpd", "union"), ("/var/www", "bind"),
            ("/var/cache/lighttpd", "bind"),
            ("/var/log/lighttpd", "bind"), ("/var/run", "bind"))
    _startup = ("service lighttpd start",)
    _shutdown = ("service lighttpd stop",)
    _verify = ("service lighttpd status",)

    @classmethod
    def generateconfig(cls, node, filename, services):
        if filename == cls._configs[0]:
            return cls.generateLighttpdConf(node, filename)
        else:
            return ""

    @classmethod
    def generateLighttpdConf(cls, node, filename):
        # TODO: for now, only return default config
        return cls.generateDefaultLighttpdConf()

    @classmethod
    def populateDirectory(cls, node, directory, services):
        print('populateDirectory: %s ' % str(directory))
        if directory == cls._dirs[1]:
            ContentServerContent.getFiles(node)

    @staticmethod
    def generateDefaultLighttpdConf():
        return """server.modules = (
    "mod_access",
    "mod_alias",
    "mod_compress",
    "mod_redirect",
    "mod_accesslog",
#   "mod_rewrite",
)

server.document-root        = "/var/www"
server.upload-dirs          = ("/var/cache/lighttpd/uploads")
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80

accesslog.filename = "/var/log/lighttpd/access.log"

index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
"""

addservice(Lighttpd)

<commit_msg>[services/web_services] added missing import<commit_after># various CORE services that implement functions for web-servers
#
# Copyright (C) 2014 Robert Wuttke <robert@benocs.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import os

from core.service import CoreService, addservice
from core.misc.utils import *

class BaseWebService(CoreService):
    _name = "WebService"
    _group = "Utility"
    _depends = ()

class Lighttpd(BaseWebService):
    _name = "Lighttpd"
    _configs = ("/etc/lighttpd/lighttpd.conf",)
    _dirs = (("/etc/lighttpd", "union"), ("/var/www", "bind"),
            ("/var/cache/lighttpd", "bind"),
            ("/var/log/lighttpd", "bind"), ("/var/run", "bind"))
    _startup = ("service lighttpd start",)
    _shutdown = ("service lighttpd stop",)
    _verify = ("service lighttpd status",)

    @classmethod
    def generateconfig(cls, node, filename, services):
        if filename == cls._configs[0]:
            return cls.generateLighttpdConf(node, filename)
        else:
            return ""

    @classmethod
    def generateLighttpdConf(cls, node, filename):
        # TODO: for now, only return default config
        return cls.generateDefaultLighttpdConf()

    @staticmethod
    def generateDefaultLighttpdConf():
        return """server.modules = (
    "mod_access",
    "mod_alias",
    "mod_compress",
    "mod_redirect",
    "mod_accesslog",
#   "mod_rewrite",
)

server.document-root        = "/var/www"
server.upload-dirs          = ("/var/cache/lighttpd/uploads")
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80

accesslog.filename = "/var/log/lighttpd/access.log"

index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
"""

addservice(Lighttpd)

<|endoftext|>


<commit_before>from __future__ import generators

from rdflib import URIRef, BNode, Literal, Namespace, RDF, RDFS

from rdflib.util import check_statement, check_pattern, check_context
from rdflib.util import check_subject, check_predicate, check_object

from rdflib import plugin, exceptions

from rdflib.backends import Backend
from rdflib.syntax.serializer import Serializer
from rdflib.syntax.parsers import Parser

from rdflib.syntax.NamespaceManager import NamespaceManager

from rdflib.URLInputSource import URLInputSource
from xml.sax.xmlreader import InputSource
from xml.sax.saxutils import prepare_input_source

from rdflib.interfaces import implements, IGraph

import logging

class Graph(object):
    """
    An RDF Graph.  The constructor accepts one argument, the 'backend'
    that will be used to store the graph data (see the 'backends'
    package for backends currently shipped with rdflib).

    Backends can be context-aware or unaware.  Unaware backends take
    up (some) less space in the backend but cannot support features
    that require context, such as true merging/demerging of sub-graphs
    and provenance.
    """

    implements(IGraph)

    def __init__(self, backend='default'):
        super(Graph, self).__init__()
        if not isinstance(backend, Backend):
            # TODO: error handling
            backend = plugin.get(backend, Backend)()
        self.__backend = backend
        self.__namespace_manager = None

    def __get_backend(self):
        return self.__backend
    backend = property(__get_backend)

    def _get_namespace_manager(self):
        if self.__namespace_manager is None:
            self.__namespace_manager = NamespaceManager(self)
        return self.__namespace_manager
    def _set_namespace_manager(self, nm):
        self.__namespace_manager = nm
    namespace_manager = property(_get_namespace_manager, _set_namespace_manager)

    def _get_context_aware(self):
        return self.__backend.context_aware
    context_aware = property(_get_context_aware)

    def open(self, path):
        """ Open the graph backend.  Might be necessary for backends
        that require opening a connection to a database or acquiring some resource."""
        if hasattr(self.__backend, "open"):
            self.__backend.open(path)

    def close(self):
        """ Close the graph backend.  Might be necessary for backends
        that require closing a connection to a database or releasing some resource."""
        if hasattr(self.__backend, "close"):
            self.__backend.close()

    def add(self, (s, p, o), context=None, quoted=False):
        """ Add a triple, optionally provide a context.  A 3-tuple or
        rdflib.Triple can be provided.  Context must be a URIRef.  If
        no context is provides, triple is added to the default
        context."""
        check_statement((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            self.__backend.add((s, p, o), context, quoted)
        else:
            assert quoted==False
            self.__backend.add((s, p, o))

    def remove(self, (s, p, o), context=None):
        """ Remove a triple from the graph.  If the triple does not
        provide a context attribute, removes the triple from all
        contexts."""

        check_pattern((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            self.__backend.remove((s, p, o), context)
        else:
            self.__backend.remove((s, p, o))

    def triples(self, (s, p, o), context=None):
        """ Generator over the triple store.  Returns triples that
        match the given triple pattern.  If triple pattern does not
        provide a context, all contexts will be searched."""
        check_pattern((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            for t in self.__backend.triples((s, p, o), context):
                yield t
        else:
            for t in self.__backend.triples((s, p, o)):
                yield t

    def contexts(self, triple=None):
        """ Generator over all contexts in the graph. If triple is specified, a generator over all contexts the triple is in."""
        assert self.context_aware, "Graph must be context aware to use this method"
        for context in self.__backend.contexts(triple):
            yield context

    def value(self, subject, predicate=RDF.value, object=None, default=None, any=False):
        """ Get a value for a subject/predicate, predicate/object, or
        subject/object pair -- exactly one of subject, predicate,
        object must be None. Useful if one knows that there may only
        be one value.

        It is one of those situations that occur a lot, hence this
        'macro' like utility

        Parameters:
        -----------
        subject, predicate, object  -- exactly one must be None
        default -- value to be returned if no values found
        any -- if True:
                 return any value in the case there is more than one
               else:
                 raise UniquenessError
        """
        retval = default
        if object is None:
            assert subject is not None
            assert predicate is not None
            values = self.objects(subject, predicate)
        if subject is None:
            assert predicate is not None
            assert object is not None
            values = self.subjects(predicate, object)
        if predicate is None:
            assert subject is not None
            assert object is not None
            values = self.predicates(subject, object)

        try:
            retval = values.next()
        except StopIteration, e:
            retval = default
        else:
            if any is False:
                try:
                    next = values.next()
                    raise exceptions.UniquenessError([retval, next] + list(values))
                except StopIteration, e:
                    pass
        return retval

    def label(self, subject, default=''):
        """ Queries for the RDFS.label of the subject, returns default if no label exists. """
        if subject is None:
            return default
        return self.value(subject, RDFS.label, default=default, any=True)

    def comment(self, subject, default=''):
        """ Queries for the RDFS.comment of the subject, returns default if no comment exists. """
        if subject is None:
            return default
        return self.value(subject, RDFS.comment, default=default, any=True)

    def items(self, list):
        """Generator over all items in the resource specified by list (an RDF collection)"""
        while list:
            item = self.value(list, RDF.first)
            if item:
                yield item
            list = self.value(list, RDF.rest)

    def __iter__(self):
        """ Iterates over all triples in the store. """
        return self.triples((None, None, None))

    def __contains__(self, triple):
        """ Support for 'triple in graph' syntax. """
        for triple in self.triples(triple):
            return 1
        return 0

    def __len__(self, context=None):
        """ Returns the number of triples in the graph. If context is specified then the number of triples in the context is returned instead."""
        if self.context_aware:
            return self.__backend.__len__(context)
        else:
            return self.__backend.__len__()

    def __eq__(self, other):
        """ Test if Graph is exactly equal to Graph other."""
        # Note: this is not a test of isomorphism, but rather exact
        # equality.
        if not other or len(self)!=len(other):
            return 0
        for s, p, o in self:
            if not (s, p, o) in other:
                return 0
        for s, p, o in other:
            if not (s, p, o) in self:
                return 0
        return 1

    def __iadd__(self, other):
        """ Add all triples in Graph other to Graph."""
        for triple in other:
            self.__backend.add(triple) # TODO: context
        return self

    def __isub__(self, other):
        """ Subtract all triples in Graph other from Graph."""
        for triple in other:
            self.__backend.remove(triple)
        return self

    def subjects(self, predicate=None, object=None):
        """ A generator of subjects with the given predicate and object. """
        for s, p, o in self.triples((None, predicate, object)):
            yield s

    def predicates(self, subject=None, object=None):
        """ A generator of predicates with the given subject and object. """
        for s, p, o in self.triples((subject, None, object)):
            yield p

    def objects(self, subject=None, predicate=None):
        """ A generator of objects with the given subject and predicate. """
        for s, p, o in self.triples((subject, predicate, None)):
            yield o

    def subject_predicates(self, object=None):
        """ A generator of (subject, predicate) tuples for the given object """
        for s, p, o in self.triples((None, None, object)):
            yield s, p

    def subject_objects(self, predicate=None):
        """ A generator of (subject, object) tuples for the given predicate """
        for s, p, o in self.triples((None, predicate, None)):
            yield s, o

    def predicate_objects(self, subject=None):
        """ A generator of (predicate, object) tuples for the given subject """
        for s, p, o in self.triples((subject, None, None)):
            yield p, o

    def get_context(self, identifier):
        """ Returns a Context graph for the given identifier, which
        must be a URIRef or BNode."""
        assert isinstance(identifier, URIRef) or \
               isinstance(identifier, BNode)
        return Context(self, identifier)

    def remove_context(self, identifier):
        """ Removes the given context from the graph. """
        self.__backend.remove_context(identifier)

    def transitive_objects(self, subject, property, remember=None):
        """ """
        if remember==None:
            remember = {}
        if not subject in remember:
            remember[subject] = 1
            yield subject
            for object in self.objects(subject, property):
                for o in self.transitive_objects(object, property, remember):
                    yield o

    def transitive_subjects(self, predicate, object, remember=None):
        """ """
        if remember==None:
            remember = {}
        if not object in remember:
            remember[object] = 1
            yield object
            for subject in self.subjects(predicate, object):
                for s in self.transitive_subjects(predicate, subject, remember):
                    yield s

    def load(self, location, publicID=None, format="xml"):
        """ for b/w compat. See parse."""
        return self.parse(location, publicID, format)

    def save(self, location, format="xml", base=None, encoding=None):
        """ for b/x compat. See serialize."""
        return self.serialize(location, format, base, encoding)

    def context_id(self, uri):
        uri = uri.split("#", 1)[0]
        return URIRef("%s#context" % uri)

    def prepare_input_source(self, source, publicID=None):
        if isinstance(source, InputSource):
            input_source = source
        else:
            if hasattr(source, "read") and not isinstance(source, Namespace): # we need to make sure it's not an instance of Namespace since Namespace instances have a read attr
                input_source = prepare_input_source(source)
            else:
                location = self.absolutize(source)
                input_source = URLInputSource(location)
                publicID = publicID or location
        if publicID:
            input_source.setPublicId(publicID)
        id = input_source.getPublicId()
        if id is None:
            logging.info("no publicID set for source. Using '' for publicID.")
            input_source.setPublicId("")
        return input_source

    def parse(self, source, publicID=None, format="xml"):
        """ Parse source into Graph. If Graph is context-aware it'll get loaded into it's own context (sub graph). Format defaults to xml (AKA rdf/xml). The publicID argument is for specifying the logical URI for the case that it's different from the physical source URI. Returns the context into which the source was parsed."""
        source = self.prepare_input_source(source, publicID)
        if self.context_aware:
            id = self.context_id(URIRef(source.getPublicId()))
            self.remove_context(id)
            context = self.get_context(id)
        else:
            context = self
        parser = plugin.get(format, Parser)()
        parser.parse(source, context)
        return context

        return parser.parse(source, publicID, format)

    def serialize(self, destination=None, format="xml", base=None, encoding=None):
        """ Serialize the Graph to destination. If destination is None serialize method returns the serialization as a string. Format defaults to xml (AKA rdf/xml)."""
        serializer = plugin.get(format, Serializer)(self)
        return serializer.serialize(destination, base=base, encoding=encoding)

    def seq(self, subject) :
        """
        Check if subject is an rdf:Seq. If yes, it returns a Seq
        class instance, None otherwise.
        """
        if (subject, RDF.type, RDF.Seq) in self :
            return Seq(self, subject)
        else :
            return None

    def absolutize(self, uri, defrag=1):
        """ Will turn uri into an absolute URI if it's not one already. """
        return self.namespace_manager.absolutize(uri, defrag)

    def bind(self, prefix, namespace, override=True):
        """Bind prefix to namespace. If override is True will bind namespace to given prefix if namespace was already bound to a different prefix."""
        return self.namespace_manager.bind(prefix, namespace, override=override)

    def namespaces(self):
        """Generator over all the prefix, namespace tuples.
        """
        for prefix, namespace in self.namespace_manager.namespaces():
            yield prefix, namespace

class Context(Graph):
    def __init__(self, graph, identifier):
        super(Context, self).__init__(backend=graph.backend)
        self.graph = graph
        self.namespace_manager = graph.namespace_manager
        self.identifier = identifier

    def _get_context_aware(self):
        return False
    context_aware = property(_get_context_aware)

    def add(self, triple, context=None, quoted=False): # TODO: test if we need context=None arg
        #assert context is None
        self.backend.add(triple, self.identifier, quoted)

    def remove(self, triple, context=None):
        assert context is None
        self.backend.remove(triple, self.identifier)

    def triples(self, triple, context=None):
        assert context is None
        return self.backend.triples(triple, self.identifier)

    def bind(self, prefix, namespace, override=True):
        return self.graph.bind(prefix, namespace, override)

    def __len__(self, context=None):
        assert context is None
        return self.backend.__len__(self.identifier)

class Seq(object):
    """
    Wrapper around an RDF Seq resource. It implements a container
    type in Python with the order of the items returned
    corresponding to the Seq content. It is based on the natural
    ordering of the predicate names _1, _2, _3, etc, which is the
    'implementation' of a sequence in RDF terms.
    """
    _list  = {}
    def __init__(self, graph, subject):
        """
        The graph which contains the sequence. The subject is
        simply the subject which is supposed to be a Seq.

        Parameters:
        -----------
        graph: the graph containing the Seq
        subject: the subject of a Seq. Note that the init does not
        check whether this is a Seq, this is done in whoever
        creates this instance!
        """

        _list = self._list = list()
        LI_INDEX = RDF.RDFNS["_"]
        for (p, o) in graph.predicate_objects(subject):
            if p.startswith(LI_INDEX): #!= RDF.Seq: #
                _list.append(("%s" % p, o))
        # here is the trick: the predicates are _1, _2, _3, etc. Ie,
        # by sorting the keys we have what we want!
        _list.sort()

    def __iter__(self):
        """Generator over the index, item tuples in the Seq"""
        for index, item in self._list:
            yield item

    def __len__(self):
        """ Returns the length of the Seq."""
        return len(self._list)

    def __getitem__(self, index):
        """ Returns the item given by index from the Seq."""
        index, item = self._list.__getitem__(index)
        return item
<commit_msg>go back through Graph<commit_after>from __future__ import generators

from rdflib import URIRef, BNode, Literal, Namespace, RDF, RDFS

from rdflib.util import check_statement, check_pattern, check_context
from rdflib.util import check_subject, check_predicate, check_object

from rdflib import plugin, exceptions

from rdflib.backends import Backend
from rdflib.syntax.serializer import Serializer
from rdflib.syntax.parsers import Parser

from rdflib.syntax.NamespaceManager import NamespaceManager

from rdflib.URLInputSource import URLInputSource
from xml.sax.xmlreader import InputSource
from xml.sax.saxutils import prepare_input_source

from rdflib.interfaces import implements, IGraph

import logging

class Graph(object):
    """
    An RDF Graph.  The constructor accepts one argument, the 'backend'
    that will be used to store the graph data (see the 'backends'
    package for backends currently shipped with rdflib).

    Backends can be context-aware or unaware.  Unaware backends take
    up (some) less space in the backend but cannot support features
    that require context, such as true merging/demerging of sub-graphs
    and provenance.
    """

    implements(IGraph)

    def __init__(self, backend='default'):
        super(Graph, self).__init__()
        if not isinstance(backend, Backend):
            # TODO: error handling
            backend = plugin.get(backend, Backend)()
        self.__backend = backend
        self.__namespace_manager = None

    def __get_backend(self):
        return self.__backend
    backend = property(__get_backend)

    def _get_namespace_manager(self):
        if self.__namespace_manager is None:
            self.__namespace_manager = NamespaceManager(self)
        return self.__namespace_manager
    def _set_namespace_manager(self, nm):
        self.__namespace_manager = nm
    namespace_manager = property(_get_namespace_manager, _set_namespace_manager)

    def _get_context_aware(self):
        return self.__backend.context_aware
    context_aware = property(_get_context_aware)

    def open(self, path):
        """ Open the graph backend.  Might be necessary for backends
        that require opening a connection to a database or acquiring some resource."""
        if hasattr(self.__backend, "open"):
            self.__backend.open(path)

    def close(self):
        """ Close the graph backend.  Might be necessary for backends
        that require closing a connection to a database or releasing some resource."""
        if hasattr(self.__backend, "close"):
            self.__backend.close()

    def add(self, (s, p, o), context=None, quoted=False):
        """ Add a triple, optionally provide a context.  A 3-tuple or
        rdflib.Triple can be provided.  Context must be a URIRef.  If
        no context is provides, triple is added to the default
        context."""
        check_statement((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            self.__backend.add((s, p, o), context, quoted)
        else:
            assert quoted==False
            self.__backend.add((s, p, o))

    def remove(self, (s, p, o), context=None):
        """ Remove a triple from the graph.  If the triple does not
        provide a context attribute, removes the triple from all
        contexts."""

        check_pattern((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            self.__backend.remove((s, p, o), context)
        else:
            self.__backend.remove((s, p, o))

    def triples(self, (s, p, o), context=None):
        """ Generator over the triple store.  Returns triples that
        match the given triple pattern.  If triple pattern does not
        provide a context, all contexts will be searched."""
        check_pattern((s, p, o))
        if self.context_aware:
            if context:
                check_context(context)
            for t in self.__backend.triples((s, p, o), context):
                yield t
        else:
            for t in self.__backend.triples((s, p, o)):
                yield t

    def contexts(self, triple=None):
        """ Generator over all contexts in the graph. If triple is specified, a generator over all contexts the triple is in."""
        assert self.context_aware, "Graph must be context aware to use this method"
        for context in self.__backend.contexts(triple):
            yield context

    def value(self, subject, predicate=RDF.value, object=None, default=None, any=False):
        """ Get a value for a subject/predicate, predicate/object, or
        subject/object pair -- exactly one of subject, predicate,
        object must be None. Useful if one knows that there may only
        be one value.

        It is one of those situations that occur a lot, hence this
        'macro' like utility

        Parameters:
        -----------
        subject, predicate, object  -- exactly one must be None
        default -- value to be returned if no values found
        any -- if True:
                 return any value in the case there is more than one
               else:
                 raise UniquenessError
        """
        retval = default
        if object is None:
            assert subject is not None
            assert predicate is not None
            values = self.objects(subject, predicate)
        if subject is None:
            assert predicate is not None
            assert object is not None
            values = self.subjects(predicate, object)
        if predicate is None:
            assert subject is not None
            assert object is not None
            values = self.predicates(subject, object)

        try:
            retval = values.next()
        except StopIteration, e:
            retval = default
        else:
            if any is False:
                try:
                    next = values.next()
                    raise exceptions.UniquenessError([retval, next] + list(values))
                except StopIteration, e:
                    pass
        return retval

    def label(self, subject, default=''):
        """ Queries for the RDFS.label of the subject, returns default if no label exists. """
        if subject is None:
            return default
        return self.value(subject, RDFS.label, default=default, any=True)

    def comment(self, subject, default=''):
        """ Queries for the RDFS.comment of the subject, returns default if no comment exists. """
        if subject is None:
            return default
        return self.value(subject, RDFS.comment, default=default, any=True)

    def items(self, list):
        """Generator over all items in the resource specified by list (an RDF collection)"""
        while list:
            item = self.value(list, RDF.first)
            if item:
                yield item
            list = self.value(list, RDF.rest)

    def __iter__(self):
        """ Iterates over all triples in the store. """
        return self.triples((None, None, None))

    def __contains__(self, triple):
        """ Support for 'triple in graph' syntax. """
        for triple in self.triples(triple):
            return 1
        return 0

    def __len__(self, context=None):
        """ Returns the number of triples in the graph. If context is specified then the number of triples in the context is returned instead."""
        if self.context_aware:
            return self.__backend.__len__(context)
        else:
            return self.__backend.__len__()

    def __eq__(self, other):
        """ Test if Graph is exactly equal to Graph other."""
        # Note: this is not a test of isomorphism, but rather exact
        # equality.
        if not other or len(self)!=len(other):
            return 0
        for s, p, o in self:
            if not (s, p, o) in other:
                return 0
        for s, p, o in other:
            if not (s, p, o) in self:
                return 0
        return 1

    def __iadd__(self, other):
        """ Add all triples in Graph other to Graph."""
        for triple in other:
            self.__backend.add(triple) # TODO: context
        return self

    def __isub__(self, other):
        """ Subtract all triples in Graph other from Graph."""
        for triple in other:
            self.__backend.remove(triple)
        return self

    def subjects(self, predicate=None, object=None):
        """ A generator of subjects with the given predicate and object. """
        for s, p, o in self.triples((None, predicate, object)):
            yield s

    def predicates(self, subject=None, object=None):
        """ A generator of predicates with the given subject and object. """
        for s, p, o in self.triples((subject, None, object)):
            yield p

    def objects(self, subject=None, predicate=None):
        """ A generator of objects with the given subject and predicate. """
        for s, p, o in self.triples((subject, predicate, None)):
            yield o

    def subject_predicates(self, object=None):
        """ A generator of (subject, predicate) tuples for the given object """
        for s, p, o in self.triples((None, None, object)):
            yield s, p

    def subject_objects(self, predicate=None):
        """ A generator of (subject, object) tuples for the given predicate """
        for s, p, o in self.triples((None, predicate, None)):
            yield s, o

    def predicate_objects(self, subject=None):
        """ A generator of (predicate, object) tuples for the given subject """
        for s, p, o in self.triples((subject, None, None)):
            yield p, o

    def get_context(self, identifier):
        """ Returns a Context graph for the given identifier, which
        must be a URIRef or BNode."""
        assert isinstance(identifier, URIRef) or \
               isinstance(identifier, BNode)
        return Context(self, identifier)

    def remove_context(self, identifier):
        """ Removes the given context from the graph. """
        self.__backend.remove_context(identifier)

    def transitive_objects(self, subject, property, remember=None):
        """ """
        if remember==None:
            remember = {}
        if not subject in remember:
            remember[subject] = 1
            yield subject
            for object in self.objects(subject, property):
                for o in self.transitive_objects(object, property, remember):
                    yield o

    def transitive_subjects(self, predicate, object, remember=None):
        """ """
        if remember==None:
            remember = {}
        if not object in remember:
            remember[object] = 1
            yield object
            for subject in self.subjects(predicate, object):
                for s in self.transitive_subjects(predicate, subject, remember):
                    yield s

    def load(self, location, publicID=None, format="xml"):
        """ for b/w compat. See parse."""
        return self.parse(location, publicID, format)

    def save(self, location, format="xml", base=None, encoding=None):
        """ for b/x compat. See serialize."""
        return self.serialize(location, format, base, encoding)

    def context_id(self, uri):
        uri = uri.split("#", 1)[0]
        return URIRef("%s#context" % uri)

    def prepare_input_source(self, source, publicID=None):
        if isinstance(source, InputSource):
            input_source = source
        else:
            if hasattr(source, "read") and not isinstance(source, Namespace): # we need to make sure it's not an instance of Namespace since Namespace instances have a read attr
                input_source = prepare_input_source(source)
            else:
                location = self.absolutize(source)
                input_source = URLInputSource(location)
                publicID = publicID or location
        if publicID:
            input_source.setPublicId(publicID)
        id = input_source.getPublicId()
        if id is None:
            logging.info("no publicID set for source. Using '' for publicID.")
            input_source.setPublicId("")
        return input_source

    def parse(self, source, publicID=None, format="xml"):
        """ Parse source into Graph. If Graph is context-aware it'll get loaded into it's own context (sub graph). Format defaults to xml (AKA rdf/xml). The publicID argument is for specifying the logical URI for the case that it's different from the physical source URI. Returns the context into which the source was parsed."""
        source = self.prepare_input_source(source, publicID)
        if self.context_aware:
            id = self.context_id(URIRef(source.getPublicId()))
            self.remove_context(id)
            context = self.get_context(id)
        else:
            context = self
        parser = plugin.get(format, Parser)()
        parser.parse(source, context)
        return context

        return parser.parse(source, publicID, format)

    def serialize(self, destination=None, format="xml", base=None, encoding=None):
        """ Serialize the Graph to destination. If destination is None serialize method returns the serialization as a string. Format defaults to xml (AKA rdf/xml)."""
        serializer = plugin.get(format, Serializer)(self)
        return serializer.serialize(destination, base=base, encoding=encoding)

    def seq(self, subject) :
        """
        Check if subject is an rdf:Seq. If yes, it returns a Seq
        class instance, None otherwise.
        """
        if (subject, RDF.type, RDF.Seq) in self :
            return Seq(self, subject)
        else :
            return None

    def absolutize(self, uri, defrag=1):
        """ Will turn uri into an absolute URI if it's not one already. """
        return self.namespace_manager.absolutize(uri, defrag)

    def bind(self, prefix, namespace, override=True):
        """Bind prefix to namespace. If override is True will bind namespace to given prefix if namespace was already bound to a different prefix."""
        return self.namespace_manager.bind(prefix, namespace, override=override)

    def namespaces(self):
        """Generator over all the prefix, namespace tuples.
        """
        for prefix, namespace in self.namespace_manager.namespaces():
            yield prefix, namespace

class Context(Graph):
    def __init__(self, graph, identifier):
        super(Context, self).__init__(backend=graph.backend)
        self.graph = graph
        self.namespace_manager = graph.namespace_manager
        self.identifier = identifier

    def _get_context_aware(self):
        return False
    context_aware = property(_get_context_aware)

    def add(self, triple, context=None, quoted=False): # TODO: test if we need context=None arg
        assert context is None
        self.graph.add(triple, self.identifier, quoted)

    def remove(self, triple, context=None):
        assert context is None
        self.backend.remove(triple, self.identifier)

    def triples(self, triple, context=None):
        assert context is None
        return self.backend.triples(triple, self.identifier)

    def bind(self, prefix, namespace, override=True):
        return self.graph.bind(prefix, namespace, override)

    def __len__(self, context=None):
        assert context is None
        return self.backend.__len__(self.identifier)

class Seq(object):
    """
    Wrapper around an RDF Seq resource. It implements a container
    type in Python with the order of the items returned
    corresponding to the Seq content. It is based on the natural
    ordering of the predicate names _1, _2, _3, etc, which is the
    'implementation' of a sequence in RDF terms.
    """
    _list  = {}
    def __init__(self, graph, subject):
        """
        The graph which contains the sequence. The subject is
        simply the subject which is supposed to be a Seq.

        Parameters:
        -----------
        graph: the graph containing the Seq
        subject: the subject of a Seq. Note that the init does not
        check whether this is a Seq, this is done in whoever
        creates this instance!
        """

        _list = self._list = list()
        LI_INDEX = RDF.RDFNS["_"]
        for (p, o) in graph.predicate_objects(subject):
            if p.startswith(LI_INDEX): #!= RDF.Seq: #
                _list.append(("%s" % p, o))
        # here is the trick: the predicates are _1, _2, _3, etc. Ie,
        # by sorting the keys we have what we want!
        _list.sort()

    def __iter__(self):
        """Generator over the index, item tuples in the Seq"""
        for index, item in self._list:
            yield item

    def __len__(self):
        """ Returns the length of the Seq."""
        return len(self._list)

    def __getitem__(self, index):
        """ Returns the item given by index from the Seq."""
        index, item = self._list.__getitem__(index)
        return item
<|endoftext|>


<commit_before>import pytest
from unittest import mock, TestCase

import datetime
from freezegun import freeze_time

import core.config
import core.input
import core.widget
import modules.core.datetime

pytest.importorskip("datetime")

def build_module(args = []):
    config = core.config.Config(args)
    return modules.core.datetime.Module(config=config, theme=None)

def build_widget():
    return core.widget.Widget()

class DatetimeTest(TestCase):
    def setup_class(self):
        locale_patcher = mock.patch('locale.getdefaultlocale')
        locale_mock = locale_patcher.start()
        locale_mock.return_value = ('en-US', 'UTF-8')

        self.widget = build_widget()

    def test_load_module(self):
        __import__("modules.core.datetime")

    @freeze_time('2020-10-15')
    def test_default_format(self):
        module = build_module()
        assert module.full_text(self.widget) == '10/15/2020 12:00:00 AM'

    @freeze_time('2020-10-20')
    def test_custom_format(self):
        module = build_module(['-p', 'datetime.format=%Y.%m.%d'])
        assert module.full_text(self.widget) == '2020.10.20'

    @freeze_time('2020-01-10 10:20:30')
    @mock.patch('locale.getdefaultlocale')
    def test_invalid_locale(self, locale_mock):
        locale_mock.return_value = ('in-IN', 'UTF-0')

        module = build_module()
        assert module.full_text(self.widget) == '01/10/2020 10:20:30 AM'

    @mock.patch('core.input.register')
    def test_register_left_mouse_action(self, input_register_mock):
        module = build_module()

        input_register_mock.assert_called_with(
            module,
            button=core.input.LEFT_MOUSE,
            cmd='calendar'
        )

<commit_msg>Remove useless import<commit_after>import pytest
from unittest import mock, TestCase
from freezegun import freeze_time

import core.config
import core.input
import core.widget
import modules.core.datetime

pytest.importorskip("datetime")

def build_module(args = []):
    config = core.config.Config(args)
    return modules.core.datetime.Module(config=config, theme=None)

def build_widget():
    return core.widget.Widget()

class DatetimeTest(TestCase):
    def setup_class(self):
        locale_patcher = mock.patch('locale.getdefaultlocale')
        locale_mock = locale_patcher.start()
        locale_mock.return_value = ('en-US', 'UTF-8')

        self.widget = build_widget()

    def test_load_module(self):
        __import__("modules.core.datetime")

    @freeze_time('2020-10-15')
    def test_default_format(self):
        module = build_module()
        assert module.full_text(self.widget) == '10/15/2020 12:00:00 AM'

    @freeze_time('2020-10-20')
    def test_custom_format(self):
        module = build_module(['-p', 'datetime.format=%Y.%m.%d'])
        assert module.full_text(self.widget) == '2020.10.20'

    @freeze_time('2020-01-10 10:20:30')
    @mock.patch('locale.getdefaultlocale')
    def test_invalid_locale(self, locale_mock):
        locale_mock.return_value = ('in-IN', 'UTF-0')

        module = build_module()
        assert module.full_text(self.widget) == '01/10/2020 10:20:30 AM'

    @mock.patch('core.input.register')
    def test_register_left_mouse_action(self, input_register_mock):
        module = build_module()

        input_register_mock.assert_called_with(
            module,
            button=core.input.LEFT_MOUSE,
            cmd='calendar'
        )

<|endoftext|>


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

"""
Created on 18 Sep 2016

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)
"""

from scs_core.data.json import JSONify
from scs_core.data.localized_datetime import LocalizedDatetime

from scs_core.particulate.opc_datum import OPCDatum
from scs_core.particulate.pmx_datum import PMxDatum

# --------------------------------------------------------------------------------------------------------------------

now = LocalizedDatetime.now()

opc = OPCDatum(now, 11, 22, 33, 9.1, [1, 2, 3, 4, 5, 6, 7, 8, 9], 11.1, 22.2, 33.3, 44.4)
print(opc)
print("-")

jstr = JSONify.dumps(opc)
print(jstr)
print("-")

# cast to PMxDatum...
opc.__class__ = PMxDatum
print(opc)
print("-")
<commit_msg>Added source field to Sample documents.<commit_after>#!/usr/bin/env python3

"""
Created on 18 Sep 2016

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)
"""

from scs_core.data.json import JSONify
from scs_core.data.localized_datetime import LocalizedDatetime

from scs_core.particulate.opc_datum import OPCDatum
from scs_core.particulate.pmx_datum import PMxDatum

# --------------------------------------------------------------------------------------------------------------------

now = LocalizedDatetime.now()

opc = OPCDatum('test', now, 11, 22, 33, 9.1, [1, 2, 3, 4, 5, 6, 7, 8, 9], 11.1, 22.2, 33.3, 44.4)
print(opc)
print("-")

jstr = JSONify.dumps(opc)
print(jstr)
print("-")

# cast to PMxDatum...
opc.__class__ = PMxDatum
print(opc)
print("-")
<|endoftext|>


<commit_before>#!/usr/bin/python
#-*- coding: utf-8 -*-
"""
OFGW Management Module
This module is a part of OFGW that is an extension to
OFELIA Control Framework. It contains CLI tool for providing management
actions on non-OpenFlow capatible devices.
"""

import sys
import argparse
import yaml

class InventoryParser(object):
    """Inventory configuration parser"""
    def __init__(self, filename="./inventory.conf"):

        self.groups = []
        self.params={}
        with open(filename) as fh:
            self.lines = fh.readlines()

    def getGroups(self):
        for line in self.lines:
            line = line.split("#")[0].strip()
            if line.startswith("[") and line.endswith("]"):
                group = line.strip("[]")
                self.groups.append(group)
        return self.groups

    def getParams(self, group=None):
        currentGroup=""
        d = {}
        if group != None:
            for line in self.lines:
                line = line.split("#")[0].strip()
                if line.startswith("[") and line.endswith("]"):
                    currentGroup = line.strip("[]")
                    d[currentGroup] = []
                elif line != "":
                    t = []
                    params = line.split(" ")
                    for param in params:
                        if param != "":
                            param = param.split("=")
                            key = param[0]
                            value = param[1]
                            t.append({key:value})
                    d[currentGroup].append(t)

        self.params = d
        return self.params

def parseGroupConfig(inventory_conf="./inventory.conf", groups_conf="./groups.yaml"):
    conf_invent = open(groups_conf, 'r')
    return yaml.load(conf_invent)

if __name__ == '__main__':
    # if len(sys.argv) < 1:
    #     usage();

    parser = argparse.ArgumentParser(description="OFGW management script")
    # group = parser.add_mutually_exclusive_group()
    # parser.add_argument("list",
    #                     help="Get list of available devices",
    #                     action="store_true")
    # parser.add_argument("reboot",
    #                     help="Reboot the selected device",
    #                     action="store_true")
    # parser.add_argument("reset",
    #                     help="Restore the factory settings on device",
    #                     action="store_true")
    parser.add_argument("command",
                        choices=["list", "reboot", "reset", "config"],
                        help="Management action")
    # parser.add_argument("DEVICE_ID",
    #                     help="Device identifier",
    #                     action="store_const")
    parser.add_argument("-s", "--status",
                        help="Get device status",
                        action="store_true")
    args = parser.parse_args()
    command = args.command

    if command == "list":
        print "Listing devices...\n"
    elif command == "reboot":
        print "Device reboot initialized...\n"
    elif command == "reset":
        print "Reset device to factory setting initialized...\n"
    elif command == "config":
        print "Parsing the configuration...\n"
        print "Group configuration\n------------------"
        print parseGroupConfig()
        print "\nHost parameters configuration\n---------------------------"
        parser = InventoryParser()
        print parser.getParams('group1')

    # print args.accumulate(args.integers)
<commit_msg>Changes in args parser<commit_after>#!/usr/bin/python
#-*- coding: utf-8 -*-
"""
OFGW Management Module
This module is a part of OFGW that is an extension to
OFELIA Control Framework. It contains CLI tool for providing management
actions on non-OpenFlow capatible devices.
"""

import sys
import argparse
import yaml

class InventoryParser(object):
    """Inventory configuration parser"""
    def __init__(self, filename="./inventory.conf"):

        self.groups = []
        self.params={}
        with open(filename) as fh:
            self.lines = fh.readlines()
        self.getGroups()
        self.getParams()

    def getGroups(self):
        for line in self.lines:
            line = line.split("#")[0].strip()
            if line.startswith("[") and line.endswith("]"):
                group = line.strip("[]")
                self.groups.append(group)
        return self.groups

    def getParams(self, group=None):
        currentGroup=""
        d = {}
        if group == None:
            for line in self.lines:
                line = line.split("#")[0].strip()
                if line.startswith("[") and line.endswith("]"):
                    currentGroup = line.strip("[]")
                    d[currentGroup] = []
                elif line != "":
                    t = []
                    params = line.split(" ")
                    for param in params:
                        if param != "":
                            param = param.split("=")
                            key = param[0]
                            value = param[1]
                            t.append({key:value})
                    d[currentGroup].append(t)

            self.params = d
            return self.params
        else:
            return self.params[group]

def parseGroupConfig(inventory_conf="./inventory.conf", groups_conf="./groups.yaml"):
    conf_invent = open(groups_conf, 'r')
    return yaml.load(conf_invent)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="OFGW management script")

    subparsers = parser.add_subparsers(help='Management command', dest="command")

    # List parser
    parser_list = subparsers.add_parser('list', help='List all devices')
    print parser_list

    # Reboot parser
    parser_reboot = subparsers.add_parser('reboot', help='Reboot the device [DEVICE_ID]')
    parser_reboot.add_argument("DEVICE_ID",
                        help="Device identifier")

    # Factory-reset parser
    parser_fact_reset = subparsers.add_parser('fact-reset', help='Reset the device and restory the factory settings {DEVICE_ID}')
    parser_fact_reset.add_argument("DEVICE_ID",
                        help="Device identifier")

    # Show parser
    parser_show = subparsers.add_parser('show', help='Show the device configuration/status {DEVICE_ID} [--ports, --of, --tables, --neighbors]')
    parser_show.add_argument("DEVICE_ID",
                        help="Device identifier")
    parser_show.add_argument("--all",
                        action="store_true",
                        help="Show all configuration - DEFAULT parameter")
    parser_show.add_argument("--ports",
                        action="store_true",
                    help="Show port status")
    parser_show.add_argument("--of",
                        action="store_true",
                    help="Show OpenFlow configuration")
    parser_show.add_argument("--tables",
                        action="store_true",
                    help="Show OpenFlow tables dump")
    parser_show.add_argument("--neighbors",
                        action="store_true",
                    help="Show device's neighbors")

    args = parser.parse_args()

    command = args.command

    if command == "list":
        print "Listing devices...\n"
    elif command == "reboot":
        print "Device reboot initialized...\n"
    elif command == "factory-reset":
        print "Reset device to factory setting initialized...\n"
    elif command == "config":
        print "Parsing the configuration...\n"
        if groupsBool:
            print parseGroupConfig()
            sys.exit()
        else:
            print "Group configuration\n------------------"
            print parseGroupConfig()
            print "\nHost parameters configuration\n---------------------------"
            parser = InventoryParser()
            print parser.getParams(group)

<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

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

import sys

# This module contains an implementation of a Tetris-like game called T-Drop.

# Example of the usage of this module:
#
#	import tdrop
#	# create board
#	board = tdrop.Board(6, 9) # width, height
#	# create a block.
#	block = tdrop.TBlock(1, 1, 1) # x, y, direction
#	board.drop(tdrop)
#

# This module is made as a solution to problem 2 of the Dutch
# Olympiad in Informatics.
#
# See http://www.informaticaolympiade.nl for more information.

class Board(object):
	"""
	The Board class represents a grid which contains blocks.
	"""
	def __init__(self, width = 6, height = 9):
		"""
		Initializes a new Board instance.

		Keyword arguments:
		width -- the width of the grid (default = 6)
		height -- the height of the grid (default = 9)
		"""
		self.width = width
		self.height = height
		self.blocks = []

	def is_valid(self, block):
		for rectangle in block.points:
			x, y = rectangle
			if x < 0 or x >= self.width or y < 0 or y >= self.height:
				return False
		for other_block in self.blocks:
			if other_block != block and block.conflict(other_block):
				return False
		return True

	def add_block(self, block):
		if not self.is_valid(block):
			return False
		self.blocks.append(block)
		return True

	def drop(self, block):
		while True:
			block.y -= 1
			if not self.is_valid(block):
				block.y += 1
				if not block in self.blocks:
					self.blocks.append(block)
				break

	def __str__(self):
		"""
		Returns a string representation of this Board.
		"""
		string = "-" * self.width * 2
		string += "\n"
		for line in reversed(range(0, self.height)):
			string += "|"
			for column in range(0, self.width):
				if not self.blocks:
					string += " "
				else:
					empty = True
					for block in self.blocks:
						if block.uses(column, line):
							string += "#"
							empty = False
							break
					if empty:
						string += " "
				string += "|"
			string += "\n"
			string += "-" * self.width * 2
			string += "\n"
		return string

class Block(object):
	def __init__(self, x, y):
		"""
		Initializes a new Block object.
		"""
		self._x = x
		self._y = y
		self.points = [(x, y)]

	def calc_max(board):
		"""
		Calculates the max amount of this block in the given board.
		"""
		return board.width * board.height

	def uses(self, x, y = 0):
		for rectangle in self.points:
			if rectangle[0] == x and rectangle[1] == y:
				return True
		return False

	def conflict(self, block):
		for rectangle in self.points:
			x, y = rectangle
			if block.uses(x, y):
				return True
		return False

	@property
	def x(self):
		return self._x

	@property
	def y(self):
		return self._y

	@x.setter
	def x(self, x):
		self._x = x
		deltaX = x - self.points[0][0]
		for index, rectangle in enumerate(self.points):
			self.points[index] = (rectangle[0] + deltaX, rectangle[1])

	@y.setter
	def y(self, y):
		self._y = y
		deltaY = y - self.points[0][1]
		for index, rectangle in enumerate(self.points):
			self.points[index] = (rectangle[0], rectangle[1] + deltaY)

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

class TBlock(Block):
	def __init__(self, x, y, direction):
		"""
		Initializes a new TBlock object.
		"""
		Block.__init__(self, x, y)
		self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y + 1)]
		self.direction = direction

	@property
	def direction(self):
		return self._direction

	@direction.setter
	def direction(self, direction):
		self._direction = direction
		x, y = self.points[0]
		if direction == 1:
			self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y + 1)]
		elif direction == 2:
			self.points = [(x, y), (x, y + 1), (x, y + 2), (x + 1, y + 1)]
		elif direction == 3:
			self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y - 1)]
		elif direction == 4:
			self.points = [(x, y), (x + 1, y + 1), (x + 1, y - 1), (x + 1, y)]

def a():
	input = open('in.txt')
	width = int(input.readline())
	height = int(input.readline()) + 1
	board = Board(width, height + 5)

	for line in input:
		x = ord(line[0].lower()) - 97
		direction = int(line[1])
		block = TBlock(x, height, direction)
		if not board.add_block(block):
			continue
		while True:
			block.y -= 1
			if not board.is_valid(block):
				block.y += 1
				break
	output = open('out.txt', "w")
	for block in board.blocks:
		output.write("{0}\n".format(block.y + 1))

def calc_max(width, height):
	"""
	Calculates the maximum amount of this block in the given board.
	"""
	if width < 2 or height < 2:
		return 0
	elif width * height < 10:
		return 1
	elif width  % 4 == height % 4 == 0:
		return int(width * height / 4)
	elif width  % 4 == height % 4 == 2 or width % 4 == 0 or height % 4 == 0:
		return int((width * height - 4) / 4)
	elif width % 4 == 0 and height % 4 == 2:
		return int((width * height - (height % 4 + 2)) / 4)
	elif width % 4 == 2 and height % 4 == 0:
		return int((width * height - (width % 4 + 2)) / 4)
	elif width == 3 and height != 3:
		if height % 3 == 0:
			return int((width * height - (height / 3 + 1)) / 4) + 1
		elif height % 3 == 1:
			return int((width * height - (((height + 2) / 3) + 1)) / 4)
		elif height % 3 == 2:
			return int((width * height - (((height + 1) / 3) + 1)) / 4)
	elif height == 3 and width != 3:
		if width % 3 == 0:
			return int((width * height - (width / 3 + 1)) / 4) + 1
		elif width % 3 == 1:
			return int((width * height - (((width + 2) / 3) + 1)) / 4)
		elif width % 3 == 2:
			return int((width * height - (((width + 1) / 3) + 1)) / 4)
	elif width == 5 or height == 5:
		if width * height % 2 == 0 and width * height % 4 != 0:
			return int((width * height - 2) / 4)
		elif width * height % 3 == 0:
			return int((width * height - 3) / 4)
		elif width * height % 4 == 0:
			return int((width * height - 4) / 4)
		elif width * height % 5 == 0:
			return int((width * height - 5) / 4)
	elif width == 6 and height != 6:
		if height % 6 == 0:
			return int((width * height - 4) / 4)
		elif height % 3 == 0:
			return int((width * height - 2) / 4)
		elif (height + 1) % 6 == 0:
			return int((width * height - 6) / 4)
		elif (height + 1) % 3 == 0:
			return int((width * height - 4)	/ 4)
	elif height == 6 and width != 6:
		if width % 6 == 0:
			return int((width * height - 4) / 4)
		elif width % 3 == 0:
			return int((width * height - 2) / 4)
		elif (width + 1) % 6 == 0:
			return int((width * height - 6) / 4)
		elif (width + 1) % 3 == 0:
			return int((width * height - 4) / 4)
	elif width == 7 and height != 7:
		if height % 4 == 0:
			return int((width * height - 4) / 4)
		elif height % 4 == 1:
			return int((width * height - 3) / 4)
		elif height % 4 == 2:
			return int((width * height - 2) / 4)
		elif height % 4 == 3:
			return int((width * height - 5) / 4)
	elif height == 7 and width != 7:
		if width % 4 == 0:
			return int((width * height - 4) / 4)
		elif width % 4 == 1:
			return int((width * height - 3) / 4)
		elif width % 4 == 2:
			return int((width * height - 2) / 4)
		elif width % 4 == 3:
			return int((width * height - 5) / 4)

def b():
	width = int(input())
	height = int(input())
	print(calc_max(width, height))

if __name__ == "__main__":
	if len(sys.argv) > 1 and sys.argv[1] == "b":
		b()
	else:
		a()
<commit_msg>Update calculation in calc_max<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

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

import sys

# This module contains an implementation of a Tetris-like game called T-Drop.

# Example of the usage of this module:
#
#	import tdrop
#	# create board
#	board = tdrop.Board(6, 9) # width, length
#	# create a block.
#	block = tdrop.TBlock(1, 1, 1) # x, y, direction
#	board.drop(tdrop)
#

# This module is made as a solution to problem 2 of the Dutch
# Olympiad in Informatics.
#
# See http://www.informaticaolympiade.nl for more information.

class Board(object):
	"""
	The Board class represents a grid which contains blocks.
	"""
	def __init__(self, width = 6, length = 9):
		"""
		Initializes a new Board instance.

		Keyword arguments:
		width -- the width of the grid (default = 6)
		length -- the length of the grid (default = 9)
		"""
		self.width = width
		self.length = length
		self.blocks = []

	def is_valid(self, block):
		for rectangle in block.points:
			x, y = rectangle
			if x < 0 or x >= self.width or y < 0 or y >= self.length:
				return False
		for other_block in self.blocks:
			if other_block != block and block.conflict(other_block):
				return False
		return True

	def add_block(self, block):
		if not self.is_valid(block):
			return False
		self.blocks.append(block)
		return True

	def drop(self, block):
		while True:
			block.y -= 1
			if not self.is_valid(block):
				block.y += 1
				if not block in self.blocks:
					self.blocks.append(block)
				break

	def __str__(self):
		"""
		Returns a string representation of this Board.
		"""
		string = "-" * self.width * 2
		string += "\n"
		for line in reversed(range(0, self.length)):
			string += "|"
			for column in range(0, self.width):
				if not self.blocks:
					string += " "
				else:
					empty = True
					for block in self.blocks:
						if block.uses(column, line):
							string += "#"
							empty = False
							break
					if empty:
						string += " "
				string += "|"
			string += "\n"
			string += "-" * self.width * 2
			string += "\n"
		return string

class Block(object):
	def __init__(self, x, y):
		"""
		Initializes a new Block object.
		"""
		self._x = x
		self._y = y
		self.points = [(x, y)]

	def calc_max(board):
		"""
		Calculates the max amount of this block in the given board.
		"""
		return board.width * board.length

	def uses(self, x, y = 0):
		for rectangle in self.points:
			if rectangle[0] == x and rectangle[1] == y:
				return True
		return False

	def conflict(self, block):
		for rectangle in self.points:
			x, y = rectangle
			if block.uses(x, y):
				return True
		return False

	@property
	def x(self):
		return self._x

	@property
	def y(self):
		return self._y

	@x.setter
	def x(self, x):
		self._x = x
		deltaX = x - self.points[0][0]
		for index, rectangle in enumerate(self.points):
			self.points[index] = (rectangle[0] + deltaX, rectangle[1])

	@y.setter
	def y(self, y):
		self._y = y
		deltaY = y - self.points[0][1]
		for index, rectangle in enumerate(self.points):
			self.points[index] = (rectangle[0], rectangle[1] + deltaY)

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

class TBlock(Block):
	def __init__(self, x, y, direction):
		"""
		Initializes a new TBlock object.
		"""
		Block.__init__(self, x, y)
		self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y + 1)]
		self.direction = direction

	@property
	def direction(self):
		return self._direction

	@direction.setter
	def direction(self, direction):
		self._direction = direction
		x, y = self.points[0]
		if direction == 1:
			self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y + 1)]
		elif direction == 2:
			self.points = [(x, y), (x, y + 1), (x, y + 2), (x + 1, y + 1)]
		elif direction == 3:
			self.points = [(x, y), (x + 1, y), (x + 2, y), (x + 1, y - 1)]
		elif direction == 4:
			self.points = [(x, y), (x + 1, y + 1), (x + 1, y - 1), (x + 1, y)]

def a():
	input = open('in.txt')
	width = int(input.readline())
	length = int(input.readline()) + 1
	board = Board(width, length + 5)

	for line in input:
		x = ord(line[0].lower()) - 97
		direction = int(line[1])
		block = TBlock(x, length, direction)
		if not board.add_block(block):
			continue
		while True:
			block.y -= 1
			if not board.is_valid(block):
				block.y += 1
				break
	output = open('out.txt', "w")
	for block in board.blocks:
		output.write("{0}\n".format(block.y + 1))

def calc_max(length, width):
	"""
	Calculates the maximum amount of T-shaped objects in a rectangle of the
	  given size.

	Keyword arguments:
	length -- the length of the rectangle.
	width -- the width of the rectangle.

	Returns the maximum amount of T-shaped objects in a rectangle of the given
	  size.
	"""
	surface = length * width
	if length < 2 or width < 2:
		return 0
	elif surface < 10:
		return 1
	elif length  % 4 == width % 4 == 0:
		return int(surface / 4)
	elif length  % 4 == width % 4 == 2 or length % 4 == 0 or width % 4 == 0:
		return int((surface - 4) / 4)
	elif length % 4 == 0 and width  % 4 == 2:
		return int((surface - (length % 4 + 2)) / 4)
	elif length % 4 == 2 and width % 4 == 0:
		return int((surface - (width % 4 + 2)) / 4)
	elif length == 3 or width == 3:
		return length == 3 and calc_max_three(width) or calc_max_three(length)
	elif length == 5 or width == 3:
		return length == 5 and calc_max_five(width) or calc_max_five(length)
	elif length == 6 or width == 6:
		return length == 6 and calc_max_six(width) or calc_max_six(length)
	elif length == 7 or width == 7:
		return length == 7 and calc_max_seven(width) or calc_max_seven(length)

def calc_max_three(length):
	"""
	Assumes that the width equals three and calculates the maximum amount of
	  T-shaped objects in a rectangle with size __3x__.

	Keyword arguments:
	length -- the length of the rectangle.

	Returns the maximum amount of T-shaped objects in a rectangle with the
	  size __3x__
	"""
	surface = 3 * length
	if length == 3:
		return 1
	elif length % 3 == 0:
		return int((surface - (l / 3 + 1)) / 4) + 1
	elif length % 3 == 1:
		return int((surface - (((length + 2) / 3) + 1)) / 4)
	elif length % 3 == 2:
		return int((surface - (((l + 1) / 3) + 1)) / 4)

def calc_max_five(length):
	"""
	Assumes that the width equals five and calculates the maximum amount of
	  T-shaped objects in a rectangle with size __5x__.

	Keyword arguments:
	length -- the length of the rectangle

	Returns the maximum amount of T-shaped objects in a rectangle with the
	  size __5x__
	"""
	surface = 5 * length
	if surface % 2 == 0 != surface:
		return int((surface - 2) / 4)
	elif surface % 3 == 0:
		return int((surface - 3) / 4)
	elif surface % 4 == 0:
		return int((surface - 4) / 4)
	elif surface % 5 == 0:
		return int((surface - 5) / 4)

def calc_max_six(length):
	"""
	Assumes that the width equals six and calculates the maximum amount of
	  T-shaped objects in a rectangle with size __6x__.

	Keyword arguments:
	l -- the length of the rectangle

	Returns the maximum amount of T-shaped objects in a rectangle with the
	  size __6x__
	"""
	surface = 6 * length
	if length % 6 == 0:
		return int((surface - 4) / 4)
	elif length % 3 == 0:
		return int((surface - 2) / 4)
	elif (length + 1) % 6 == 0:
		return int((surface - 6) / 4)
	elif (length + 1) % 3 == 0:
		return int((surface - 4) / 4)

def calc_max_seven(length):
	"""
	Assumes that the width equals seven and calculates the maximum amount of
	  T-shaped objects in a rectangle with size __7x__.

	Keyword arguments:
	length -- the length of the rectangle

	Returns the maximum amount of T-shaped objects in a rectangle with the
	  size __7x__
	"""
	surface = 7 * length
	if length % 4 == 0:
		return int((surface - 4) / 4)
	elif length % 4 == 1:
		return int((surface - 3) / 4)
	elif length % 4 == 2:
		return int((surface - 2) / 4)
	elif length % 4 == 3:
		return int((surface - 5) / 4)

if __name__ == "__main__":
	if len(sys.argv) <= 1:
		a()
	elif sys.argv[1] == "b":
		width = int(input())
		length = int(input())
		print(calc_max(length, width))
<|endoftext|>


<commit_before># Python 2/3 compatibility
# pylint: disable=wildcard-import,unused-wildcard-import,wrong-import-order,wrong-import-position,no-name-in-module,import-error
from __future__ import (absolute_import, division, print_function, unicode_literals)
from future.builtins.disabled import *
from future.builtins import *
from future.standard_library import install_aliases
install_aliases()
# pylint: enable=wildcard-import,unused-wildcard-import,wrong-import-order,wrong-import-position,no-name-in-module,import-error

# Standard lib imports
import os
import sys

# Third-party imports
import pytest

# Local imports
import arcpyext
from arcpyext.exceptions.serv_def_draft_create_error import ServDefDraftCreateError
from arcpyext.publishing._publishing import check_analysis

PROJECT_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.aprx".format(os.path.dirname(__file__)))
MXD_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.mxd".format(os.path.dirname(__file__)))
DRAFT_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.sddraft".format(os.path.dirname(__file__)))

def test_convert_map_to_sddraft():
    if sys.version_info.major > 2:
        mapservice = arcpyext.publishing.convert_map_to_service_draft(
            PROJECT_PATH,
            DRAFT_PATH,
            'Test',
            'Test',
            copy_data_to_server=False,
            portal_folder=None)
    else:
        mapservice = arcpyext.publishing.convert_map_to_service_draft(MXD_PATH,
                                                                      DRAFT_PATH,
                                                                      'Test',
                                                                      'Test',
                                                                      copy_data_to_server=False)

    assert os.path.exists(mapservice)

def test_check_analysis():
    # This is a py2 only function. Skip if 3
    if sys.version_info.major <= 2:
        with pytest.raises(ServDefDraftCreateError):
            arcpyext.publishing._publishing.check_analysis({"messages": None,
                                            "warnings": None,
                                            "errors": {('Some message', 999): None}})

def test_convert_sddraft_to_sd():
    if sys.version_info.major > 2:
        # Create an sddraft
        mapservice = arcpyext.publishing.convert_map_to_service_draft(
            PROJECT_PATH,
            DRAFT_PATH,
            'Test',
            'Test',
            copy_data_to_server=False,
            portal_folder=None)
        # Convert to staged service
        arcpyext.publishing.convert_service_draft_to_staged_service(mapservice, DRAFT_PATH.replace('.sddraft', '.sd'))
        assert os.path.exists(DRAFT_PATH.replace('.sddraft', '.sd'))

    else:
        # Create sddraft
        mapservice = arcpyext.publishing.convert_map_to_service_draft(MXD_PATH,
                                                                      DRAFT_PATH,
                                                                      'Test',
                                                                      'Test',
                                                                      copy_data_to_server=False)
        # Convert to stages service
        arcpyext.publishing.convert_service_draft_to_staged_service(mapservice, DRAFT_PATH.replace('.sddraft', '.sd'))
        assert os.path.exists(DRAFT_PATH.replace('.sddraft', '.sd'))<commit_msg>Removed test that covers a removed function<commit_after># Python 2/3 compatibility
# pylint: disable=wildcard-import,unused-wildcard-import,wrong-import-order,wrong-import-position,no-name-in-module,import-error
from __future__ import (absolute_import, division, print_function, unicode_literals)
from future.builtins.disabled import *
from future.builtins import *
from future.standard_library import install_aliases
install_aliases()
# pylint: enable=wildcard-import,unused-wildcard-import,wrong-import-order,wrong-import-position,no-name-in-module,import-error

# Standard lib imports
import os
import sys

# Third-party imports
import pytest

# Local imports
import arcpyext
from arcpyext.exceptions.serv_def_draft_create_error import ServDefDraftCreateError
from arcpyext.publishing._publishing import check_analysis

PROJECT_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.aprx".format(os.path.dirname(__file__)))
MXD_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.mxd".format(os.path.dirname(__file__)))
DRAFT_PATH = os.path.abspath("{0}/../samples/test_mapping_complex.sddraft".format(os.path.dirname(__file__)))

def test_convert_map_to_sddraft():
    if sys.version_info.major > 2:
        mapservice = arcpyext.publishing.convert_map_to_service_draft(
            PROJECT_PATH,
            DRAFT_PATH,
            'Test',
            'Test',
            copy_data_to_server=False,
            portal_folder=None)
    else:
        mapservice = arcpyext.publishing.convert_map_to_service_draft(MXD_PATH,
                                                                      DRAFT_PATH,
                                                                      'Test',
                                                                      'Test',
                                                                      copy_data_to_server=False)

    assert os.path.exists(mapservice)

def test_check_analysis():
    # This is a py2 only function. Skip if 3
    if sys.version_info.major <= 2:
        with pytest.raises(ServDefDraftCreateError):
            arcpyext.publishing._publishing.check_analysis({"messages": None,
                                            "warnings": None,
                                            "errors": {('Some message', 999): None}})
<|endoftext|>


<commit_before>'''
'''
__title__ = 'olypy'
__version__ = '0.9.9'
__build__ = 0x010000
__author__ = 'Greg Lindahl and others'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2017 Greg Lindahl and others'
<commit_msg>find the lib stuff<commit_after>'''
'''
import os.path

__title__ = 'olypy'
__version__ = '0.9.9'
__build__ = 0x010000
__author__ = 'Greg Lindahl and others'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2016-2017 Greg Lindahl and others'

def get_mapgen_lib():
    head, tail = os.path.split(__file__)
    return os.path.join(head, 'mapgen-lib')

def get_template_lib():
    head, tail = os.path.split(__file__)
    return os.path.join(head, 'template-lib')
<|endoftext|>