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

import collections
import inflection

from ._util import oagprop

from openarc.exception import *

class CacheProxy(object):
    """Responsible for manipulation of relational data frame"""
    def __init__(self, oag):
        self._oag = oag

        # Cache storage object.
        self._oagcache ={}

    def clear(self):
        self._oagcache = {}

    def clone(self, src):
        self._oagcache   = list(src.oagache._oagcache)

    def invalidate(self, invstream):
        # - filter out all non-dbstream items: calcs can no longer be trusted as node as been invalidated
        tmpoagcache = {oag:self._oagcache[oag] for oag in self._oagcache if oag in self._oag.streams.keys()}
        # - filter out invalidated downstream node
        tmpoagcache = {oag:tmpoagcache[oag] for oag in tmpoagcache if oag != invstream}

        self._oagcache = tmpoagcache

    def match(self, stream):
        return self._oagcache[stream]

    def put(self, stream, new_value):
        self._oagcache[stream] = new_value

    @property
    def state(self):

        return self._oagcache

class RdfProxy(object):
    """Responsible for manipulation of relational data frame"""
    def __init__(self, oag):
        self._oag = oag

        # All data. Currently can only be set from database.
        self._rdf = None

        # An array of lambdas sequentially used to filter the rdf
        self._rdf_filter_cache = []

        # If this is a slice, it can be used to further filter the rdf
        self._rdf_window_index = 0

        # After
        self._rdf_window = None

    def clone(self, src):
        self._rdf        = list(src.rdf._rdf)
        self._rdf_window = list(src.rdf._rdf_window)
        self._rdf_window_index =\
                                src.rdf._rdf_window_index
        # self._rdf_filter_cache =\
        #                         list(src.rdf._rdf_filter_cache)

    def filter(self, predicate, rerun=False):
        if self._oag.is_unique:
            raise OAError("Cannot filter OAG that is marked unique")

        self._oag.cache.clear()

        self._rdf_window = self._rdf

        if rerun is False:
            self._rdf_filter_cache.append(predicate)

        self._rdf_window = []
        for i, frame in enumerate(self._rdf):
            self._oag.propmgr._cframe = frame
            self._oag.propmgr._set_attrs_from_cframe()
            if predicate(self._oag):
                self._rdf_window.append(self._rdf[i])

        if len(self._rdf_window)>0:
            self._oag.propmgr._cframe = self._rdf_window[0]
        else:
            self._rdf_window = []
            self._oag.propmgr._cframe = {}

        self._oag.propmgr._set_attrs_from_cframe()

        return self._oag

    def reset(self):

        # Clear RDF
        self._rdf = None
        self._rdf_filter_cache = []
        self._rdf_window_index = 0
        self._rdf_window = None

        # Clear RDF cache
        self._oag.cache.clear()

        # Clear cframe
        self._oag.propmgr._cframe = {}

        return self._oag

    def sort(self, key):

        self._rdf.sort(key=lambda x: x[key])
        self._rdf_window = self._rdf
        self._rdf_window_index = None
        self._oag.propmgr._cframe = {}

        return self._oag

class PropProxy(object):
    """Manipulates properties"""
    def __init__(self, oag):

        # OAG whose properties are being managed
        self._oag           = oag

        # Mutuable pointer to a row in OAG's RDF
        self._cframe        = {}

        # Used to store properties for __getattribute__ calls
        self._oagprops      = {}

    def add(self, stream, oagprop, fk=False):
        if fk or self.is_managed_oagprop(stream):
            self._oagprops[stream] = oagprop
        else:
            raise OAGraphIntegrityError("This [%s] is not a managed oagprop" % stream)

    def clear(self):
        for stream in self._oagprops:
            self._oagprops[stream] = None

    def clone(self, src):
        self._cframe = dict(src.propmgr._cframe)

    def get(self, stream):
        try:
            if self.is_managed_oagprop(stream):
                # Set default value on class
                try:
                    attr = object.__getattribute__(self._oag, stream)
                except AttributeError:
                    setattr(self._oag.__class__, stream, None)

                # Return it
                if type(self._oagprops[stream])==oagprop:
                    return self._oagprops[stream].__get__(self._oag)
                else:
                    return self._oagprops[stream]
            else:
                raise AttributeError("This attribute is not managed by the propmanager")
        except KeyError as e:
            raise AttributeError("Cannot find attribute [%s] in propmanager" % stream)

    def is_managed_oagprop(self, stream):
        """Takes requested attribute and returns True or false"""
        allowed_streams = list(set(
            [object.__getattribute__(self._oag, 'dbpkname')] +\
            list(object.__getattribute__(self._oag, 'streams').keys()) +\
            list(self._oagprops.keys())
        ))
        return stream in allowed_streams

    def _set_attrs_from_cframe(self):
        from .graph import OAG_RootNode

        # Blank everything if _cframe isn't set
        if len(self._cframe)==0:
            self.clear()
            return

        # Set dbstream attributes
        for stream, streaminfo in self._cframe.items():
            self._set_oagprop(stream, streaminfo)

        # Set forward lookup attributes
        for fk in self._oag.__class__._fkframe:
            classname = "OAG_"+inflection.camelize(fk['table'])
            for cls in OAG_RootNode.__subclasses__():
                if cls.__name__==classname:
                    stream = fk['table']
                    def fget(obj,
                             cls=cls,
                             searchprms=[getattr(self._oag, fk['points_to_id'], None)],
                             searchidx='by_'+{cls.stream_db_mapping[k]:k for k in cls.stream_db_mapping}[fk['id']],
                             logger=self._oag.logger):
                        return cls(searchprms, searchidx, logger=self._oag.logger)
                    fget.__name__ = stream
                    self.add(stream, oagprop(fget), fk=True)

    def _set_attrs_from_cframe_uniq(self):
        if len(self._oag.rdf._rdf_window) > 1:
            raise OAGraphIntegrityError("Graph object indicated unique, but returns more than one row from database")

        if len(self._oag.rdf._rdf_window) == 1:
            self._cframe = self._oag.rdf._rdf_window[0]
        else:
            self._cframe = []

        self._set_attrs_from_cframe()

    def _set_cframe_from_userprms(self, userprms, force_attr_refresh=False, fullhouse=False):

        setattrs = []

        attrinit = len(userprms)>0 or force_attr_refresh

        if attrinit:

            invalid_streams = []
            processed_streams = {}

            for oagkey in self._oag.streams:
                setattr(self._oag, oagkey, None)

            if len(userprms)>0:
                invalid_streams = [ s for s in userprms if s not in self._oag.streams.keys() ]
                if len(invalid_streams)>0:
                    raise OAGraphIntegrityError("Invalid update stream(s) detected %s" % invalid_streams)

                processed_streams = { s:userprms[s] for s in userprms if s not in invalid_streams }
                for stream, streaminfo in processed_streams.items():
                    setattr(self._oag, stream, streaminfo)
                    self._set_oagprop(stream, streaminfo, cframe_form=False)
                setattrs = processed_streams.keys()

        self._set_cframe_from_attrs(setattrs, fullhouse=fullhouse)

    def _set_cframe_from_attrs(self, attrs, fullhouse=False):
        cframe_tmp = {}
        raw_missing_streams = []

        all_streams = list(self._oag.streams.keys())
        if len(self._cframe) > 0:
            all_streams.append(self._oag.dbpkname)

        for oagkey in all_streams:

            # Special handling for indices
            if oagkey[0] == '_':
                cframe_tmp[oagkey] = getattr(self._oag, oagkey, None)
                continue

            cfkey = oagkey
            if self._oag.is_oagnode(oagkey):
                cfkey = self._oag.stream_db_mapping[oagkey]
            cfval = getattr(self._oag, oagkey, None)

            # Special handling for nullable items
            if type(self._oag.streams[oagkey][0])!=str\
                and self._oag.streams[oagkey][1] is False:
                cframe_tmp[cfkey] = cfval.id if cfval else None
                continue

            # Is a value missing for this stream?
            if cfval is None:
                raw_missing_streams.append(oagkey)
                continue

            # Ok, actualy set cframe
            if self._oag.is_oagnode(oagkey):
                # this only works if we're in dbpersist mode
                # if there's a key error, we're working in-memory
                try:
                    cfval = cfval.id
                except KeyError:
                    pass
            cframe_tmp[cfkey] = cfval

        if fullhouse:
            missing_streams = []
            for rms in raw_missing_streams:
                if self._oag.is_oagnode(rms):
                    missing_streams.append(rms)
                else:
                    if self._oag.streams[rms][1] is not None:
                        missing_streams.append(rms)
            if len(missing_streams)>0:
                raise OAGraphIntegrityError("Missing streams detected %s" % missing_streams)

        self._cframe = cframe_tmp

    def _set_oagprop(self, stream, cfval, searchidx='id', cframe_form=True):

        # primary key: set directly
        if stream[0] == '_':
            setattr(self._oag, stream, self._cframe[stream])
            return

        # Normalize stream name to OAG form
        if cframe_form:
            db_stream_mapping = {self._oag.stream_db_mapping[k]:k for k in self._oag.stream_db_mapping}
            stream = db_stream_mapping[stream]

        if self._oag.is_oagnode(stream):

            # oagprop: update cache if necessary
            try:
                currattr = getattr(self._oag, stream, None)
                if currattr is None:
                    if self._oag.streams[stream][1] is False and cfval:
                        currattr = self._oag.streams[stream][0](cfval, searchidx, logger=self._oag.logger)
                        if not currattr.is_unique:
                            currattr = currattr[-1]
            except OAGraphRetrieveError:
                currattr = None

            if currattr:
                self._oag.cache.put(stream, currattr)

            # oagprop: actually set it
            def fget(obj,
                     stream=stream,
                     streaminfo=self._oag.streams[stream],
                     searchprms=[cfval],
                     searchidx=searchidx,
                     logger=self._oag.logger,
                     currattr=currattr):
                # Do not instantiate objects unnecessarily
                if currattr:
                    try:
                        if currattr == searchprms[0]:
                            return currattr
                        if currattr.id == searchprms[0]:
                            return currattr
                    except KeyError:
                        # We're dealing with in-memory OAGs, just return
                        return currattr
                elif streaminfo[1] is False:
                    return currattr
                else:
                    newattr = streaminfo[0](searchprms, searchidx, logger=logger)
                    if not newattr.is_unique:
                        newattr = newattr[-1]
                    return newattr
                newattr = streaminfo[0](searchprms, searchidx, logger=logger)
                return newattr
            fget.__name__ = stream
            self.add(stream, oagprop(fget))
        else:
            setattr(self._oag, stream, cfval)
<commit_msg>Remove blanking of attrs when setting OAG attrs from userprms<commit_after>#!/usr/local/env python3

import collections
import inflection

from ._util import oagprop

from openarc.exception import *

class CacheProxy(object):
    """Responsible for manipulation of relational data frame"""
    def __init__(self, oag):
        self._oag = oag

        # Cache storage object.
        self._oagcache ={}

    def clear(self):
        self._oagcache = {}

    def clone(self, src):
        self._oagcache   = list(src.oagache._oagcache)

    def invalidate(self, invstream):
        # - filter out all non-dbstream items: calcs can no longer be trusted as node as been invalidated
        tmpoagcache = {oag:self._oagcache[oag] for oag in self._oagcache if oag in self._oag.streams.keys()}
        # - filter out invalidated downstream node
        tmpoagcache = {oag:tmpoagcache[oag] for oag in tmpoagcache if oag != invstream}

        self._oagcache = tmpoagcache

    def match(self, stream):
        return self._oagcache[stream]

    def put(self, stream, new_value):
        self._oagcache[stream] = new_value

    @property
    def state(self):

        return self._oagcache

class RdfProxy(object):
    """Responsible for manipulation of relational data frame"""
    def __init__(self, oag):
        self._oag = oag

        # All data. Currently can only be set from database.
        self._rdf = None

        # An array of lambdas sequentially used to filter the rdf
        self._rdf_filter_cache = []

        # If this is a slice, it can be used to further filter the rdf
        self._rdf_window_index = 0

        # After
        self._rdf_window = None

    def clone(self, src):
        self._rdf        = list(src.rdf._rdf)
        self._rdf_window = list(src.rdf._rdf_window)
        self._rdf_window_index =\
                                src.rdf._rdf_window_index
        # self._rdf_filter_cache =\
        #                         list(src.rdf._rdf_filter_cache)

    def filter(self, predicate, rerun=False):
        if self._oag.is_unique:
            raise OAError("Cannot filter OAG that is marked unique")

        self._oag.cache.clear()

        self._rdf_window = self._rdf

        if rerun is False:
            self._rdf_filter_cache.append(predicate)

        self._rdf_window = []
        for i, frame in enumerate(self._rdf):
            self._oag.propmgr._cframe = frame
            self._oag.propmgr._set_attrs_from_cframe()
            if predicate(self._oag):
                self._rdf_window.append(self._rdf[i])

        if len(self._rdf_window)>0:
            self._oag.propmgr._cframe = self._rdf_window[0]
        else:
            self._rdf_window = []
            self._oag.propmgr._cframe = {}

        self._oag.propmgr._set_attrs_from_cframe()

        return self._oag

    def reset(self):

        # Clear RDF
        self._rdf = None
        self._rdf_filter_cache = []
        self._rdf_window_index = 0
        self._rdf_window = None

        # Clear RDF cache
        self._oag.cache.clear()

        # Clear cframe
        self._oag.propmgr._cframe = {}

        return self._oag

    def sort(self, key):

        self._rdf.sort(key=lambda x: x[key])
        self._rdf_window = self._rdf
        self._rdf_window_index = None
        self._oag.propmgr._cframe = {}

        return self._oag

class PropProxy(object):
    """Manipulates properties"""
    def __init__(self, oag):

        # OAG whose properties are being managed
        self._oag           = oag

        # Mutuable pointer to a row in OAG's RDF
        self._cframe        = {}

        # Used to store properties for __getattribute__ calls
        self._oagprops      = {}

    def add(self, stream, oagprop, fk=False):
        if fk or self.is_managed_oagprop(stream):
            self._oagprops[stream] = oagprop
        else:
            raise OAGraphIntegrityError("This [%s] is not a managed oagprop" % stream)

    def clear(self):
        for stream in self._oagprops:
            self._oagprops[stream] = None

    def clone(self, src):
        self._cframe = dict(src.propmgr._cframe)

    def get(self, stream):
        try:
            if self.is_managed_oagprop(stream):
                # Set default value on class
                try:
                    attr = object.__getattribute__(self._oag, stream)
                except AttributeError:
                    setattr(self._oag.__class__, stream, None)

                # Return it
                if type(self._oagprops[stream])==oagprop:
                    return self._oagprops[stream].__get__(self._oag)
                else:
                    return self._oagprops[stream]
            else:
                raise AttributeError("This attribute is not managed by the propmanager")
        except KeyError as e:
            raise AttributeError("Cannot find attribute [%s] in propmanager" % stream)

    def is_managed_oagprop(self, stream):
        """Takes requested attribute and returns True or false"""
        allowed_streams = list(set(
            [object.__getattribute__(self._oag, 'dbpkname')] +\
            list(object.__getattribute__(self._oag, 'streams').keys()) +\
            list(self._oagprops.keys())
        ))
        return stream in allowed_streams

    def _set_attrs_from_cframe(self):
        from .graph import OAG_RootNode

        # Blank everything if _cframe isn't set
        if len(self._cframe)==0:
            self.clear()
            return

        # Set dbstream attributes
        for stream, streaminfo in self._cframe.items():
            self._set_oagprop(stream, streaminfo)

        # Set forward lookup attributes
        for fk in self._oag.__class__._fkframe:
            classname = "OAG_"+inflection.camelize(fk['table'])
            for cls in OAG_RootNode.__subclasses__():
                if cls.__name__==classname:
                    stream = fk['table']
                    def fget(obj,
                             cls=cls,
                             searchprms=[getattr(self._oag, fk['points_to_id'], None)],
                             searchidx='by_'+{cls.stream_db_mapping[k]:k for k in cls.stream_db_mapping}[fk['id']],
                             logger=self._oag.logger):
                        return cls(searchprms, searchidx, logger=self._oag.logger)
                    fget.__name__ = stream
                    self.add(stream, oagprop(fget), fk=True)

    def _set_attrs_from_cframe_uniq(self):
        if len(self._oag.rdf._rdf_window) > 1:
            raise OAGraphIntegrityError("Graph object indicated unique, but returns more than one row from database")

        if len(self._oag.rdf._rdf_window) == 1:
            self._cframe = self._oag.rdf._rdf_window[0]
        else:
            self._cframe = []

        self._set_attrs_from_cframe()

    def _set_cframe_from_userprms(self, userprms, force_attr_refresh=False, fullhouse=False):

        setattrs = []

        attrinit = len(userprms)>0 or force_attr_refresh

        if attrinit:

            invalid_streams = []
            processed_streams = {}

            if len(userprms)>0:
                invalid_streams = [ s for s in userprms if s not in self._oag.streams.keys() ]
                if len(invalid_streams)>0:
                    raise OAGraphIntegrityError("Invalid update stream(s) detected %s" % invalid_streams)

                processed_streams = { s:userprms[s] for s in userprms if s not in invalid_streams }
                for stream, streaminfo in processed_streams.items():
                    setattr(self._oag, stream, streaminfo)
                    self._set_oagprop(stream, streaminfo, cframe_form=False)
                setattrs = processed_streams.keys()

        self._set_cframe_from_attrs(setattrs, fullhouse=fullhouse)

    def _set_cframe_from_attrs(self, attrs, fullhouse=False):
        cframe_tmp = {}
        raw_missing_streams = []

        all_streams = list(self._oag.streams.keys())
        if len(self._cframe) > 0:
            all_streams.append(self._oag.dbpkname)

        for oagkey in all_streams:

            # Special handling for indices
            if oagkey[0] == '_':
                cframe_tmp[oagkey] = getattr(self._oag, oagkey, None)
                continue

            cfkey = oagkey
            if self._oag.is_oagnode(oagkey):
                cfkey = self._oag.stream_db_mapping[oagkey]
            cfval = getattr(self._oag, oagkey, None)

            # Special handling for nullable items
            if type(self._oag.streams[oagkey][0])!=str\
                and self._oag.streams[oagkey][1] is False:
                cframe_tmp[cfkey] = cfval.id if cfval else None
                continue

            # Is a value missing for this stream?
            if cfval is None:
                raw_missing_streams.append(oagkey)
                continue

            # Ok, actualy set cframe
            if self._oag.is_oagnode(oagkey):
                # this only works if we're in dbpersist mode
                # if there's a key error, we're working in-memory
                try:
                    cfval = cfval.id
                except KeyError:
                    pass
            cframe_tmp[cfkey] = cfval

        if fullhouse:
            missing_streams = []
            for rms in raw_missing_streams:
                if self._oag.is_oagnode(rms):
                    missing_streams.append(rms)
                else:
                    if self._oag.streams[rms][1] is not None:
                        missing_streams.append(rms)
            if len(missing_streams)>0:
                raise OAGraphIntegrityError("Missing streams detected on [%s]: %s" % (self._oag.dbtable, missing_streams))

        self._cframe = cframe_tmp

    def _set_oagprop(self, stream, cfval, searchidx='id', cframe_form=True):

        # primary key: set directly
        if stream[0] == '_':
            setattr(self._oag, stream, self._cframe[stream])
            return

        # Normalize stream name to OAG form
        if cframe_form:
            db_stream_mapping = {self._oag.stream_db_mapping[k]:k for k in self._oag.stream_db_mapping}
            stream = db_stream_mapping[stream]

        if self._oag.is_oagnode(stream):

            # oagprop: update cache if necessary
            try:
                currattr = getattr(self._oag, stream, None)
                if currattr is None:
                    if self._oag.streams[stream][1] is False and cfval:
                        currattr = self._oag.streams[stream][0](cfval, searchidx, logger=self._oag.logger)
                        if not currattr.is_unique:
                            currattr = currattr[-1]
            except OAGraphRetrieveError:
                currattr = None

            if currattr:
                self._oag.cache.put(stream, currattr)

            # oagprop: actually set it
            def fget(obj,
                     stream=stream,
                     streaminfo=self._oag.streams[stream],
                     searchprms=[cfval],
                     searchidx=searchidx,
                     logger=self._oag.logger,
                     currattr=currattr):
                # Do not instantiate objects unnecessarily
                if currattr:
                    try:
                        if currattr == searchprms[0]:
                            return currattr
                        if currattr.id == searchprms[0]:
                            return currattr
                    except KeyError:
                        # We're dealing with in-memory OAGs, just return
                        return currattr
                elif streaminfo[1] is False:
                    return currattr
                else:
                    newattr = streaminfo[0](searchprms, searchidx, logger=logger)
                    if not newattr.is_unique:
                        newattr = newattr[-1]
                    return newattr
                newattr = streaminfo[0](searchprms, searchidx, logger=logger)
                return newattr
            fget.__name__ = stream
            self.add(stream, oagprop(fget))
        else:
            setattr(self._oag, stream, cfval)
<|endoftext|>


<commit_before>from utils.preprocessing import FileHelper

from collections import defaultdict
import itertools
import logging

class App(object):
    def __init__(self, tag, f, c=0):
        self.set_f(f)
        self.set_c(c)
        self.tag = tag

    def set_f(self, f):
        self.f = f

    def set_c(self, c):
        self.c = c

    def get_printable(self):
        return '{} ({}, {})'.format(self.tag, self.f, self.c)

    def gen_feed(self):
        feed_f = ('f', self.f)
        feed_c = ('c', self.c)
        return [feed_f, feed_c]

class AppHelper(object):
    @staticmethod
    def gen_app(path=None, regress_model=None):
        fs = [.5, .9, .99, .999]
        cs = [.0, .001, .01, .1]
        tag = 'Pathological'
        if path is not None:
            assert(regress_model)
            data, wklds = FileHelper.read_data(path)
        else:
            return [App(tag, f, c) for f, c in itertools.product(fs, cs)]

        if regress_model:
            apps = []
            for k, df in data.groupby('workload'):
                cores = df['thread_count']
                speedup = df['speedup']
                result = regress_model.fit(cores, speedup)
                if 'c' in result:
                    apps.append(App(k, result['f'], result['c']))
                else:
                    apps.append(App(k, result['f'], 0))
            return apps
<commit_msg>fix app<commit_after>from collections import defaultdict
import itertools
import logging

class App(object):
    def __init__(self, tag, f, c=0):
        self.set_f(f)
        self.set_c(c)
        self.tag = tag

    def set_f(self, f):
        self.f = f

    def set_c(self, c):
        self.c = c

    def get_printable(self):
        return '{} ({}, {})'.format(self.tag, self.f, self.c)

    def gen_feed(self):
        feed_f = ('f', self.f)
        feed_c = ('c', self.c)
        return [feed_f, feed_c]
<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
#    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.

# See http://code.google.com/p/python-nose/issues/detail?id=373
# The code below enables nosetests to work with i18n _() blocks
import __builtin__
import unittest
setattr(__builtin__, '_', lambda x: x)

class BaseTest(unittest.TestCase):

    def setUp(self):
        pass

def setUp():
    pass
<commit_msg>remove unneeded __init__<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# Software License Agreement (BSD License)
#
# Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from __future__ import unicode_literals

import os
import io
import unittest
import subprocess
import tempfile
import shutil
import re
from vcstools.svn import SvnClient

class SvnClientTestSetups(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        self.root_directory = tempfile.mkdtemp()
        self.directories = dict(setUp=self.root_directory)
        self.remote_path = os.path.join(self.root_directory, "remote")
        self.init_path = os.path.join(self.root_directory, "init")

        # create a "remote" repo
        subprocess.check_call("svnadmin create %s" % self.remote_path, shell=True, cwd=self.root_directory)
        self.local_root_url = "file://localhost" + self.remote_path
        self.local_url = self.local_root_url + "/trunk"

        # create an "init" repo to populate remote repo
        subprocess.check_call("svn checkout %s %s" % (self.local_root_url, self.init_path), shell=True, cwd=self.root_directory)

        for cmd in [
            "mkdir trunk",
            "mkdir branches",
            "mkdir tags",
            "svn add trunk branches tags",
            "touch trunk/fixed.txt",
            "svn add trunk/fixed.txt",
            "svn commit -m initial"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_version_init = "-r1"

        # files to be modified in "local" repo
        for cmd in [
            "touch trunk/modified.txt",
            "touch trunk/modified-fs.txt",
            "svn add trunk/modified.txt trunk/modified-fs.txt",
            "svn commit -m initial"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_version_second = "-r2"
        for cmd in [
            "touch trunk/deleted.txt",
            "touch trunk/deleted-fs.txt",
            "svn add trunk/deleted.txt trunk/deleted-fs.txt",
            "svn commit -m modified"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_path = os.path.join(self.root_directory, "local")

    @classmethod
    def tearDownClass(self):
        for d in self.directories:
            shutil.rmtree(self.directories[d])

    def tearDown(self):
        if os.path.exists(self.local_path):
            shutil.rmtree(self.local_path)

class SvnClientTest(SvnClientTestSetups):

    def test_get_url_by_reading(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(self.local_url, client.get_url())
        #self.assertEqual(client.get_version(), self.local_version)
        self.assertEqual(client.get_version("PREV"), "-r2")
        self.assertEqual(client.get_version("2"), "-r2")
        self.assertEqual(client.get_version("-r2"), "-r2")
        # test invalid cient and repo without url
        client = SvnClient(os.path.join(self.remote_path, 'foo'))
        self.assertEqual(None, client.get_url())

    def test_get_type_name(self):
        local_path = "/tmp/dummy"
        client = SvnClient(local_path)
        self.assertEqual(client.get_vcs_type_name(), 'svn')

    def test_get_url_nonexistant(self):
        local_path = "/tmp/dummy"
        client = SvnClient(local_path)
        self.assertEqual(client.get_url(), None)

    def test_checkout(self):
        url = self.local_url
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_path(), self.local_path)
        self.assertEqual(client.get_url(), url)

    def test_checkout_emptyversion(self):
        url = self.local_url
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url, version=''))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_path(), self.local_path)
        self.assertEqual(client.get_url(), url)
        self.assertTrue(client.update(None))
        self.assertTrue(client.update(""))

    def test_checkout_specific_version_and_update_short(self):
        "using just a number as version"
        url = self.local_url
        version = "3"
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url, version))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_version(), "-r3")
        new_version = '2'
        self.assertTrue(client.update(new_version))
        self.assertEqual(client.get_version(), "-r2")

    def testDiffClean(self):
        client = SvnClient(self.remote_path)
        self.assertEquals('', client.get_diff())

    def testStatusClean(self):
        client = SvnClient(self.remote_path)
        self.assertEquals('', client.get_status())

class SvnClientLogTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)

    def test_get_log_defaults(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log()
        self.assertEquals(3, len(log))
        self.assertEquals('modified', log[0]['message'])
        for key in ['id', 'author', 'date', 'message']:
            self.assertTrue(log[0][key] is not None, key)
        # svn logs don't have email, but key should be in dict
        self.assertTrue(log[0]['email'] is None)

    def test_get_log_limit(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log(limit=1)
        self.assertEquals(1, len(log))
        self.assertEquals('modified', log[0]['message'])

    def test_get_log_path(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log(relpath='fixed.txt')
        self.assertEquals('initial', log[0]['message'])

class SvnDiffStatClientTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        # after setting up "local" repo, change files and make some changes
        subprocess.check_call("rm deleted-fs.txt", shell=True, cwd=self.local_path)
        subprocess.check_call("svn rm deleted.txt", shell=True, cwd=self.local_path)
        f = io.open(os.path.join(self.local_path, "modified.txt"), 'a')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "modified-fs.txt"), 'a')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "added-fs.txt"), 'w')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "added.txt"), 'w')
        f.write('0123456789abcdef')
        f.close()
        subprocess.check_call("svn add added.txt", shell=True, cwd=self.local_path)

    def tearDown(self):
        pass

    def assertStatusListEqual(self, listexpect, listactual):
          """helper fun to check scm status output while discarding file ordering differences"""
          lines_expect = listexpect.splitlines()
          lines_actual = listactual.splitlines()
          for line in lines_expect:
               self.assertTrue(line in lines_actual, 'Missing entry %s in output %s' % (line, listactual))
          for line in lines_actual:
               self.assertTrue(line in lines_expect, 'Superflous entry %s in output %s' % (line, listactual))

    def assertEqualDiffs(self, expected, actual):
        "True if actual is similar enough to expected, minus svn properties"

        def filter_block(block):
            """removes property information that varies between systems, not relevant fo runit test"""
            newblock = []
            for line in block.splitlines():
                if re.search("[=+-\\@ ].*", line) == None:
                    break
                else:
                    newblock.append(line)
            return "\n".join(newblock)

        filtered_actual_blocks = []
        # A block starts with \nIndex, and the actual diff goes up to the first line starting with [a-zA-Z], e.g. "Properties changed:"
        for block in actual.split("\nIndex: "):
            if filtered_actual_blocks != []:
                # restore "Index: " removed by split()
                block = "Index: " + block
            block = filter_block(block)
            filtered_actual_blocks.append(block)
        expected_blocks = []
        for block in expected.split("\nIndex: "):
            if expected_blocks != []:
                block = "Index: " + block
            expected_blocks.append(block)
        filtered = "\n".join(filtered_actual_blocks)
        self.assertEquals(set(expected_blocks), set(filtered_actual_blocks))

    def test_diff(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())

        self.assertEqualDiffs('Index: added.txt\n===================================================================\n--- added.txt\t(revision 0)\n+++ added.txt\t(revision 0)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: modified-fs.txt\n===================================================================\n--- modified-fs.txt\t(revision 3)\n+++ modified-fs.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: modified.txt\n===================================================================\n--- modified.txt\t(revision 3)\n+++ modified.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file',
                          client.get_diff().rstrip())

    def test_diff_relpath(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())

        self.assertEqualDiffs('Index: local/added.txt\n===================================================================\n--- local/added.txt\t(revision 0)\n+++ local/added.txt\t(revision 0)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: local/modified-fs.txt\n===================================================================\n--- local/modified-fs.txt\t(revision 3)\n+++ local/modified-fs.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: local/modified.txt\n===================================================================\n--- local/modified.txt\t(revision 3)\n+++ local/modified.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file', client.get_diff(basepath=os.path.dirname(self.local_path)).rstrip())

    def test_status(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('A       added.txt\nD       deleted.txt\nM       modified-fs.txt\n!       deleted-fs.txt\nM       modified.txt\n', client.get_status())

    def test_status_relpath(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('A       local/added.txt\nD       local/deleted.txt\nM       local/modified-fs.txt\n!       local/deleted-fs.txt\nM       local/modified.txt\n', client.get_status(basepath=os.path.dirname(self.local_path)))

    def test_status_untracked(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('?       added-fs.txt\nA       added.txt\nD       deleted.txt\nM       modified-fs.txt\n!       deleted-fs.txt\nM       modified.txt\n', client.get_status(untracked=True))

class SvnExportRepositoryClientTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)

        self.basepath_export = os.path.join(self.root_directory, 'export')

    def tearDown(self):
        pass

    def test_export_repository(self):
        client = SvnClient(self.local_path)
        self.assertTrue(
          client.export_repository('',
            self.basepath_export)
        )

        self.assertTrue(os.path.exists(self.basepath_export + '.tar.gz'))
        self.assertFalse(os.path.exists(self.basepath_export + '.tar'))
        self.assertFalse(os.path.exists(self.basepath_export))
<commit_msg>fix svn diff output changed in 1.7<commit_after>#!/usr/bin/env python
# Software License Agreement (BSD License)
#
# Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from __future__ import unicode_literals

import os
import io
import unittest
import subprocess
import tempfile
import shutil
import re
from vcstools.svn import SvnClient

class SvnClientTestSetups(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        self.root_directory = tempfile.mkdtemp()
        self.directories = dict(setUp=self.root_directory)
        self.remote_path = os.path.join(self.root_directory, "remote")
        self.init_path = os.path.join(self.root_directory, "init")

        # create a "remote" repo
        subprocess.check_call("svnadmin create %s" % self.remote_path, shell=True, cwd=self.root_directory)
        self.local_root_url = "file://localhost" + self.remote_path
        self.local_url = self.local_root_url + "/trunk"

        # create an "init" repo to populate remote repo
        subprocess.check_call("svn checkout %s %s" % (self.local_root_url, self.init_path), shell=True, cwd=self.root_directory)

        for cmd in [
            "mkdir trunk",
            "mkdir branches",
            "mkdir tags",
            "svn add trunk branches tags",
            "touch trunk/fixed.txt",
            "svn add trunk/fixed.txt",
            "svn commit -m initial"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_version_init = "-r1"

        # files to be modified in "local" repo
        for cmd in [
            "touch trunk/modified.txt",
            "touch trunk/modified-fs.txt",
            "svn add trunk/modified.txt trunk/modified-fs.txt",
            "svn commit -m initial"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_version_second = "-r2"
        for cmd in [
            "touch trunk/deleted.txt",
            "touch trunk/deleted-fs.txt",
            "svn add trunk/deleted.txt trunk/deleted-fs.txt",
            "svn commit -m modified"]:
            subprocess.check_call(cmd, shell=True, cwd=self.init_path)

        self.local_path = os.path.join(self.root_directory, "local")

    @classmethod
    def tearDownClass(self):
        for d in self.directories:
            shutil.rmtree(self.directories[d])

    def tearDown(self):
        if os.path.exists(self.local_path):
            shutil.rmtree(self.local_path)

class SvnClientTest(SvnClientTestSetups):

    def test_get_url_by_reading(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(self.local_url, client.get_url())
        #self.assertEqual(client.get_version(), self.local_version)
        self.assertEqual(client.get_version("PREV"), "-r2")
        self.assertEqual(client.get_version("2"), "-r2")
        self.assertEqual(client.get_version("-r2"), "-r2")
        # test invalid cient and repo without url
        client = SvnClient(os.path.join(self.remote_path, 'foo'))
        self.assertEqual(None, client.get_url())

    def test_get_type_name(self):
        local_path = "/tmp/dummy"
        client = SvnClient(local_path)
        self.assertEqual(client.get_vcs_type_name(), 'svn')

    def test_get_url_nonexistant(self):
        local_path = "/tmp/dummy"
        client = SvnClient(local_path)
        self.assertEqual(client.get_url(), None)

    def test_checkout(self):
        url = self.local_url
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_path(), self.local_path)
        self.assertEqual(client.get_url(), url)

    def test_checkout_emptyversion(self):
        url = self.local_url
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url, version=''))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_path(), self.local_path)
        self.assertEqual(client.get_url(), url)
        self.assertTrue(client.update(None))
        self.assertTrue(client.update(""))

    def test_checkout_specific_version_and_update_short(self):
        "using just a number as version"
        url = self.local_url
        version = "3"
        client = SvnClient(self.local_path)
        self.assertFalse(client.path_exists())
        self.assertFalse(client.detect_presence())
        self.assertTrue(client.checkout(url, version))
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertEqual(client.get_version(), "-r3")
        new_version = '2'
        self.assertTrue(client.update(new_version))
        self.assertEqual(client.get_version(), "-r2")

    def testDiffClean(self):
        client = SvnClient(self.remote_path)
        self.assertEquals('', client.get_diff())

    def testStatusClean(self):
        client = SvnClient(self.remote_path)
        self.assertEquals('', client.get_status())

class SvnClientLogTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)

    def test_get_log_defaults(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log()
        self.assertEquals(3, len(log))
        self.assertEquals('modified', log[0]['message'])
        for key in ['id', 'author', 'date', 'message']:
            self.assertTrue(log[0][key] is not None, key)
        # svn logs don't have email, but key should be in dict
        self.assertTrue(log[0]['email'] is None)

    def test_get_log_limit(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log(limit=1)
        self.assertEquals(1, len(log))
        self.assertEquals('modified', log[0]['message'])

    def test_get_log_path(self):
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        log = client.get_log(relpath='fixed.txt')
        self.assertEquals('initial', log[0]['message'])

class SvnDiffStatClientTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)
        # after setting up "local" repo, change files and make some changes
        subprocess.check_call("rm deleted-fs.txt", shell=True, cwd=self.local_path)
        subprocess.check_call("svn rm deleted.txt", shell=True, cwd=self.local_path)
        f = io.open(os.path.join(self.local_path, "modified.txt"), 'a')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "modified-fs.txt"), 'a')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "added-fs.txt"), 'w')
        f.write('0123456789abcdef')
        f.close()
        f = io.open(os.path.join(self.local_path, "added.txt"), 'w')
        f.write('0123456789abcdef')
        f.close()
        subprocess.check_call("svn add added.txt", shell=True, cwd=self.local_path)

    def tearDown(self):
        pass

    def assertStatusListEqual(self, listexpect, listactual):
          """helper fun to check scm status output while discarding file ordering differences"""
          lines_expect = listexpect.splitlines()
          lines_actual = listactual.splitlines()
          for line in lines_expect:
               self.assertTrue(line in lines_actual, 'Missing entry %s in output %s' % (line, listactual))
          for line in lines_actual:
               self.assertTrue(line in lines_expect, 'Superflous entry %s in output %s' % (line, listactual))

    def assertEqualDiffs(self, expected, actual):
        "True if actual is similar enough to expected, minus svn properties"

        def filter_block(block):
            """removes property information that varies between systems, not relevant fo runit test"""
            newblock = []
            for line in block.splitlines():
                if re.search("[=+-\\@ ].*", line) == None:
                    break
                else:
                    # new svn versions use different labels for added
                    # files (working copy) vs (revision x)
                    fixedline = re.sub('\(revision [0-9]+\)', '(working copy)', line)
                    newblock.append(fixedline)
            return "\n".join(newblock)

        filtered_actual_blocks = []
        # A block starts with \nIndex, and the actual diff goes up to the first line starting with [a-zA-Z], e.g. "Properties changed:"
        for block in actual.split("\nIndex: "):
            if filtered_actual_blocks != []:
                # restore "Index: " removed by split()
                block = "Index: " + block
            block = filter_block(block)
            filtered_actual_blocks.append(block)
        expected_blocks = []
        for block in expected.split("\nIndex: "):
            if expected_blocks != []:
                block = "Index: " + block
            block = filter_block(block)
            expected_blocks.append(block)
        filtered = "\n".join(filtered_actual_blocks)
        self.assertEquals(set(expected_blocks), set(filtered_actual_blocks))

    def test_diff(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())

        self.assertEqualDiffs('Index: added.txt\n===================================================================\n--- added.txt\t(revision 0)\n+++ added.txt\t(revision 0)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: modified-fs.txt\n===================================================================\n--- modified-fs.txt\t(revision 3)\n+++ modified-fs.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: modified.txt\n===================================================================\n--- modified.txt\t(revision 3)\n+++ modified.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file',
                          client.get_diff().rstrip())

    def test_diff_relpath(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())

        self.assertEqualDiffs('Index: local/added.txt\n===================================================================\n--- local/added.txt\t(revision 0)\n+++ local/added.txt\t(revision 0)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: local/modified-fs.txt\n===================================================================\n--- local/modified-fs.txt\t(revision 3)\n+++ local/modified-fs.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file\nIndex: local/modified.txt\n===================================================================\n--- local/modified.txt\t(revision 3)\n+++ local/modified.txt\t(working copy)\n@@ -0,0 +1 @@\n+0123456789abcdef\n\\ No newline at end of file', client.get_diff(basepath=os.path.dirname(self.local_path)).rstrip())

    def test_status(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('A       added.txt\nD       deleted.txt\nM       modified-fs.txt\n!       deleted-fs.txt\nM       modified.txt\n', client.get_status())

    def test_status_relpath(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('A       local/added.txt\nD       local/deleted.txt\nM       local/modified-fs.txt\n!       local/deleted-fs.txt\nM       local/modified.txt\n', client.get_status(basepath=os.path.dirname(self.local_path)))

    def test_status_untracked(self):
        client = SvnClient(self.local_path)
        self.assertTrue(client.path_exists())
        self.assertTrue(client.detect_presence())
        self.assertStatusListEqual('?       added-fs.txt\nA       added.txt\nD       deleted.txt\nM       modified-fs.txt\n!       deleted-fs.txt\nM       modified.txt\n', client.get_status(untracked=True))

class SvnExportRepositoryClientTest(SvnClientTestSetups):

    @classmethod
    def setUpClass(self):
        SvnClientTestSetups.setUpClass()
        client = SvnClient(self.local_path)
        client.checkout(self.local_url)

        self.basepath_export = os.path.join(self.root_directory, 'export')

    def tearDown(self):
        pass

    def test_export_repository(self):
        client = SvnClient(self.local_path)
        self.assertTrue(
          client.export_repository('',
            self.basepath_export)
        )

        self.assertTrue(os.path.exists(self.basepath_export + '.tar.gz'))
        self.assertFalse(os.path.exists(self.basepath_export + '.tar'))
        self.assertFalse(os.path.exists(self.basepath_export))
<|endoftext|>


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

    This utility helps you to get localization strings
    from your Apple or Android applications.

    :copyright: (c) 2016 Qurami srl.
    :license: MIT, see LICENSE for more details.
"""

VERSION = '0.3.2'
__version__ = VERSION
<commit_msg>Version bump<commit_after># -*- coding: utf-8 -*-
"""
    strings2pot
    -----------

    This utility helps you to get localization strings
    from your Apple or Android applications.

    :copyright: (c) 2016 Qurami srl.
    :license: MIT, see LICENSE for more details.
"""

VERSION = '0.3.3'
__version__ = VERSION
<|endoftext|>


<commit_before>from inspect import isgenerator

class Dict(dict):
    """
    Dict is a subclass of dict, which allows you to get AND SET(!!)
    items in the dict using the attribute syntax!

    When you previously had to write:

    my_dict = {'a': {'b': {'c': [1, 2, 3]}}}

    you can now do the same simply by:

    my_Dict = Dict()
    my_Dict.a.b.c = [1, 2, 3]

    Or for instance, if you'd like to add some additional stuff,
    where you'd with the normal dict would write

    my_dict['a']['b']['d'] = [4, 5, 6],

    you may now do the AWESOME

    my_Dict.a.b.d = [4, 5, 6]

    instead. But hey, you can always use the same syntax as a regular dict,
    however, this will not raise TypeErrors or AttributeErrors at any time
    while you try to get an item. A lot like a defaultdict.

    """
    def __init__(self, *args, **kwargs):
        """
        If we're initialized with a dict, make sure we turn all the
        subdicts into Dicts as well.

        """
        for arg in args:
            if not arg:
                continue
            elif isinstance(arg, dict):
                for key, val in arg.items():
                    self[key] = val
            elif isinstance(arg, tuple) and (not isinstance(arg[0], tuple)):
                self[arg[0]] = arg[1]
            elif isinstance(arg, (list, tuple)) or isgenerator(arg):
                for key, val in arg:
                    self[key] = val
            else:
                raise TypeError("Dict does not understand "
                                "{0} types".format(type(arg)))

        for key, val in kwargs.items():
            self[key] = val

    def __setattr__(self, name, value):
        """
        setattr is called when the syntax a.b = 2 is used to set a value.

        """
        if hasattr(Dict, name):
            raise AttributeError("'Dict' object attribute "
                                 "'{0}' is read-only".format(name))
        else:
            self[name] = value

    def __setitem__(self, name, value):
        """
        This is called when trying to set a value of the Dict using [].
        E.g. some_instance_of_Dict['b'] = val. If 'val

        """
        value = self._hook(value)
        super(Dict, self).__setitem__(name, value)

    @classmethod
    def _hook(cls, item):
        """
        Called to ensure that each dict-instance that are being set
        is a addict Dict. Recurses.

        """
        if isinstance(item, dict):
            return cls(item)
        elif isinstance(item, (list, tuple)):
            return type(item)(cls._hook(elem) for elem in item)
        return item

    def __getattr__(self, item):
        return self.__getitem__(item)

    def __getitem__(self, name):
        """
        This is called when the Dict is accessed by []. E.g.
        some_instance_of_Dict['a'];
        If the name is in the dict, we return it. Otherwise we set both
        the attr and item to a new instance of Dict.

        """
        if name not in self:
            self[name] = {}
        return super(Dict, self).__getitem__(name)

    def __delattr__(self, name):
        """
        Is invoked when del some_instance_of_Dict.b is called.

        """
        del self[name]

    def __dir__(self):
        """
        Is invoked on a Dict instance causes __getitem__() to get invoked
        which in this module will trigger the creation of the following
        properties: `__members__` and `__methods__`

        To avoid these keys from being added, we simply return an explicit
        call to dir for the Dict object
        """
        return dir(Dict)

    def _ipython_display_(self):
        print(str(self))    # pragma: no cover

    def _repr_html_(self):
        return str(self)

    def prune(self, prune_zero=False, prune_empty_list=True):
        """
        Removes all empty Dicts and falsy stuff inside the Dict.
        E.g
        >>> a = Dict()
        >>> a.b.c.d
        {}
        >>> a.a = 2
        >>> a
        {'a': 2, 'b': {'c': {'d': {}}}}
        >>> a.prune()
        >>> a
        {'a': 2}

        Set prune_zero=True to remove 0 values
        E.g
        >>> a = Dict()
        >>> a.b.c.d = 0
        >>> a.prune(prune_zero=True)
        >>> a
        {}

        Set prune_empty_list=False to have them persist
        E.g
        >>> a = Dict({'a': []})
        >>> a.prune()
        >>> a
        {}
        >>> a = Dict({'a': []})
        >>> a.prune(prune_empty_list=False)
        >>> a
        {'a': []}
        """
        for key, val in list(self.items()):
            if ((not val) and ((val != 0) or prune_zero) and
                    not isinstance(val, list)):
                del self[key]
            elif isinstance(val, Dict):
                val.prune(prune_zero, prune_empty_list)
                if not val:
                    del self[key]
            elif isinstance(val, (list, tuple)):
                new_iter = self._prune_iter(val, prune_zero, prune_empty_list)
                if (not new_iter) and prune_empty_list:
                    del self[key]
                else:
                    if isinstance(val, tuple):
                        new_iter = tuple(new_iter)
                    self[key] = new_iter

    @classmethod
    def _prune_iter(cls, some_iter, prune_zero=False, prune_empty_list=True):
        new_iter = []
        for item in some_iter:
            if item == 0 and prune_zero:
                continue
            elif isinstance(item, Dict):
                item.prune(prune_zero, prune_empty_list)
                if item:
                    new_iter.append(item)
            elif isinstance(item, (list, tuple)):
                new_item = type(item)(
                    cls._prune_iter(item, prune_zero, prune_empty_list))
                if new_item or not prune_empty_list:
                    new_iter.append(new_item)
            else:
                new_iter.append(item)
        return new_iter

    def to_dict(self):
       """
       Recursively turn your addict Dicts into dicts.

       """
       base = dict()
       for key, value in self.items():
           if isinstance(value, type(self)):
               base[key] = value.to_dict()
           elif isinstance(value, (list, tuple)):
               base[key] = type(value)(
                item.to_dict() if isinstance(item, type(self)) else
                item for item in value)
           else:
               base[key] = value
       return base

<commit_msg>Include keys as attributes returned by __dir__()<commit_after>from inspect import isgenerator
import re

class Dict(dict):
    """
    Dict is a subclass of dict, which allows you to get AND SET(!!)
    items in the dict using the attribute syntax!

    When you previously had to write:

    my_dict = {'a': {'b': {'c': [1, 2, 3]}}}

    you can now do the same simply by:

    my_Dict = Dict()
    my_Dict.a.b.c = [1, 2, 3]

    Or for instance, if you'd like to add some additional stuff,
    where you'd with the normal dict would write

    my_dict['a']['b']['d'] = [4, 5, 6],

    you may now do the AWESOME

    my_Dict.a.b.d = [4, 5, 6]

    instead. But hey, you can always use the same syntax as a regular dict,
    however, this will not raise TypeErrors or AttributeErrors at any time
    while you try to get an item. A lot like a defaultdict.

    """
    def __init__(self, *args, **kwargs):
        """
        If we're initialized with a dict, make sure we turn all the
        subdicts into Dicts as well.

        """
        for arg in args:
            if not arg:
                continue
            elif isinstance(arg, dict):
                for key, val in arg.items():
                    self[key] = val
            elif isinstance(arg, tuple) and (not isinstance(arg[0], tuple)):
                self[arg[0]] = arg[1]
            elif isinstance(arg, (list, tuple)) or isgenerator(arg):
                for key, val in arg:
                    self[key] = val
            else:
                raise TypeError("Dict does not understand "
                                "{0} types".format(type(arg)))

        for key, val in kwargs.items():
            self[key] = val

    def __setattr__(self, name, value):
        """
        setattr is called when the syntax a.b = 2 is used to set a value.

        """
        if hasattr(Dict, name):
            raise AttributeError("'Dict' object attribute "
                                 "'{0}' is read-only".format(name))
        else:
            self[name] = value

    def __setitem__(self, name, value):
        """
        This is called when trying to set a value of the Dict using [].
        E.g. some_instance_of_Dict['b'] = val. If 'val

        """
        value = self._hook(value)
        super(Dict, self).__setitem__(name, value)

    @classmethod
    def _hook(cls, item):
        """
        Called to ensure that each dict-instance that are being set
        is a addict Dict. Recurses.

        """
        if isinstance(item, dict):
            return cls(item)
        elif isinstance(item, (list, tuple)):
            return type(item)(cls._hook(elem) for elem in item)
        return item

    def __getattr__(self, item):
        return self.__getitem__(item)

    def __getitem__(self, name):
        """
        This is called when the Dict is accessed by []. E.g.
        some_instance_of_Dict['a'];
        If the name is in the dict, we return it. Otherwise we set both
        the attr and item to a new instance of Dict.

        """
        if name not in self:
            self[name] = {}
        return super(Dict, self).__getitem__(name)

    def __delattr__(self, name):
        """
        Is invoked when del some_instance_of_Dict.b is called.

        """
        del self[name]

    # Regular expression pattern for valid Python attributes
    # https://docs.python.org/3/reference/lexical_analysis.html#identifiers
    _re_pattern = re.compile('[a-zA-Z_][a-zA-Z0-9_]*')

    def __dir__(self):
        """
        Return a list of addict object attributes.
        This includes key names of any dict entries, filtered to the subset of
        valid attribute names (e.g. alphanumeric strings beginning with a letter
        or underscore).  Also includes attributes of parent dict class.
        """
        dict_keys = []
        for k in self.keys():
            if isinstance(k, str):
                m = self._re_pattern.match(k)
                if m:
                    dict_keys.append(m.string)

        obj_attrs = list(dir(Dict))

        return dict_keys + obj_attrs

    def _ipython_display_(self):
        print(str(self))    # pragma: no cover

    def _repr_html_(self):
        return str(self)

    def prune(self, prune_zero=False, prune_empty_list=True):
        """
        Removes all empty Dicts and falsy stuff inside the Dict.
        E.g
        >>> a = Dict()
        >>> a.b.c.d
        {}
        >>> a.a = 2
        >>> a
        {'a': 2, 'b': {'c': {'d': {}}}}
        >>> a.prune()
        >>> a
        {'a': 2}

        Set prune_zero=True to remove 0 values
        E.g
        >>> a = Dict()
        >>> a.b.c.d = 0
        >>> a.prune(prune_zero=True)
        >>> a
        {}

        Set prune_empty_list=False to have them persist
        E.g
        >>> a = Dict({'a': []})
        >>> a.prune()
        >>> a
        {}
        >>> a = Dict({'a': []})
        >>> a.prune(prune_empty_list=False)
        >>> a
        {'a': []}
        """
        for key, val in list(self.items()):
            if ((not val) and ((val != 0) or prune_zero) and
                    not isinstance(val, list)):
                del self[key]
            elif isinstance(val, Dict):
                val.prune(prune_zero, prune_empty_list)
                if not val:
                    del self[key]
            elif isinstance(val, (list, tuple)):
                new_iter = self._prune_iter(val, prune_zero, prune_empty_list)
                if (not new_iter) and prune_empty_list:
                    del self[key]
                else:
                    if isinstance(val, tuple):
                        new_iter = tuple(new_iter)
                    self[key] = new_iter

    @classmethod
    def _prune_iter(cls, some_iter, prune_zero=False, prune_empty_list=True):
        new_iter = []
        for item in some_iter:
            if item == 0 and prune_zero:
                continue
            elif isinstance(item, Dict):
                item.prune(prune_zero, prune_empty_list)
                if item:
                    new_iter.append(item)
            elif isinstance(item, (list, tuple)):
                new_item = type(item)(
                    cls._prune_iter(item, prune_zero, prune_empty_list))
                if new_item or not prune_empty_list:
                    new_iter.append(new_item)
            else:
                new_iter.append(item)
        return new_iter

    def to_dict(self):
       """
       Recursively turn your addict Dicts into dicts.

       """
       base = dict()
       for key, value in self.items():
           if isinstance(value, type(self)):
               base[key] = value.to_dict()
           elif isinstance(value, (list, tuple)):
               base[key] = type(value)(
                item.to_dict() if isinstance(item, type(self)) else
                item for item in value)
           else:
               base[key] = value
       return base

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
import meshio
import pytest

import helpers
import legacy_reader
import legacy_writer

vtk = pytest.importorskip('vtk')

test_set = [
    helpers.tri_mesh,
    helpers.triangle6_mesh,
    helpers.quad_mesh,
    helpers.quad8_mesh,
    helpers.tri_quad_mesh,
    helpers.tet_mesh,
    helpers.tet10_mesh,
    helpers.hex_mesh,
    helpers.hex20_mesh,
    helpers.add_point_data(helpers.tri_mesh, 1),
    helpers.add_point_data(helpers.tri_mesh, 2),
    helpers.add_point_data(helpers.tri_mesh, 3),
    helpers.add_cell_data(helpers.tri_mesh, 1),
    helpers.add_cell_data(helpers.tri_mesh, 2),
    helpers.add_cell_data(helpers.tri_mesh, 3),
    ]

@pytest.mark.parametrize('mesh', test_set)
def test_ascii(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=False, **kwargs)

    helpers.write_read(writer, meshio.vtk_io.read, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
def test_ascii_legacy1(mesh):
    # test with legacy writer
    def lw(*args, **kwargs):
        return legacy_writer.write('vtk-ascii', *args, **kwargs)

    # The legacy writer only writes with low precision.
    helpers.write_read(lw, meshio.vtk_io.read, mesh, 1.0e-11)

@pytest.mark.parametrize('mesh', test_set)
def test_ascii_legacy2(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=False, **kwargs)

    # test with legacy reader
    def lr(filename):
        return legacy_reader.read('vtk-ascii', filename)

    helpers.write_read(writer, lr, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
def test_binary(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=True, **kwargs)

    helpers.write_read(writer, meshio.vtk_io.read, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
# test with legacy writer
def test_binary_legacy1(mesh):
    def lw(
            filename, points, cells, point_data, cell_data, field_data
            ):
        return legacy_writer.write(
            'vtk-binary',
            filename, points, cells, point_data, cell_data, field_data
            )

    # The legacy writer only writes with low precision.
    helpers.write_read(lw, meshio.vtk_io.read, mesh, 1.0e-11)
    return

@pytest.mark.parametrize('mesh', test_set)
# test with legacy reader
def test_binary_legacy2(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=True, **kwargs)

    # The legacy writer only writes with low precision.
    def lr(filename):
        return legacy_reader.read('vtk-binary', filename)

    helpers.write_read(writer, lr, mesh, 1.0e-15)
    return

if __name__ == '__main__':
    test_binary(helpers.tri_mesh)
<commit_msg>simplify vtk tests<commit_after># -*- coding: utf-8 -*-
#
import meshio
import pytest

import helpers
import legacy_reader
import legacy_writer

vtk = pytest.importorskip('vtk')

test_set = [
    helpers.tri_mesh,
    helpers.triangle6_mesh,
    helpers.quad_mesh,
    helpers.quad8_mesh,
    helpers.tri_quad_mesh,
    helpers.tet_mesh,
    helpers.tet10_mesh,
    helpers.hex_mesh,
    helpers.hex20_mesh,
    helpers.add_point_data(helpers.tri_mesh, 1),
    helpers.add_point_data(helpers.tri_mesh, 2),
    helpers.add_point_data(helpers.tri_mesh, 3),
    helpers.add_cell_data(helpers.tri_mesh, 1),
    helpers.add_cell_data(helpers.tri_mesh, 2),
    helpers.add_cell_data(helpers.tri_mesh, 3),
    ]

@pytest.mark.parametrize('mesh', test_set)
def test_ascii(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=False, **kwargs)

    helpers.write_read(writer, meshio.vtk_io.read, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
def test_ascii_legacy1(mesh):
    # test with legacy writer
    def lw(*args, **kwargs):
        return legacy_writer.write('vtk-ascii', *args, **kwargs)

    # The legacy writer only writes with low precision.
    helpers.write_read(lw, meshio.vtk_io.read, mesh, 1.0e-11)
    return

@pytest.mark.parametrize('mesh', test_set)
def test_ascii_legacy2(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=False, **kwargs)

    # test with legacy reader
    def lr(filename):
        return legacy_reader.read('vtk-ascii', filename)

    helpers.write_read(writer, lr, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
def test_binary(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=True, **kwargs)

    helpers.write_read(writer, meshio.vtk_io.read, mesh, 1.0e-15)
    return

@pytest.mark.parametrize('mesh', test_set)
# test with legacy writer
def test_binary_legacy1(mesh):
    def lw(*args, **kwargs):
        return legacy_writer.write('vtk-binary', *args, **kwargs)

    # The legacy writer only writes with low precision.
    helpers.write_read(lw, meshio.vtk_io.read, mesh, 1.0e-11)
    return

@pytest.mark.parametrize('mesh', test_set)
# test with legacy reader
def test_binary_legacy2(mesh):
    def writer(*args, **kwargs):
        return meshio.vtk_io.write(*args, write_binary=True, **kwargs)

    # The legacy writer only writes with low precision.
    def lr(filename):
        return legacy_reader.read('vtk-binary', filename)

    helpers.write_read(writer, lr, mesh, 1.0e-15)
    return

if __name__ == '__main__':
    test_binary(helpers.tri_mesh)
<|endoftext|>


<commit_before># dathomir
# Copyright (C) 2007 Phil Christensen
#
# $Id$
#
# See LICENSE for details

import traceback, mimetypes, os, stat, os.path

from mod_python import apache

class Request(dict):
	def __init__(self, d):
		dict.__init__(self)
		self.update(d)

	def __getattr__(self, key):
		if(key in self):
			return self[key]
		elif(key.find('_') != -1):
			return self[key.replace('_', '.')]
		raise AttributeError(key)

	def log_error(self, data):
		self['wsgi.errors'].write(data)

class InputWrapper(object):
	def __init__(self, mp_req):
		self.mp_req = mp_req

	def close(self):
		pass

	def read(self, size=-1):
		return self.mp_req.read(size)

	def readline(self, size=-1):
		return self.mp_req.readline(size)

	def readlines(self, hint=-1):
		return self.mp_req.readlines(hint)

	def __iter__(self):
		line = self.readline()
		while line:
			yield line
			# Notice this won't prefetch the next line; it only
			# gets called if the generator is resumed.
			line = self.readline()

class ErrorWrapper(object):
	def __init__(self, mp_req):
		self.mp_req = mp_req

	def flush(self):
		pass

	def write(self, msg):
		self.mp_req.log_error(msg)

	def writelines(self, seq):
		self.write(''.join(seq))

class FileWrapper:
	def __init__(self, filelike, blksize=8192):
		self.filelike = filelike
		self.blksize = blksize
		if hasattr(filelike,'close'):
			self.close = filelike.close

	def __getitem__(self,key):
		data = self.filelike.read(self.blksize)
		if data:
			return data
		raise IndexError

def get_environment(mp_req):
	options = mp_req.get_options()

	# Threading and forking
	try:
		q = apache.mpm_query
		threaded = q(apache.AP_MPMQ_IS_THREADED)
		forked = q(apache.AP_MPMQ_IS_FORKED)
	except AttributeError:
		threaded = options.get('multithread', '').lower()
		if threaded == 'on':
			threaded = True
		elif threaded == 'off':
			threaded = False
		else:
			raise ValueError(bad_value % "multithread")

		forked = options.get('multiprocess', '').lower()
		if forked == 'on':
			forked = True
		elif forked == 'off':
			forked = False
		else:
			raise ValueError(bad_value % "multiprocess")

	env = dict(apache.build_cgi_env(mp_req))

	from dathomir import app
	app.load_config(env)

	env['SCRIPT_FILENAME'] = env['dathomir.approot'] = apache.get_handler_root()
	env['SCRIPT_NAME'] = env['dathomir.config.base_url']

	uri = env['REQUEST_URI']
	if(uri.startswith(env['SCRIPT_NAME'])):
		env['PATH_INFO'] = env['dathomir.path'] = uri[len(env['SCRIPT_NAME']):]
	else:
		env['PATH_INFO'] = env['dathomir.path'] = uri

	if('CONTENT_LENGTH' in mp_req.headers_in):
		env['CONTENT_LENGTH'] = long(mp_req.headers_in['Content-Length'])

	approot = env['dathomir.approot']
	webroot = env['dathomir.config.webroot']
	webroot = os.path.join(approot, webroot)
	env['PATH_TRANSLATED'] = os.path.realpath(webroot + env['dathomir.path'])

	env['wsgi.input'] = InputWrapper(mp_req)
	env['wsgi.errors'] = ErrorWrapper(mp_req)
	env['wsgi.file_wrapper'] = FileWrapper
	env['wsgi.version'] = (1,0)
	env['wsgi.run_once'] = False
	if env.get("HTTPS") in ('yes', 'on', '1'):
		env['wsgi.url_scheme'] = 'https'
	else:
		env['wsgi.url_scheme'] = 'http'
	env['wsgi.multithread'] = threaded
	env['wsgi.multiprocess'] = forked

	return env

def handler(req, start_response):
	from dathomir import app

	req = Request(req)

	result = check_file(req)
	if(result):
		content = []
		if(result[1]):
			app.add_header('Content-Type', result[1])
			app.add_header('Content-Length', result[2])
			try:
				content = FileWrapper(open(result[0]))
			except:
				status = '401 Forbidden'
			else:
				status = '200 OK'
		else:
			status = '401 Forbidden'
		start_response(status, app.get_headers())
		return content

	tree = app.get_tree()
	rsrc = tree.parse(req['dathomir.path'])
	if not(rsrc):
		start_response('404 Not Found', [])
		return []

	req['dathomir.tree'] = tree

	req.log_error('req was: ' + str(req))
	app.bootstrap(req)
	req.log_error('req is: ' + str(req))

	rsrc.prepare_content(req)
	app.add_header('Content-Type', rsrc.get_content_type(req))
	content = rsrc.get_content(req)
	app.add_header('Content-Length', len(content))

	if(req['dathomir.config.db_url'] and req['dathomir.config.session_class']):
		req['dathomir.session'].save()

	start_response('200 OK', app.get_headers())
	return [content]

def check_file(req):
	true_path = req['PATH_TRANSLATED']
	try:
		finfo = os.stat(true_path)
		# note that there's no support for directory indexes,
		# only direct file access
		if(stat.S_ISREG(finfo.st_mode)):
			try:
				content_type = mimetypes.guess_type(true_path)[0]
				size = finfo.st_size
				return (true_path, content_type, size)
			except IOError:
				return (true_path, None, None)
	except OSError:
		pass

	return None

<commit_msg>Removed some debugging info, session tweak<commit_after># dathomir
# Copyright (C) 2007 Phil Christensen
#
# $Id$
#
# See LICENSE for details

import traceback, mimetypes, os, stat, os.path

from mod_python import apache

class Request(dict):
	def __init__(self, d):
		dict.__init__(self)
		self.update(d)

	def __getattr__(self, key):
		if(key in self):
			return self[key]
		elif(key.find('_') != -1):
			return self[key.replace('_', '.')]
		raise AttributeError(key)

	def log_error(self, data):
		self['wsgi.errors'].write(data)

class InputWrapper(object):
	def __init__(self, mp_req):
		self.mp_req = mp_req

	def close(self):
		pass

	def read(self, size=-1):
		return self.mp_req.read(size)

	def readline(self, size=-1):
		return self.mp_req.readline(size)

	def readlines(self, hint=-1):
		return self.mp_req.readlines(hint)

	def __iter__(self):
		line = self.readline()
		while line:
			yield line
			# Notice this won't prefetch the next line; it only
			# gets called if the generator is resumed.
			line = self.readline()

class ErrorWrapper(object):
	def __init__(self, mp_req):
		self.mp_req = mp_req

	def flush(self):
		pass

	def write(self, msg):
		self.mp_req.log_error(msg)

	def writelines(self, seq):
		self.write(''.join(seq))

class FileWrapper:
	def __init__(self, filelike, blksize=8192):
		self.filelike = filelike
		self.blksize = blksize
		if hasattr(filelike,'close'):
			self.close = filelike.close

	def __getitem__(self,key):
		data = self.filelike.read(self.blksize)
		if data:
			return data
		raise IndexError

def get_environment(mp_req):
	options = mp_req.get_options()

	# Threading and forking
	try:
		q = apache.mpm_query
		threaded = q(apache.AP_MPMQ_IS_THREADED)
		forked = q(apache.AP_MPMQ_IS_FORKED)
	except AttributeError:
		threaded = options.get('multithread', '').lower()
		if threaded == 'on':
			threaded = True
		elif threaded == 'off':
			threaded = False
		else:
			raise ValueError(bad_value % "multithread")

		forked = options.get('multiprocess', '').lower()
		if forked == 'on':
			forked = True
		elif forked == 'off':
			forked = False
		else:
			raise ValueError(bad_value % "multiprocess")

	env = dict(apache.build_cgi_env(mp_req))

	from dathomir import app
	app.load_config(env)

	env['SCRIPT_FILENAME'] = env['dathomir.approot'] = apache.get_handler_root()
	env['SCRIPT_NAME'] = env['dathomir.config.base_url']

	uri = env['REQUEST_URI']
	if(uri.startswith(env['SCRIPT_NAME'])):
		env['PATH_INFO'] = env['dathomir.path'] = uri[len(env['SCRIPT_NAME']):]
	else:
		env['PATH_INFO'] = env['dathomir.path'] = uri

	if('CONTENT_LENGTH' in mp_req.headers_in):
		env['CONTENT_LENGTH'] = long(mp_req.headers_in['Content-Length'])

	approot = env['dathomir.approot']
	webroot = env['dathomir.config.webroot']
	webroot = os.path.join(approot, webroot)
	env['PATH_TRANSLATED'] = os.path.realpath(webroot + env['dathomir.path'])

	env['wsgi.input'] = InputWrapper(mp_req)
	env['wsgi.errors'] = ErrorWrapper(mp_req)
	env['wsgi.file_wrapper'] = FileWrapper
	env['wsgi.version'] = (1,0)
	env['wsgi.run_once'] = False
	if env.get("HTTPS") in ('yes', 'on', '1'):
		env['wsgi.url_scheme'] = 'https'
	else:
		env['wsgi.url_scheme'] = 'http'
	env['wsgi.multithread'] = threaded
	env['wsgi.multiprocess'] = forked

	return env

def handler(req, start_response):
	from dathomir import app

	req = Request(req)

	result = check_file(req)
	if(result):
		content = []
		if(result[1]):
			app.add_header('Content-Type', result[1])
			app.add_header('Content-Length', result[2])
			try:
				content = FileWrapper(open(result[0]))
			except:
				status = '401 Forbidden'
			else:
				status = '200 OK'
		else:
			status = '401 Forbidden'
		start_response(status, app.get_headers())
		return content

	tree = app.get_tree()
	rsrc = tree.parse(req['dathomir.path'])
	if not(rsrc):
		start_response('404 Not Found', [])
		return []

	req['dathomir.tree'] = tree

	app.bootstrap(req)

	rsrc.prepare_content(req)
	app.add_header('Content-Type', rsrc.get_content_type(req))
	content = rsrc.get_content(req)
	app.add_header('Content-Length', len(content))

	if('dathomir.session' in req):
		req['dathomir.session'].save()

	start_response('200 OK', app.get_headers())
	return [content]

def check_file(req):
	true_path = req['PATH_TRANSLATED']
	try:
		finfo = os.stat(true_path)
		# note that there's no support for directory indexes,
		# only direct file access
		if(stat.S_ISREG(finfo.st_mode)):
			try:
				content_type = mimetypes.guess_type(true_path)[0]
				size = finfo.st_size
				return (true_path, content_type, size)
			except IOError:
				return (true_path, None, None)
	except OSError:
		pass

	return None

<|endoftext|>


<commit_before>from urwid import (Columns,
                   LineBox,
                   Text,
                   Frame,
                   ListBox,
                   AttrMap,
                   Padding,
                   SimpleListWalker)

from . import version, title

class AerendeInterface(Columns):
    """
    Creates the interface for Aerende, as well as providing refresh and drawing
    functions.
    """

    def __init__(self):
        self.notes_frame = NotesFrame([])
        self.tags_list = TagsListBox([])
        Columns.__init__(self, [(18, self.tags_list), self.notes_frame])

    # [ Notes ]

    def draw_notes(self, notes):
        self.contents[1][0].draw_notes(notes)

    # [ Tags ]

    def draw_tags(self, tags):
        self.contents[0][0].draw_tags(tags)

class NoteWidget(LineBox):
    """Widget for displaying a note"""

    def __init__(self, note):
        self.note = note

        header = self._create_header(note)
        footer = self._create_footer(note)
        note_display = Text("{0}\n\n{1}\n\n{2}".format(
                                  header, note.text, footer))
        LineBox.__init__(self, note_display)

    def _create_header(self, note):
        return "{0} :: {1}".format(note.priority, note.title)

    def _create_footer(self, note):
        footer_template = "[ {0} ]"
        return footer_template.format(" // ".join(note.tags))

class NotesFrame(Frame):
    """"Frame for displaying notes and status"""

    def __init__(self, notes):
        note_widgets = self._create_note_widgets(notes)
        self.notes = ListBox(SimpleListWalker(note_widgets))
        self.status = self._create_statusbar(notes)
        Frame.__init__(self, self.notes, footer=self.status)

    def _create_note_widgets(self, notes):
        note_widgets = []
        for note in notes:
            note_widgets.append(NoteWidget(note))
        return note_widgets

    def _create_statusbar(self, notes):
        aerende_text = Text("{0} :: {1}".format(title, version))
        notes_text = Text(" [ {0} ]".format(len(notes)), align='right')
        columns = Columns([aerende_text, notes_text])
        return AttrMap(Padding(columns, left=1, right=1), 'highlight')

    def draw_notes(self, notes):
        note_widgets = self._create_note_widgets(notes)
        self.body = ListBox(SimpleListWalker(note_widgets))
        self.set_body(self.body)
        self.footer = self._create_statusbar(notes)
        self.set_footer(self.footer)

class TagsListBox(ListBox):
    """ListBox widget for displaying a list of tags"""

    def __init__(self, tags):
        tag_widgets = self._create_tag_widgets(tags)
        ListBox.__init__(self, SimpleListWalker(tag_widgets))

    def _create_tag_widgets(self, tags):
        tag_widgets = []
        for tag in tags:
            tag_widgets.append(Text(str(tag)))
        return tag_widgets

    def draw_tags(self, tags):
        tag_widgets = self._create_tag_widgets(tags)
        self.body = SimpleListWalker(tag_widgets)
<commit_msg>Resize tag sidebar based on longest tag<commit_after>from urwid import (Columns,
                   LineBox,
                   Text,
                   Frame,
                   ListBox,
                   AttrMap,
                   Padding,
                   SimpleListWalker)

from . import version, title

class AerendeInterface(Columns):
    """
    Creates the interface for Aerende, as well as providing refresh and drawing
    functions.
    """

    def __init__(self):
        self.notes_frame = NotesFrame([])
        self.tags_list = TagsListBox([])
        Columns.__init__(self, [(18, self.tags_list), self.notes_frame])

    # [ Notes ]

    def draw_notes(self, notes):
        self.contents[1][0].draw_notes(notes)

    # [ Tags ]

    def draw_tags(self, tags):
        tag_list = self.contents[0][0]
        tag_list.draw_tags(tags)
        new_options = self.options('given', tag_list.get_max_width(tags),
                                   False)
        self.contents[0] = (tag_list, new_options)

class NoteWidget(LineBox):
    """Widget for displaying a note"""

    def __init__(self, note):
        self.note = note

        header = self._create_header(note)
        footer = self._create_footer(note)
        note_display = Text("{0}\n\n{1}\n\n{2}".format(
                                  header, note.text, footer))
        LineBox.__init__(self, note_display)

    def _create_header(self, note):
        return "{0} :: {1}".format(note.priority, note.title)

    def _create_footer(self, note):
        footer_template = "[ {0} ]"
        return footer_template.format(" // ".join(note.tags))

class NotesFrame(Frame):
    """"Frame for displaying notes and status"""

    def __init__(self, notes):
        note_widgets = self._create_note_widgets(notes)
        self.notes = ListBox(SimpleListWalker(note_widgets))
        self.status = self._create_statusbar(notes)
        Frame.__init__(self, self.notes, footer=self.status)

    def _create_note_widgets(self, notes):
        note_widgets = []
        for note in notes:
            note_widgets.append(NoteWidget(note))
        return note_widgets

    def _create_statusbar(self, notes):
        aerende_text = Text("{0} :: {1}".format(title, version))
        notes_text = Text(" [ {0} ]".format(len(notes)), align='right')
        columns = Columns([aerende_text, notes_text])
        return AttrMap(Padding(columns, left=1, right=1), 'highlight')

    def draw_notes(self, notes):
        note_widgets = self._create_note_widgets(notes)
        self.body = ListBox(SimpleListWalker(note_widgets))
        self.set_body(self.body)
        self.footer = self._create_statusbar(notes)
        self.set_footer(self.footer)

class TagsListBox(ListBox):
    """ListBox widget for displaying a list of tags"""

    def __init__(self, tags):
        tag_widgets = self._create_tag_widgets(tags)
        ListBox.__init__(self, SimpleListWalker(tag_widgets))

    def _create_tag_widgets(self, tags):
        tag_widgets = []
        for tag in tags:
            tag_widgets.append(Text(str(tag)))
        return tag_widgets

    def draw_tags(self, tags):
        tag_widgets = self._create_tag_widgets(tags)
        self.body = SimpleListWalker(tag_widgets)

    def get_max_width(self, tags):
        max_width = 30
        min_width = 18
        width = 0
        for tag in tags:
            l = len(str(tag)) + 2
            if l > width:
                width = l

        if width > max_width:
            return max_width
        elif width < min_width:
            return min_width
        return max_width
<|endoftext|>


<commit_before># Copyright 2020 The XLS Authors
#
# 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.

"""Provides a rule that creates a C++ library from an .so file."""

load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")

def _impl(ctx):
    cc_toolchain = find_cc_toolchain(ctx)
    feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain = cc_toolchain)
    linker_inputs = [cc_common.create_linker_input(
        owner = ctx.label,
        user_link_flags = depset([ctx.file.src.path]),
        additional_inputs = depset([ctx.file.src]),
    )]

    return [
        DefaultInfo(
            files = depset([ctx.file.src]),
        ),
        CcInfo(
            linking_context = cc_common.create_linking_context(
                linker_inputs = depset(linker_inputs),
            ),
        ),
    ]

cc_so_library = rule(
    implementation = _impl,
    fragments = ["cpp"],
    attrs = {
        "src": attr.label(allow_single_file = True),
        "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
    },
    incompatible_use_toolchain_transition = True,
    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)
<commit_msg>Remove uses of `incompatible_use_toolchain_transition` now that it is enabled by default.<commit_after># Copyright 2020 The XLS Authors
#
# 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.

"""Provides a rule that creates a C++ library from an .so file."""

load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")

def _impl(ctx):
    cc_toolchain = find_cc_toolchain(ctx)
    feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain = cc_toolchain)
    linker_inputs = [cc_common.create_linker_input(
        owner = ctx.label,
        user_link_flags = depset([ctx.file.src.path]),
        additional_inputs = depset([ctx.file.src]),
    )]

    return [
        DefaultInfo(
            files = depset([ctx.file.src]),
        ),
        CcInfo(
            linking_context = cc_common.create_linking_context(
                linker_inputs = depset(linker_inputs),
            ),
        ),
    ]

cc_so_library = rule(
    implementation = _impl,
    fragments = ["cpp"],
    attrs = {
        "src": attr.label(allow_single_file = True),
        "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
    },
    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)
<|endoftext|>