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

'''
File: MongoSplitter.py
Author: NYU ITP Team
Description: Will calculate splits for a given collection/database
and store/return them in MongoSplit objects
'''
from pymongo import Connection, uri_parser
from sets import Set
from MongoInputSplit import MongoInputSplit
from mongoUtil import getCollection, getConnection,getDatabase

import logging
import bson

from pymongo.uri_parser import (_partition,
                                _rpartition,
                                parse_userinfo,
                                split_hosts,
                                split_options,
                                parse_uri)

def calculate_splits(config):
    """reads config to find out what type of split to perform"""
    #pass
    uri = config.get("inputURI") if "inputURI" in config else "mongodb://localhost/test.in"

    #HACK -> make config align with this ^^
    config['inputURI'] = uri
    #/HACK

    #config.getInputURI()
    uri_info = uri_parser.parse_uri(uri)

    database_name = uri_info['database']
    collection_name = uri_info['collection']

    '''
    connection = getConnection(uri)
    db = connection[database_name]
    '''

    db = getDatabase(uri)
    stats = db.command("collstats", collection_name)

    isSharded = False if "sharded" not in stats else stats["sharded"]
    useShards = False #config.canReadSplitsFromShards()
    useChunks = False #config.isShardChunkedSplittingEnabled()
    slaveOk = True #config.canReadSplitsFromSecondary()

    logging.info(" Calculate Splits Code ... Use Shards? - %s\nUse Chunks? - %s\nCollection Sharded? - %s" % (useShards, useChunks, isSharded))

    if config.get("createInputSplits"):
        logging.info( "Creation of Input Splits is enabled." )
        if isSharded and (useShards or useChunks):
            if useShards and useChunks:
                logging.warn( "Combining 'use chunks' and 'read from shards directly' can have unexpected & erratic behavior in a live system due to chunk migrations. " )

            logging.info( "Sharding mode calculation entering." )
            return calculate_sharded_splits( config, useShards, useChunks, slaveOk, uri, mongo )

        else: # perfectly ok for sharded setups to run with a normally calculated split. May even be more efficient for some cases
            logging.info( "Using Unsharded Split mode (Calculating multiple splits though)" )
            return calculate_unsharded_splits( config, slaveOk, uri, collection_name )

    else:
        logging.info( "Creation of Input Splits is disabled; Non-Split mode calculation entering." );
        return calculate_single_split( config )

def calculate_unsharded_splits(config, slaveOk, uri, collection_name):
    """@todo: Docstring for calculate_unsharded_splits

    :returns: @todo

    Note: collection_name seems unnecessary --CW

    """
    splits = [] #will return this list
    print "calculating unsharded splits"

    # TODO: pass these fields VV as parameters? (02/26/12, 11:30, AFlock)
    '''
    connection = getConnection(uri)
    db = getDatabase(uri)
    coll = db[config.get('collection_name')]
    '''
    coll = getCollection(uri)

    q = {} if not "query" in config else config.get("query")

    print 'in unsharded splits'
    #print 'query in MongoSplitter is ' + q
    #for key in q:
        #print 'am I printing the query?'
        #print q[key]

    #create command
    #command to split should look like this VV
    #SON([('splitVector', u'test.test_data'), ('maxChunkSize', 2), ('force', False), ('keyPattern', {'x': 1})])
    split_key = config.get('splitKey')
    split_size = config.get('splitSize')
    full_name  = coll.full_name
    logging.info("Calculating unsharded splits on collection %s with Split Key %s" % (full_name, split_key))
    logging.info("Max split size :: %sMB" % split_size)

    cmd = bson.son.SON()
    cmd["splitVector"]  = full_name
    cmd["maxChunkSize"] = split_size
    cmd["keyPattern"]   = split_key
    cmd["force"]        = True

    logging.debug("Issuing Command: %s" % cmd)
    print "Issuing Command: %s" % cmd
    data = coll.database.command(cmd)
    print data

    #results look like this VV
    #{u'ok': 1.0, u'splitKeys': [{u'_id': ObjectId('4f49775348d9846c5e582b00')}, {u'_id': ObjectId('4f49775548d9846c5e58553b')}]}

    if data.get("err"):
        raise Exception(data.get("err"))
    elif data.get("ok") != 1.0:
        print data
        raise Exception("Unable to calculate splits")

    split_data = data.get('splitKeys')
    if not split_data:
        logging.warning("WARNING: No Input Splits were calculated by the split code.  Proceeding with a *single* split. Data may be too small, try lowering 'mongo.input.split_size'  if this is undesirable.")
    else:
        logging.info("Calculated %s splits" % len(split_data))

        # TODO: what is the query q parameter? (02/26/12, 12:18, AFlock)
        last_key = None
        for bound in split_data:
            splits.append(_split(config, q, last_key, bound))
            last_key = bound
        splits.append(_split(config, q, last_key, None))

    return [s.format_uri_with_query() for s in splits]

def _split(config=None, q={}, min=None, max=None):
    """@todo: Docstring for _split
    :returns: an actual MongoSplit object
    """
    print "_split being created"
    query = bson.son.SON()
    query["$query"]  = q

    if min:
        query["$min"] = min

    if max:
        query["$max"] = max

    logging.info("Assembled Query: " , query)

    return MongoInputSplit(
            config.get("inputURI"),
            config.get("inputKey"),
            query,
            config.get("fields"),
            config.get("sort"),
            config.get("limit", 0),
            config.get("skip", 0),
            config.get("timeout", True))

def calculate_single_split(config):
    #splits = [None] * 1 #will return this list's URI
    splits = []
    print "calculating single split"

    splits.append(MongoInputSplit(
            config.get("inputURI"),
            config.get("inputKey"),
            query,
            config.get("fields"),
            config.get("sort"),
            config.get("limit", 0),
            config.get("skip", 0),
            config.get("timeout", True)))

    logging.debug("Calculated %d split objects"% len(splits) )
    logging.debug("Dump of calculated splits ... ")
    for s in splits:
        logging.debug("    Split: %s"% split)
    return [s.format_uri_with_query() for s in splits]
#pass

def calculate_sharded_splits(config, useShards, useChunks, slaveOk, uri):
    """Worry about this after unsharded splits are doen

    :returns: @todo
    """
    splits = []
    if useChunks:
        splits = fetch_splits_via_chunks(config, uri, useShards, slaveOk)
    elif useShards:
        logging.warn("Fetching Input Splits directly from shards is potentially dangerous for data consistency should migrations occur during the retrieval.")
        splits = fetch_splits_from_shards(config, uri, slaveOk)
    else:
        logging.error("Neither useChunks nor useShards enabled; failed to pick a valid state.")

    if splits == None:
        logging.error("Failed to create/calculate Input Splits from Shard Chunks; final splits content is 'None'." )

    logging.debug("Calculated splits and returning them - splits: ", splits)
    return splits

def fetch_splits_from_shards(config, uri, slaveOk):
    """@todo: Docstring for fetch_splits_from_shards

    :returns: @todo
    """
    logging.warn("WARNING getting splits that connect directly to the backend mongods is risky and might not produce correct results")
    connection = getConnection(uri)

    configDB = connection["config"]
    shardsColl = db[config.get("shards")]

    shardSet = set()
    cur = shardsColl.find()

    try:
        for row in cur:
            host = row.get('host')
            slashIndex = host.find("/")
            if slashIndex > 0:
                host = host[slashIndex+1:]
            shardSet.append(host)
    finally:
        if cur != None:
            cur.close()
        cur = None

    splits = []
    for host in shardSet:
        splits.append(MongoInputSplit(config.get("inputURI"),
                config.get("inputKey"),
                config.get("query"),
                config.get("fields"),
                config.get("sort"),
                config.get("limit", 0),
                config.get("skip", 0),
                config.get("timeout", True)))

    return [s.format_uri_with_query() for s in splits]

def fetch_splits_via_chunks(config, uri, useShards, slaveOk):
    """@todo: Docstring for fetch_splits_via_chunks

    :returns: @todo
    """
    originalQuery = config.get("query")
    if useShards:
        logging.warn("WARNING getting splits that connect directly to the backend mongods is risky and might not produce correct results" )

    logging.debug("fetch_splits_via_chunks: originalQuery: %s"% originalQuery)

    connection = getConnection(uri)

    configDB = connection["config"]

    shardMap = {}

    if useShards:
        shardsColl = db[config.get("shards")]
        cur = shardsColl.find()

        try:
            for row in cur:
                host = row.get('host')
                slashIndex = host.find("/")
                if slashIndex > 0:
                    host = host[slashIndex+1:]
                shardMap[row.get('_id')] = host
        finally:
            if cur != None:
                cur.close()

    logging.debug( "MongoInputFormat.getSplitsUsingChunks(): shard map is: %s"% shardMap )

    chunksCollection = db[config.get("chunks")]
    query = bson.son.SON()
    db = connection[config['db_name']]
    query["$ns"] = db + "." + db[config['collection_name']]

    cur = chunksCollection.find(query)

    try:
        numChunks = 0
        numExpectedChunks = len(cur)

        splits = []

        for row in cur:
            numChunks += 1
            minObj = row.get('min')
            shardKeyQuery = bson.son.SON()
            min = bson.son.SON()
            max = bson.son.SON()

            for key in minObj:
                tMin = minObj[key]
                tMax = (row.get('max'))[key]
    #if (The splitFriendyDBCallBack calls here!!!!)
	#
	#
	#
            if originalQuery == None:
                originalQuery = bson.son.SON()

            shardKeyQuery["$min"] = min
            shardKeyQuery["$max"] = max
            shardKeyQuery["$query"] = originalQuery

            logging.debug("["+numChunks+"/"+numExpectedChunks+"] new query is: "+shardKeyQuery)

            inputURI = config.get("inputURI")

            if useShards:
                shardName = row.get('shard')
                host = shardMap[shardName]
               #inputURI = new URI??

            splits.append(MongoInputSplit(
                config.get("inputURI"),
                config.get("inputKey"),
                config.get("query"),
                config.get("fields"),
                config.get("sort"),
                config.get("limit", 0),
                config.get("skip", 0),
                config.get("timeout", True)))

        logging.debug("MongoInputFormat.fetch_splits_via_chunks(): There were %d chunks, returning %d splits: %s"%(numChunks, len(splits), splits))

        return [s.format_uri_with_query() for s in splits]

    finally:
        if cur != None:
            cur.close()

'''
def get_new_URI(original_URI, new_URI, slave_OK):
    """@todo: Docstring for get_new_URI

    :original_URI: @todo
    :etc: @todo
    :returns: a new Mongo_URI
    """

#    pass
    orig_URI_string = SCHEME_LEN
    server_end = -1
    server_start = 0

    """to find the last index of / in the original URI string """
    idx = orig_URI_string[::-1].find("/")
    if idx < 0:
        server_end = len(orig_URI_string)
    else:
        server_end = idx

    idx = orig_URI_string.find("@")

    if idx > 0:
        server_start = idx + 1

    sb = orig_URI_string
    sb.replace(orig_URI_string[server_start:server_end], new_URI)
    if slave_OK != null:
        if "?" in orig_URI_string:
            sb.append("&slaveok=").append(slave_OK)
        else
            sb.append("?slaveok=").append(slave_OK)

    ans = SCHEME + sb
    logging.debug("get_new_URI(): original " + original_URI + " new uri: " + ans )
    return ans
'''
<commit_msg>Fix error in fetch_splits_from_shards function<commit_after>#!/usr/bin/env python
# encoding: utf-8

'''
File: MongoSplitter.py
Author: NYU ITP Team
Description: Will calculate splits for a given collection/database
and store/return them in MongoSplit objects
'''
from pymongo import Connection, uri_parser
from sets import Set
from MongoInputSplit import MongoInputSplit
from mongoUtil import getCollection, getConnection,getDatabase

import logging
import bson

from pymongo.uri_parser import (_partition,
                                _rpartition,
                                parse_userinfo,
                                split_hosts,
                                split_options,
                                parse_uri)

def calculate_splits(config):
    """reads config to find out what type of split to perform"""
    #pass
    uri = config.get("inputURI") if "inputURI" in config else "mongodb://localhost/test.in"

    #HACK -> make config align with this ^^
    config['inputURI'] = uri
    #/HACK

    #config.getInputURI()
    uri_info = uri_parser.parse_uri(uri)

    database_name = uri_info['database']
    collection_name = uri_info['collection']

    '''
    connection = getConnection(uri)
    db = connection[database_name]
    '''

    db = getDatabase(uri)
    stats = db.command("collstats", collection_name)

    isSharded = False if "sharded" not in stats else stats["sharded"]
    useShards = False #config.canReadSplitsFromShards()
    useChunks = False #config.isShardChunkedSplittingEnabled()
    slaveOk = True #config.canReadSplitsFromSecondary()

    logging.info(" Calculate Splits Code ... Use Shards? - %s\nUse Chunks? - %s\nCollection Sharded? - %s" % (useShards, useChunks, isSharded))

    if config.get("createInputSplits"):
        logging.info( "Creation of Input Splits is enabled." )
        if isSharded and (useShards or useChunks):
            if useShards and useChunks:
                logging.warn( "Combining 'use chunks' and 'read from shards directly' can have unexpected & erratic behavior in a live system due to chunk migrations. " )

            logging.info( "Sharding mode calculation entering." )
            return calculate_sharded_splits( config, useShards, useChunks, slaveOk, uri, mongo )

        else: # perfectly ok for sharded setups to run with a normally calculated split. May even be more efficient for some cases
            logging.info( "Using Unsharded Split mode (Calculating multiple splits though)" )
            return calculate_unsharded_splits( config, slaveOk, uri, collection_name )

    else:
        logging.info( "Creation of Input Splits is disabled; Non-Split mode calculation entering." );
        return calculate_single_split( config )

def calculate_unsharded_splits(config, slaveOk, uri, collection_name):
    """@todo: Docstring for calculate_unsharded_splits

    :returns: @todo

    Note: collection_name seems unnecessary --CW

    """
    splits = [] #will return this list
    print "calculating unsharded splits"

    # TODO: pass these fields VV as parameters? (02/26/12, 11:30, AFlock)
    '''
    connection = getConnection(uri)
    db = getDatabase(uri)
    coll = db[config.get('collection_name')]
    '''
    coll = getCollection(uri)

    q = {} if not "query" in config else config.get("query")

    print 'in unsharded splits'
    #print 'query in MongoSplitter is ' + q
    #for key in q:
        #print 'am I printing the query?'
        #print q[key]

    #create command
    #command to split should look like this VV
    #SON([('splitVector', u'test.test_data'), ('maxChunkSize', 2), ('force', False), ('keyPattern', {'x': 1})])
    split_key = config.get('splitKey')
    split_size = config.get('splitSize')
    full_name  = coll.full_name
    logging.info("Calculating unsharded splits on collection %s with Split Key %s" % (full_name, split_key))
    logging.info("Max split size :: %sMB" % split_size)

    cmd = bson.son.SON()
    cmd["splitVector"]  = full_name
    cmd["maxChunkSize"] = split_size
    cmd["keyPattern"]   = split_key
    cmd["force"]        = True

    logging.debug("Issuing Command: %s" % cmd)
    print "Issuing Command: %s" % cmd
    data = coll.database.command(cmd)
    print data

    #results look like this VV
    #{u'ok': 1.0, u'splitKeys': [{u'_id': ObjectId('4f49775348d9846c5e582b00')}, {u'_id': ObjectId('4f49775548d9846c5e58553b')}]}

    if data.get("err"):
        raise Exception(data.get("err"))
    elif data.get("ok") != 1.0:
        print data
        raise Exception("Unable to calculate splits")

    split_data = data.get('splitKeys')
    if not split_data:
        logging.warning("WARNING: No Input Splits were calculated by the split code.  Proceeding with a *single* split. Data may be too small, try lowering 'mongo.input.split_size'  if this is undesirable.")
    else:
        logging.info("Calculated %s splits" % len(split_data))

        # TODO: what is the query q parameter? (02/26/12, 12:18, AFlock)
        last_key = None
        for bound in split_data:
            splits.append(_split(config, q, last_key, bound))
            last_key = bound
        splits.append(_split(config, q, last_key, None))

    return [s.format_uri_with_query() for s in splits]

def _split(config=None, q={}, min=None, max=None):
    """@todo: Docstring for _split
    :returns: an actual MongoSplit object
    """
    print "_split being created"
    query = bson.son.SON()
    query["$query"]  = q

    if min:
        query["$min"] = min

    if max:
        query["$max"] = max

    logging.info("Assembled Query: " , query)

    return MongoInputSplit(
            config.get("inputURI"),
            config.get("inputKey"),
            query,
            config.get("fields"),
            config.get("sort"),
            config.get("limit", 0),
            config.get("skip", 0),
            config.get("timeout", True))

def calculate_single_split(config):
    #splits = [None] * 1 #will return this list's URI
    splits = []
    print "calculating single split"

    splits.append(MongoInputSplit(
            config.get("inputURI"),
            config.get("inputKey"),
            query,
            config.get("fields"),
            config.get("sort"),
            config.get("limit", 0),
            config.get("skip", 0),
            config.get("timeout", True)))

    logging.debug("Calculated %d split objects"% len(splits) )
    logging.debug("Dump of calculated splits ... ")
    for s in splits:
        logging.debug("    Split: %s"% split)
    return [s.format_uri_with_query() for s in splits]
#pass

def calculate_sharded_splits(config, useShards, useChunks, slaveOk, uri):
    """Worry about this after unsharded splits are doen

    :returns: @todo
    """
    splits = []
    if useChunks:
        splits = fetch_splits_via_chunks(config, uri, useShards, slaveOk)
    elif useShards:
        logging.warn("Fetching Input Splits directly from shards is potentially dangerous for data consistency should migrations occur during the retrieval.")
        splits = fetch_splits_from_shards(config, uri, slaveOk)
    else:
        logging.error("Neither useChunks nor useShards enabled; failed to pick a valid state.")

    if splits == None:
        logging.error("Failed to create/calculate Input Splits from Shard Chunks; final splits content is 'None'." )

    logging.debug("Calculated splits and returning them - splits: ", splits)
    return splits

def fetch_splits_from_shards(config, uri, slaveOk):
    """@todo: Docstring for fetch_splits_from_shards

    :returns: @todo
    """
    logging.warn("WARNING getting splits that connect directly to the backend mongods is risky and might not produce correct results")
    connection = getConnection(uri)

    configDB = connection["config"]
    shardsColl = configDB["shards"]

    shardSet = set()
    cur = shardsColl.find()

    try:
        for row in cur:
            host = row.get('host')
            slashIndex = host.find("/")
            if slashIndex > 0:
                host = host[slashIndex+1:]
            shardSet.append(host)
    finally:
        if cur != None:
            cur.close()
        cur = None

    splits = []
    for host in shardSet:
        splits.append(MongoInputSplit(config.get("inputURI"),
                config.get("inputKey"),
                config.get("query"),
                config.get("fields"),
                config.get("sort"),
                config.get("limit", 0),
                config.get("skip", 0),
                config.get("timeout", True)))

    return [s.format_uri_with_query() for s in splits]

def fetch_splits_via_chunks(config, uri, useShards, slaveOk):
    """@todo: Docstring for fetch_splits_via_chunks

    :returns: @todo
    """
    originalQuery = config.get("query")
    if useShards:
        logging.warn("WARNING getting splits that connect directly to the backend mongods is risky and might not produce correct results" )

    logging.debug("fetch_splits_via_chunks: originalQuery: %s"% originalQuery)

    connection = getConnection(uri)

    configDB = connection["config"]

    shardMap = {}

    if useShards:
        shardsColl = db[config.get("shards")]
        cur = shardsColl.find()

        try:
            for row in cur:
                host = row.get('host')
                slashIndex = host.find("/")
                if slashIndex > 0:
                    host = host[slashIndex+1:]
                shardMap[row.get('_id')] = host
        finally:
            if cur != None:
                cur.close()

    logging.debug( "MongoInputFormat.getSplitsUsingChunks(): shard map is: %s"% shardMap )

    chunksCollection = db[config.get("chunks")]
    query = bson.son.SON()
    db = connection[config['db_name']]
    query["$ns"] = db + "." + db[config['collection_name']]

    cur = chunksCollection.find(query)

    try:
        numChunks = 0
        numExpectedChunks = len(cur)

        splits = []

        for row in cur:
            numChunks += 1
            minObj = row.get('min')
            shardKeyQuery = bson.son.SON()
            min = bson.son.SON()
            max = bson.son.SON()

            for key in minObj:
                tMin = minObj[key]
                tMax = (row.get('max'))[key]
    #if (The splitFriendyDBCallBack calls here!!!!)
	#
	#
	#
            if originalQuery == None:
                originalQuery = bson.son.SON()

            shardKeyQuery["$min"] = min
            shardKeyQuery["$max"] = max
            shardKeyQuery["$query"] = originalQuery

            logging.debug("["+numChunks+"/"+numExpectedChunks+"] new query is: "+shardKeyQuery)

            inputURI = config.get("inputURI")

            if useShards:
                shardName = row.get('shard')
                host = shardMap[shardName]
               #inputURI = new URI??

            splits.append(MongoInputSplit(
                config.get("inputURI"),
                config.get("inputKey"),
                config.get("query"),
                config.get("fields"),
                config.get("sort"),
                config.get("limit", 0),
                config.get("skip", 0),
                config.get("timeout", True)))

        logging.debug("MongoInputFormat.fetch_splits_via_chunks(): There were %d chunks, returning %d splits: %s"%(numChunks, len(splits), splits))

        return [s.format_uri_with_query() for s in splits]

    finally:
        if cur != None:
            cur.close()

'''
def get_new_URI(original_URI, new_URI, slave_OK):
    """@todo: Docstring for get_new_URI

    :original_URI: @todo
    :etc: @todo
    :returns: a new Mongo_URI
    """

#    pass
    orig_URI_string = SCHEME_LEN
    server_end = -1
    server_start = 0

    """to find the last index of / in the original URI string """
    idx = orig_URI_string[::-1].find("/")
    if idx < 0:
        server_end = len(orig_URI_string)
    else:
        server_end = idx

    idx = orig_URI_string.find("@")

    if idx > 0:
        server_start = idx + 1

    sb = orig_URI_string
    sb.replace(orig_URI_string[server_start:server_end], new_URI)
    if slave_OK != null:
        if "?" in orig_URI_string:
            sb.append("&slaveok=").append(slave_OK)
        else
            sb.append("?slaveok=").append(slave_OK)

    ans = SCHEME + sb
    logging.debug("get_new_URI(): original " + original_URI + " new uri: " + ans )
    return ans
'''
<|endoftext|>


<commit_before># Python Security Project (PySec) and its related class files.
#
# PySec is a set of tools for secure application development under Linux
#
# Copyright 2014 PySec development team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from itertools import izip_longest, islice
import operator
import heapq

def absjoinpath(*parts):
    return os.path.abspath(os.path.join(*parts))

def path_split(path):
    parts = []
    pre, post = os.path.split(os.path.normpath(str(path)))
    if not pre:
        return [post]
    while post:
        parts.append(post)
        pre, post = os.path.split(os.path.normpath(str(pre)))
    if pre:
        parts.append(pre)
    return reversed(parts)

def is_subpath(path1, path2):
    """Returns:
        0   if path2 is not in directory path1
        1   if path2 is equal to path1
        2   if path2 is in directory path1
    """
    for p1, p2 in izip_longest(path_split(str(path1)),
                               path_split(str(path2)), fillvalue=None):
        if p1 is None and p2 is None:
            return 1
        elif p1 is None:
            return 2
        elif p2 is None:
            return 0
        if p1 != p2:
            return 0
    return 1

def subtract_path(prefix, path):
    pre = []
    post = []
    zl = izip_longest(path_split(str(prefix)), path_split(str(path)),
                      fillvalue=None)
    for p1, p2 in zl:
        if p1 is None and p2 is None:
            break
        elif p1 == p2:
            pre.append(p1)
        else:
            post.append(p2)
            break
    for _, p2 in zl:
        post.append(p2)
    return os.path.join(*pre), os.path.join(*post)

def xrange(start, stop, step=1):
    n = int(start)
    stop = int(stop)
    step = int(step)
    if step < 0:
        start, stop = stop, start
        bcmp = operator.gt
    elif step > 0:
        bcmp = operator.lt
    else:
        raise StopIteration
    while bcmp(n, stop):
        yield n
        n += step

def top_n(values, n=10):
    values = iter(values)
    top = [val for val in islice(values, n)]
    if len(top) < n:
        return top
    heapq.heapify(top)
    for val in values:
        heapq.heappushpop(top, val)
    return top
<commit_msg>add docs and change short names<commit_after># Python Security Project (PySec) and its related class files.
#
# PySec is a set of tools for secure application development under Linux
#
# Copyright 2014 PySec development team
#
# 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.
"""A lot of utilies for:
    - Operations on paths
    - Counting
"""
import os
from itertools import izip_longest, islice
import operator
import heapq

def absjoinpath(*parts):
    """Joins all path's parts and returns the absolute path"""
    return os.path.abspath(os.path.join(*parts))

def path_split(path):
    """Returns all the directories that constitute the full path"""
    parts = []
    pre, post = os.path.split(os.path.normpath(str(path)))
    if not pre:
        return [post]
    while post:
        parts.append(post)
        pre, post = os.path.split(os.path.normpath(str(pre)))
    if pre:
        parts.append(pre)
    return reversed(parts)

def is_subpath(path1, path2):
    """Returns:
        0   if path2 is not in directory path1
        1   if path2 is equal to path1
        2   if path2 is in directory path1
    """
    for part1, part2 in izip_longest(path_split(str(path1)),
                               path_split(str(path2)), fillvalue=None):
        if part1 is None and part2 is None:
            return 1
        elif part1 is None:
            return 2
        elif part2 is None:
            return 0
        if part1 != part2:
            return 0
    return 1

def subtract_path(prefix, path):
    """Remove prefix path from path"""
    pre = []
    post = []
    couples = izip_longest(path_split(str(prefix)), path_split(str(path)),
                      fillvalue=None)
    for part1, part2 in couples:
        if part1 is None and part2 is None:
            break
        elif part1 == part2:
            pre.append(part1)
        else:
            post.append(part2)
            break
    for _, part2 in couples:
        post.append(part2)
    return os.path.join(*pre), os.path.join(*post)

def xrange(start, stop, step=1):
    """This xrange use python's integers and have not limits of
    machine integers."""
    act = int(start)
    stop = int(stop)
    step = int(step)
    if step < 0:
        start, stop = stop, start
        bcmp = operator.gt
    elif step > 0:
        bcmp = operator.lt
    else:
        raise StopIteration
    while bcmp(act, stop):
        yield act
        act += step

def top_n(values, first_n=10):
    """Returns the *n* greatest objects in values"""
    values = iter(values)
    top = [val for val in islice(values, first_n)]
    if len(top) < first_n:
        return top
    heapq.heapify(top)
    for val in values:
        heapq.heappushpop(top, val)
    return top
<|endoftext|>


<commit_before># Generated by Django 2.1.1 on 2018-11-04 22:37

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields

class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('languages', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('conferences', '0008_auto_20181104_2234'),
    ]

    operations = [
        migrations.CreateModel(
            name='Talk',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
                ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
                ('title', models.CharField(max_length=100, verbose_name='title')),
                ('abstract', models.TextField(max_length=1000, verbose_name='abstract')),
                ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='conferences.Conference', verbose_name='conference')),
                ('language', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='languages.Language', verbose_name='language')),
                ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='talks', to=settings.AUTH_USER_MODEL, verbose_name='owner')),
                ('topic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='conferences.Topic', verbose_name='topic')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]
<commit_msg>Reset migrations<commit_after># Generated by Django 2.1.1 on 2018-11-10 19:19

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields

class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('languages', '0001_initial'),
        ('conferences', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Talk',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
                ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
                ('title', models.CharField(max_length=100, verbose_name='title')),
                ('abstract', models.TextField(max_length=1000, verbose_name='abstract')),
                ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='conferences.Conference', verbose_name='conference')),
                ('language', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='languages.Language', verbose_name='language')),
                ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='talks', to=settings.AUTH_USER_MODEL, verbose_name='owner')),
                ('topic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='conferences.Topic', verbose_name='topic')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]
<|endoftext|>


<commit_before>#!/usr/bin/python3
VERSION = '1.0.0'

"""The ok.py script runs tests, checks for updates, and saves your work.

Common uses:
  python3 ok.py          Run unlocked tests (and save your work).
  python3 ok.py -u       Unlock new tests interactively.
  python3 ok.py -h       Display full help documentation.

This script will search the current directory for test files. Make sure that
ok.py appears in the same directory as the assignment you wish to test.
Otherwise, use -t to specify a test file manually.
"""

# TODO(denero) Add mechanism for removing DEVELOPER INSTRUCTIONS.
DEVELOPER_INSTRUCTIONS = """

This multi-line string contains instructions for developers. It is removed
when the client is distributed to students.

This file is responsible for coordinating all communication with the ok-server.
Students should never need to modify this file.

Local and remote interactions are encapsulated as protocols.
Contributors should do the following to add a protocol to this autograder:

    1- Extend the Protocol class and implement on_start and on_interact.
    2- Add the classname of your protocol to the "protocols" list.
    3- If your protocol needs command line arguments, change parse_input.

A standard protocol lifecycle has only one round-trip communication with the
server, processed by the on_start method. If other interactions are required
outside of this lifecycle, the send_to_server function can be used to send and
receive information from the server outside of the default times. Such
communications should be limited to the body of an on_interact method.
"""

from auth import authenticate
from models import core
from urllib import request, error
import argparse
import config
import exceptions
import importlib.machinery
import json
import os
import sys
import utils
import multiprocessing
import base64
import time

def send_to_server(access_token, messages, assignment, server, endpoint='submission'):
    """Send messages to server, along with user authentication."""
    data = {
        'assignment': assignment['name'],
        'messages': messages,
    }
    try:
        address = 'https://' + server + '/api/v1/' + endpoint
        serialized = json.dumps(data).encode(encoding='utf-8')
        # TODO(denero) Wrap in timeout (maybe use PR #51 timed execution).
        # TODO(denero) Send access token with the request
        address += "?access_token=%s&client_version=%s" % (access_token, VERSION)
        req = request.Request(address)
        req.add_header("Content-Type", "application/json")
        response = request.urlopen(req, serialized)
        return json.loads(response.read().decode('utf-8'))
    except error.HTTPError as ex:
        # print("Error while sending to server: {}".format(ex))
        try:
            #response_json = json.loads(response)
            if ex.code == 403:
                get_latest_version(server)
            #message = response_json['message']
            #indented = '\n'.join('\t' + line for line in message.split('\n'))
            #print(indented)
            return {}
        except Exception as e:
            # print(e)
            # print("Couldn't connect to server")
            pass

######################
# Assignment loading #
######################

INFO_FILE = 'info.py'

def load_tests(test_dir, case_map):
    """Loads information and tests for the current assignment.

    PARAMETERS:
    test_dir -- str; a filepath to the test directory, 'tests' by default.
    case_map -- dict; a mapping of TestCase tags to TestCase classes

    RETURNS:
    assignment -- Assignment; contains information related to the
    assignment and its tests.
    """
    if not os.path.isdir(test_dir):
        raise exceptions.OkException(
                'Assignment must have a {} directory'.format(test_dir))
    info_file = os.path.join(test_dir, INFO_FILE)
    if not os.path.isfile(info_file):
        raise exceptions.OkException(
                'Directory {} must have a file called {}'.format(
                    test_dir, INFO_FILE))
    assignment = _get_info(info_file)
    _get_tests(test_dir, assignment, case_map)
    return assignment

def _get_info(filepath):
    """Loads information from an INFO file, given by the filepath.

    PARAMETERS:
    filepath -- str; filepath to an INFO file.

    RETURNS:
    dict; information contained in the INFO file.
    """
    # TODO(albert): add error handling in case no attribute info is
    # found.
    info_json = _import_module(filepath).info
    return core.Assignment.deserialize(info_json)

def _get_tests(directory, assignment, case_map):
    """Loads all tests in a tests directory and adds them to the given
    Assignment object.

    PARAMETER:
    directory  -- str; filepath to a directory that contains tests.
    assignment -- Assignment; top-level information about the
                  assignment, extracted from the info file.
    """
    test_files = os.listdir(directory)
    # TODO(albert): have a better way to sort tests.
    for file in sorted(test_files):
        if file == INFO_FILE or not file.endswith('.py'):
            continue
        path = os.path.normpath(os.path.join(directory, file))
        if os.path.isfile(path):
            try:
                test_json = _import_module(path).test
                test = core.Test.deserialize(test_json, assignment, case_map)
                assignment.add_test(test)
            except AttributeError as ex:
                # TODO(soumya): Do something here, but only for staff protocols.
                pass

def _import_module(path):
    """Attempt to load the source file at path. Returns None on failure."""
    loader = importlib.machinery.SourceFileLoader(path, path)
    test_module = loader.load_module()
    return test_module

######################
# Assignment dumping #
######################

def dump_tests(test_dir, assignment):
    """Writes an assignment into the given test directory.

    PARAMETERS:
    test_dir   -- str; filepath to the assignment's test directory.
    assignment -- dict; contains information, including Test objects,
                  for an assignment.
    """
    # TODO(albert): prettyify string formatting by using triple quotes.
    # TODO(albert): verify that assign_copy is serializable into json.
    info = utils.prettyformat(assignment.serialize())
    with open(os.path.join(test_dir, INFO_FILE), 'w') as f:
        f.write('info = ' + info)

    # TODO(albert): writing causes an error halfway, the tests
    # directory may be left in a corrupted state.
    # TODO(albert): might need to delete obsolete test files too.
    # TODO(albert): verify that test_json is serializable into json.
    for test in assignment.tests:
        test_json = utils.prettyformat(test.serialize())
        with open(os.path.join(test_dir, test.name + '.py'), 'w') as f:
            f.write('test = ' + test_json)

#####################
# Software Updating #
#####################

def get_latest_version(server):
    """Check for the latest version of ok and update this file accordingly.
    """
    print("We detected that you are running an old version of ok.py: {0}".format(VERSION))

    # Get server version
    address = "https://" + server + "/api/v1" + "/version?name=okpy"

    try:
        print("Updating now...")
        req = request.Request(address)
        response = request.urlopen(req)

        full_response = json.loads(response.read().decode('utf-8'))

        file_contents = base64.b64decode(full_response['data']['results'][0]['file_data'])
        new_file = open('ok', 'wb')
        new_file.write(file_contents)
        new_file.close()
        print("Done updating!")
    except error.HTTPError as ex:
        # print("Error when downloading new version")
        pass

##########################
# Command-line Interface #
##########################

def parse_input():
    """Parses command line input."""
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('-q', '--question', type=str,
                        help="focus on a specific question")
    parser.add_argument('-s', '--server', type=str, default='ok-server.appspot.com',
                        help="server address")
    parser.add_argument('-t', '--tests', metavar='A', default='tests', type=str,
                        help="partial name or path to test file or directory")
    parser.add_argument('-u', '--unlock', action='store_true',
                        help="unlock tests interactively")
    parser.add_argument('-v', '--verbose', action='store_true',
                        help="print more output")
    parser.add_argument('-i', '--interactive', action='store_true',
                        help="toggles interactive mode")
    parser.add_argument('-l', '--lock', type=str,
                        help="partial name or path to test file or directory to lock")
    parser.add_argument('-f', '--force', action='store_true',
                        help="Forces a server response regardless of how long it takes")
    return parser.parse_args()

def ok_main(args):
    """Run all relevant aspects of ok.py."""
    timer_thread = multiprocessing.Process(target=lambda: time.sleep(0.8), args=())
    print("You are running version {0} of ok.py".format(VERSION))
    timer_thread.start()
    assignment = load_tests(args.tests, config.cases)

    # TODO(soumya): uncomment this once ok.py is ready to ship, to hide
    # error messages.
    # try:
    #     assignment = load_tests(args.tests, config.cases)
    # except Exception as ex:
    #     print(ex)
    #     sys.exit(1)

    logger = sys.stdout = utils.OutputLogger()

    start_protocols = \
        [p(args, assignment, logger) for p in config.protocols.values()]
    interact_protocols = \
        [p(args, assignment, logger) for p in config.protocols.values()]

    messages = dict()

    for protocol in start_protocols:
        messages[protocol.name] = protocol.on_start()

    try:
        access_token = authenticate()
        server_thread = multiprocessing.Process(target=send_to_server, args=(access_token, messages, assignment, args.server))
        server_thread.start()
    except error.URLError as ex:
        # TODO(soumya) Make a better error message
        # print("Nothing was sent to the server!")
        pass

    for protocol in interact_protocols:
        protocol.on_interact()

    # TODO(denero) Print server responses.

    # TODO(albert): a premature error might prevent tests from being
    # dumped. Perhaps add this in a "finally" clause.
    dump_tests(args.tests, assignment)

    while timer_thread.is_alive():
        pass

    if not args.force:
        server_thread.terminate()

if __name__ == '__main__':
    ok_main(parse_input())
<commit_msg>Remove print statements from updating code<commit_after>#!/usr/bin/python3
VERSION = '1.0.0'

"""The ok.py script runs tests, checks for updates, and saves your work.

Common uses:
  python3 ok.py          Run unlocked tests (and save your work).
  python3 ok.py -u       Unlock new tests interactively.
  python3 ok.py -h       Display full help documentation.

This script will search the current directory for test files. Make sure that
ok.py appears in the same directory as the assignment you wish to test.
Otherwise, use -t to specify a test file manually.
"""

# TODO(denero) Add mechanism for removing DEVELOPER INSTRUCTIONS.
DEVELOPER_INSTRUCTIONS = """

This multi-line string contains instructions for developers. It is removed
when the client is distributed to students.

This file is responsible for coordinating all communication with the ok-server.
Students should never need to modify this file.

Local and remote interactions are encapsulated as protocols.
Contributors should do the following to add a protocol to this autograder:

    1- Extend the Protocol class and implement on_start and on_interact.
    2- Add the classname of your protocol to the "protocols" list.
    3- If your protocol needs command line arguments, change parse_input.

A standard protocol lifecycle has only one round-trip communication with the
server, processed by the on_start method. If other interactions are required
outside of this lifecycle, the send_to_server function can be used to send and
receive information from the server outside of the default times. Such
communications should be limited to the body of an on_interact method.
"""

from auth import authenticate
from models import core
from urllib import request, error
import argparse
import config
import exceptions
import importlib.machinery
import json
import os
import sys
import utils
import multiprocessing
import base64
import time

def send_to_server(access_token, messages, assignment, server, endpoint='submission'):
    """Send messages to server, along with user authentication."""
    data = {
        'assignment': assignment['name'],
        'messages': messages,
    }
    try:
        address = 'https://' + server + '/api/v1/' + endpoint
        serialized = json.dumps(data).encode(encoding='utf-8')
        # TODO(denero) Wrap in timeout (maybe use PR #51 timed execution).
        # TODO(denero) Send access token with the request
        address += "?access_token=%s&client_version=%s" % (access_token, VERSION)
        req = request.Request(address)
        req.add_header("Content-Type", "application/json")
        response = request.urlopen(req, serialized)
        return json.loads(response.read().decode('utf-8'))
    except error.HTTPError as ex:
        # print("Error while sending to server: {}".format(ex))
        try:
            #response_json = json.loads(response)
            if ex.code == 403:
                get_latest_version(server)
            #message = response_json['message']
            #indented = '\n'.join('\t' + line for line in message.split('\n'))
            #print(indented)
            return {}
        except Exception as e:
            # print(e)
            # print("Couldn't connect to server")
            pass

######################
# Assignment loading #
######################

INFO_FILE = 'info.py'

def load_tests(test_dir, case_map):
    """Loads information and tests for the current assignment.

    PARAMETERS:
    test_dir -- str; a filepath to the test directory, 'tests' by default.
    case_map -- dict; a mapping of TestCase tags to TestCase classes

    RETURNS:
    assignment -- Assignment; contains information related to the
    assignment and its tests.
    """
    if not os.path.isdir(test_dir):
        raise exceptions.OkException(
                'Assignment must have a {} directory'.format(test_dir))
    info_file = os.path.join(test_dir, INFO_FILE)
    if not os.path.isfile(info_file):
        raise exceptions.OkException(
                'Directory {} must have a file called {}'.format(
                    test_dir, INFO_FILE))
    assignment = _get_info(info_file)
    _get_tests(test_dir, assignment, case_map)
    return assignment

def _get_info(filepath):
    """Loads information from an INFO file, given by the filepath.

    PARAMETERS:
    filepath -- str; filepath to an INFO file.

    RETURNS:
    dict; information contained in the INFO file.
    """
    # TODO(albert): add error handling in case no attribute info is
    # found.
    info_json = _import_module(filepath).info
    return core.Assignment.deserialize(info_json)

def _get_tests(directory, assignment, case_map):
    """Loads all tests in a tests directory and adds them to the given
    Assignment object.

    PARAMETER:
    directory  -- str; filepath to a directory that contains tests.
    assignment -- Assignment; top-level information about the
                  assignment, extracted from the info file.
    """
    test_files = os.listdir(directory)
    # TODO(albert): have a better way to sort tests.
    for file in sorted(test_files):
        if file == INFO_FILE or not file.endswith('.py'):
            continue
        path = os.path.normpath(os.path.join(directory, file))
        if os.path.isfile(path):
            try:
                test_json = _import_module(path).test
                test = core.Test.deserialize(test_json, assignment, case_map)
                assignment.add_test(test)
            except AttributeError as ex:
                # TODO(soumya): Do something here, but only for staff protocols.
                pass

def _import_module(path):
    """Attempt to load the source file at path. Returns None on failure."""
    loader = importlib.machinery.SourceFileLoader(path, path)
    test_module = loader.load_module()
    return test_module

######################
# Assignment dumping #
######################

def dump_tests(test_dir, assignment):
    """Writes an assignment into the given test directory.

    PARAMETERS:
    test_dir   -- str; filepath to the assignment's test directory.
    assignment -- dict; contains information, including Test objects,
                  for an assignment.
    """
    # TODO(albert): prettyify string formatting by using triple quotes.
    # TODO(albert): verify that assign_copy is serializable into json.
    info = utils.prettyformat(assignment.serialize())
    with open(os.path.join(test_dir, INFO_FILE), 'w') as f:
        f.write('info = ' + info)

    # TODO(albert): writing causes an error halfway, the tests
    # directory may be left in a corrupted state.
    # TODO(albert): might need to delete obsolete test files too.
    # TODO(albert): verify that test_json is serializable into json.
    for test in assignment.tests:
        test_json = utils.prettyformat(test.serialize())
        with open(os.path.join(test_dir, test.name + '.py'), 'w') as f:
            f.write('test = ' + test_json)

#####################
# Software Updating #
#####################

def get_latest_version(server):
    """Check for the latest version of ok and update this file accordingly.
    """
    #print("We detected that you are running an old version of ok.py: {0}".format(VERSION))

    # Get server version
    address = "https://" + server + "/api/v1" + "/version?name=okpy"

    try:
        #print("Updating now...")
        req = request.Request(address)
        response = request.urlopen(req)

        full_response = json.loads(response.read().decode('utf-8'))

        file_contents = base64.b64decode(full_response['data']['results'][0]['file_data'])
        new_file = open('ok', 'wb')
        new_file.write(file_contents)
        new_file.close()
        #print("Done updating!")
    except error.HTTPError as ex:
        # print("Error when downloading new version")
        pass

##########################
# Command-line Interface #
##########################

def parse_input():
    """Parses command line input."""
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('-q', '--question', type=str,
                        help="focus on a specific question")
    parser.add_argument('-s', '--server', type=str, default='ok-server.appspot.com',
                        help="server address")
    parser.add_argument('-t', '--tests', metavar='A', default='tests', type=str,
                        help="partial name or path to test file or directory")
    parser.add_argument('-u', '--unlock', action='store_true',
                        help="unlock tests interactively")
    parser.add_argument('-v', '--verbose', action='store_true',
                        help="print more output")
    parser.add_argument('-i', '--interactive', action='store_true',
                        help="toggles interactive mode")
    parser.add_argument('-l', '--lock', type=str,
                        help="partial name or path to test file or directory to lock")
    parser.add_argument('-f', '--force', action='store_true',
                        help="Forces a server response regardless of how long it takes")
    return parser.parse_args()

def ok_main(args):
    """Run all relevant aspects of ok.py."""
    timer_thread = multiprocessing.Process(target=lambda: time.sleep(0.8), args=())
    print("You are running version {0} of ok.py".format(VERSION))
    timer_thread.start()
    assignment = load_tests(args.tests, config.cases)

    # TODO(soumya): uncomment this once ok.py is ready to ship, to hide
    # error messages.
    # try:
    #     assignment = load_tests(args.tests, config.cases)
    # except Exception as ex:
    #     print(ex)
    #     sys.exit(1)

    logger = sys.stdout = utils.OutputLogger()

    start_protocols = \
        [p(args, assignment, logger) for p in config.protocols.values()]
    interact_protocols = \
        [p(args, assignment, logger) for p in config.protocols.values()]

    messages = dict()

    for protocol in start_protocols:
        messages[protocol.name] = protocol.on_start()

    try:
        access_token = authenticate()
        server_thread = multiprocessing.Process(target=send_to_server, args=(access_token, messages, assignment, args.server))
        server_thread.start()
    except error.URLError as ex:
        # TODO(soumya) Make a better error message
        # print("Nothing was sent to the server!")
        pass

    for protocol in interact_protocols:
        protocol.on_interact()

    # TODO(denero) Print server responses.

    # TODO(albert): a premature error might prevent tests from being
    # dumped. Perhaps add this in a "finally" clause.
    dump_tests(args.tests, assignment)

    while timer_thread.is_alive():
        pass

    if not args.force:
        server_thread.terminate()

if __name__ == '__main__':
    ok_main(parse_input())
<|endoftext|>


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

from glance.policies import base

DEPRECATED_REASON = """
The image API now supports roles.
"""

image_policies = [
    policy.DocumentedRuleDefault(
        name="add_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Create new image',
        operations=[
            {'path': '/v2/images',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="add_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY)
    ),
    policy.DocumentedRuleDefault(
        name="delete_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Deletes the image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'DELETE'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_image",
        check_str=base.ADMIN_OR_PROJECT_READER_GET_IMAGE,
        scope_types=['system', 'project'],
        description='Get specified image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_images",
        check_str=base.ADMIN_OR_PROJECT_READER,
        scope_types=['system', 'project'],
        description='Get all available images',
        operations=[
            {'path': '/v2/images',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_images", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="modify_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Updates given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="modify_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="publicize_image",
        check_str='role:admin',
        scope_types=['system', 'project'],
        description='Publicize given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ]
    ),
    policy.DocumentedRuleDefault(
        name="communitize_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Communitize given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="communitize_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="download_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER_DOWNLOAD_IMAGE,
        scope_types=['system', 'project'],
        description='Downloads given image',
        operations=[
            {'path': '/v2/images/{image_id}/file',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="download_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="upload_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Uploads data to specified image',
        operations=[
            {'path': '/v2/images/{image_id}/file',
             'method': 'PUT'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="upload_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="delete_image_location",
        check_str='role:admin',
        scope_types=['system', 'project'],
        description='Deletes the location of given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_image_location",
        check_str=base.ADMIN_OR_PROJECT_READER,
        scope_types=['system', 'project'],
        description='Reads the location of the image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="set_image_location",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Sets location URI to given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="set_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="add_member",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Create image member',
        operations=[
            {'path': '/v2/images/{image_id}/members',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="add_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="delete_member",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Delete image member',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'DELETE'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_member",
        check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='Show image member details',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_members",
        check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='List image members',
        operations=[
            {'path': '/v2/images/{image_id}/members',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_members", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="modify_member",
        check_str=base.ADMIN_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='Update image member',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'PUT'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="modify_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.RuleDefault(
        name="manage_image_cache",
        check_str='role:admin',
        # NOTE(lbragstad): Remove 'project' from the list below when glance
        # fully supports system-scope and this policy is updated to reflect
        # that in the check string.
        scope_types=['system', 'project'],
        description='Manage image cache'
    ),

    policy.DocumentedRuleDefault(
        name="deactivate",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Deactivate image',
        operations=[
            {'path': '/v2/images/{image_id}/actions/deactivate',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="deactivate", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="reactivate",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Reactivate image',
        operations=[
            {'path': '/v2/images/{image_id}/actions/reactivate',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="reactivate", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="copy_image",
        check_str='role:admin',
        # Eventually, we need to make sure we update the check string here to
        # be scope-aware, but for now this is restricted to system-admins and
        # project-admins. That might change in the future if we decide to push
        # this functionality down to project-members.
        scope_types=['system', 'project'],
        description='Copy existing image to other stores',
        operations=[
            {'path': '/v2/images/{image_id}/import',
             'method': 'POST'}
        ]
    ),
]

def list_rules():
    return image_policies
<commit_msg>trivial: Double quote check_str for consistency<commit_after>#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from oslo_log import versionutils
from oslo_policy import policy

from glance.policies import base

DEPRECATED_REASON = """
The image API now supports roles.
"""

image_policies = [
    policy.DocumentedRuleDefault(
        name="add_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Create new image',
        operations=[
            {'path': '/v2/images',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="add_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY)
    ),
    policy.DocumentedRuleDefault(
        name="delete_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Deletes the image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'DELETE'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_image",
        check_str=base.ADMIN_OR_PROJECT_READER_GET_IMAGE,
        scope_types=['system', 'project'],
        description='Get specified image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_images",
        check_str=base.ADMIN_OR_PROJECT_READER,
        scope_types=['system', 'project'],
        description='Get all available images',
        operations=[
            {'path': '/v2/images',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_images", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="modify_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Updates given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="modify_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="publicize_image",
        check_str='role:admin',
        scope_types=['system', 'project'],
        description='Publicize given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ]
    ),
    policy.DocumentedRuleDefault(
        name="communitize_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Communitize given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="communitize_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="download_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER_DOWNLOAD_IMAGE,
        scope_types=['system', 'project'],
        description='Downloads given image',
        operations=[
            {'path': '/v2/images/{image_id}/file',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="download_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="upload_image",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Uploads data to specified image',
        operations=[
            {'path': '/v2/images/{image_id}/file',
             'method': 'PUT'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="upload_image", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="delete_image_location",
        check_str="role:admin",
        scope_types=['system', 'project'],
        description='Deletes the location of given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_image_location",
        check_str=base.ADMIN_OR_PROJECT_READER,
        scope_types=['system', 'project'],
        description='Reads the location of the image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="set_image_location",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Sets location URI to given image',
        operations=[
            {'path': '/v2/images/{image_id}',
             'method': 'PATCH'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="set_image_location", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="add_member",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Create image member',
        operations=[
            {'path': '/v2/images/{image_id}/members',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="add_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="delete_member",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Delete image member',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'DELETE'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="delete_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_member",
        check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='Show image member details',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="get_members",
        check_str=base.ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='List image members',
        operations=[
            {'path': '/v2/images/{image_id}/members',
             'method': 'GET'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="get_members", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="modify_member",
        check_str=base.ADMIN_OR_SHARED_MEMBER,
        scope_types=['system', 'project'],
        description='Update image member',
        operations=[
            {'path': '/v2/images/{image_id}/members/{member_id}',
             'method': 'PUT'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="modify_member", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.RuleDefault(
        name="manage_image_cache",
        check_str='role:admin',
        # NOTE(lbragstad): Remove 'project' from the list below when glance
        # fully supports system-scope and this policy is updated to reflect
        # that in the check string.
        scope_types=['system', 'project'],
        description='Manage image cache'
    ),

    policy.DocumentedRuleDefault(
        name="deactivate",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Deactivate image',
        operations=[
            {'path': '/v2/images/{image_id}/actions/deactivate',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="deactivate", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),
    policy.DocumentedRuleDefault(
        name="reactivate",
        check_str=base.ADMIN_OR_PROJECT_MEMBER,
        scope_types=['system', 'project'],
        description='Reactivate image',
        operations=[
            {'path': '/v2/images/{image_id}/actions/reactivate',
             'method': 'POST'}
        ],
        deprecated_rule=policy.DeprecatedRule(
            name="reactivate", check_str="rule:default",
            deprecated_reason=DEPRECATED_REASON,
            deprecated_since=versionutils.deprecated.WALLABY),
    ),

    policy.DocumentedRuleDefault(
        name="copy_image",
        check_str='role:admin',
        # Eventually, we need to make sure we update the check string here to
        # be scope-aware, but for now this is restricted to system-admins and
        # project-admins. That might change in the future if we decide to push
        # this functionality down to project-members.
        scope_types=['system', 'project'],
        description='Copy existing image to other stores',
        operations=[
            {'path': '/v2/images/{image_id}/import',
             'method': 'POST'}
        ]
    ),
]

def list_rules():
    return image_policies
<|endoftext|>


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

"""
Created on 21 Aug 2019

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

import time

from scs_dfe.interface.pzhb.pzhb_mcu_t2_f1 import PZHBMCUt2f1

from scs_host.bus.i2c import I2C
from scs_host.sys.host import Host

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

header = PZHBMCUt2f1(PZHBMCUt2f1.DEFAULT_ADDR)
print(header)

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

try:
    I2C.open(Host.I2C_SENSORS)

    ident = header.version_ident()
    print("ident: [%s]" % ident)

    tag = header.version_tag()
    print("tag: [%s]" % tag)

    print("-")

    v_batt = header.read_batt_v()
    print("v_batt: %0.1f V" % v_batt)

    c_current = header.read_current_count()
    print("c_current: %d" % c_current)

    print("-")

    print("LED...")
    on = True

    for _ in range(10):
        header.led1(on)
        on = not on
        time.sleep(2)

    # exit(0)

    print("button...")

    header.button_enable()

    count = 0

    while True:
        time.sleep(1)

        button_pressed = header.button_pressed()

        if button_pressed:
            print("button pressed: %d" % count)
            break

        count += 1

finally:
    I2C.close()
<commit_msg>Changed Praxis LED colour scheme.<commit_after>#!/usr/bin/env python3

"""
Created on 21 Aug 2019

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

import time

from scs_dfe.interface.pzhb.pzhb_mcu_t2_f1 import PZHBMCUt2f1

from scs_host.bus.i2c import I2C
from scs_host.sys.host import Host

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

header = PZHBMCUt2f1(PZHBMCUt2f1.DEFAULT_ADDR)
print(header)

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

try:
    I2C.open(Host.I2C_SENSORS)

    ident = header.version_ident()
    print("ident: [%s]" % ident)

    tag = header.version_tag()
    print("tag: [%s]" % tag)

    print("-")

    v_batt = header.read_batt_v()
    print("v_batt: %0.1f V" % v_batt)

    c_current = header.read_current_count()
    print("c_current: %d" % c_current)

    print("-")

    print("LED...")
    on = True

    for _ in range(10):
        header.led1(on)
        header.led2(on)
        on = not on
        time.sleep(2)

    # exit(0)

    print("button...")

    header.button_enable()

    count = 0

    while True:
        time.sleep(1)

        button_pressed = header.button_pressed()

        if button_pressed:
            print("button pressed: %d" % count)
            break

        count += 1

finally:
    I2C.close()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

import TestSCons

test = TestSCons.TestSCons()

import SCons

if SCons.__version__ == "__VERSION__":

    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
sys.exit(0)
""")

    test.run()

    test.write('SConstruct', """
import sys
EnsurePythonVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

else:
    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
EnsureSConsVersion(0,0)
sys.exit(0)
""")

    test.run()

    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
EnsureSConsVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

    test.write('SConstruct', """
import sys
EnsurePythonVersion(2000,0)
EnsureSConsVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

test.write('SConstruct', """\
import sys
delattr(sys, 'version_info')
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(1,3)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
delattr(sys, 'version_info')
sys.version = '2.3+ (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,2)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
delattr(sys, 'version_info')
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,3)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
delattr(sys, 'version_info')
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,4)
sys.exit(0)
""")

test.run(status=2)

test.pass_test()
<commit_msg>Portability of test/EnsureVersion.py back to pre-Python-2 versions.<commit_after>#!/usr/bin/env python
#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

import TestSCons

test = TestSCons.TestSCons()

import SCons

if SCons.__version__ == "__VERSION__":

    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
sys.exit(0)
""")

    test.run()

    test.write('SConstruct', """
import sys
EnsurePythonVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

else:
    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
EnsureSConsVersion(0,0)
sys.exit(0)
""")

    test.run()

    test.write('SConstruct', """
import sys
EnsurePythonVersion(0,0)
EnsureSConsVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

    test.write('SConstruct', """
import sys
EnsurePythonVersion(2000,0)
EnsureSConsVersion(2000,0)
sys.exit(0)
""")

    test.run(status=2)

test.write('SConstruct', """\
import sys
try:
    delattr(sys, 'version_info')
except AttributeError:
    pass
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(1,3)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
try:
    delattr(sys, 'version_info')
except AttributeError:
    pass
sys.version = '2.3+ (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,2)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
try:
    delattr(sys, 'version_info')
except AttributeError:
    pass
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,3)
sys.exit(0)
""")

test.run()

test.write('SConstruct', """\
import sys
try:
    delattr(sys, 'version_info')
except AttributeError:
    pass
sys.version = '2.3b1 (#0, Feb 24 2003, 19:13:11)\\n'
EnsurePythonVersion(2,4)
sys.exit(0)
""")

test.run(status=2)

test.pass_test()
<|endoftext|>