<commit_before>#room base
class Room():
    '''
    models abstract data type Room, not intended to be instanciated
    '''
    #keep track of all rooms created
    number_of_rooms = 0

    def __init__(self, max_occupants, name):
        '''
        return Room with no occupats
        '''
        Room.number_of_rooms += 1
        self.__name = name
        self.__max_occupants = max_occupants
        self.__occupants = []
        self.__id = Room.number_of_rooms

    @property
    def id(self):
        '''
        return id, unique identifier for room
        '''
        return self.__id

    @property
    def name(self):
        '''
        property name, return name for room
        '''
        return self.__name

    @name.setter
    def name(self, new_name):
        '''
        setter: set's name for room
        '''
        self.__name = new_name

    @property
    def max_occupants(self):
        return self.__max_occupants

    @property
    def current_population(self):
        '''
        return number of ppl in room
        '''
        return len(self.__occupants)

    def is_full(self):
        '''
        return True if room is full, else false
        '''
        return len(self.__occupants) == Room.max_occupants

    def is_in_room(self, person):
        '''
        returns true if person in room_name
        '''
        return person in self.__occupants

    def add_occupant(self, person):
        '''
        adds person to room_name
        '''
        if self.current_population == self.max_occupants:
            pass
            #raise full error
        if not self.is_in_room(person):
            self.__occupants.append(person)

        #raise some error

    def remove_occupant(self, person):
        '''
        removes person from room
        '''
        if self.is_in_room(person):
            del self.__occupants[self.__occupants.index(person)]
        #raise some error
    def get_occupants(self):
        '''
        returns a generator with all occupants
        '''
        occupants = self.__occupants[:]
        def occupants():
            for person in occupants:
                yield person
        return occupants()

#create a Office
class Office(Room):
    """
    input name -> string
    models Offices space
    """
    #number of offices a
    number_of_offices = 0

    max_occupants = 6
    def __init__(self, name):
        Office.number_of_offices += 1
        Room.__init__(self, Office.max_occupants, name)

#create a LivingSpace
class LivingSpace(Room):
    """
    input : name -> string
    models a LivingSpace
    """
    #number of LivingSpaces
    number_of_livingspace = 0

    max_occupants = 4
    def __init__(self, name):
        LivingSpace.number_of_livingspace += 1
        Room.__init__(self, LivingSpace.max_occupants, name)

################################################################################
class Dojo():
    """
    input name -> string
    models Dojo facillity
    """
    facillity_names = []
    def __init__(self, name):
        if type(name) != type("str"):
            raise TypeError

        if name in Dojo.facillity_names:
            raise DuplicateError

        self.__cleaned_name = self.clean_name(name)

        if not self.__cleaned_name:
            raise TypeError

        self.__number_rooms = 0
        self.__number_office = 0
        self.__number_livingspace = 0
        self.__rooms = {'offices' : [], 'livingspace' : []}
        self.__person = {'fellow' : [], 'staff' : []}
        self.__name = name
        Dojo.facillity_names.append(self.__cleaned_name)

    #validate name
    def clean_name(self, name):
        clean_name = ''
        name_stripped = name.split()
        if len(name_stripped) == 0:
            return ''

        cleaned_name = name_stripped[0]

        #check for atleat one letter

        if cleaned_name:
            return cleaned_name

    @property
    def name(self):
        """
        returns name for Dojo
        """
        return self.__name

    @property
    def room(self, room):
        """
        returns a copy  all rooms
        """
        return self.__rooms['offices'] + self.__rooms['livingspace']

    @property
    def office(self):
        """
        returns a copy of all offices
        """
        return self.__rooms['offices'][:]
    @office.setter
    def office(self, new_office):
        """
        Adds new office to dojo
        """
        self.__rooms['offices'].append(new_office)
    @property
    def livingspace(self):
        """
        returns a copy of all the lving space
        """

        return self.__rooms['livingspace'][:]
    @livingspace.setter
    def livingspace(self, new_livingspace):
        """
        Adds new livingspace to the dojo
        """
        self.__rooms['livingspace'].append(new_livingspace)

    @property
    def fellow(self):
        """
        returns a copy of all fellows
        """
        return self.__person['fellow'][:]
    @fellow.setter
    def fellow(self, new_fellow):
        """
        Adds a new fellow to dojo
        """
        self.__person['fellow'].append(new_fellow)
    def is_fellow(self, person):
        """
        returns true if person is fellow @ Dojo else False
        """
        return person in self.__person['fellow']

    @property
    def staff(self):
        """
        returns a copy of the staff
        """
        return self.__person['staff'][:]
    @staff.setter
    def staff(self, new_staff):
        """
        Adds new staff to the Dojo
        """
        self.__person['staff'].append(new_staff)
    def is_staff(self, person):
        """
        returns True if person is staff @ Dojo else false
        """
        return person in self.__person["staff"]

    @property
    def number_of_rooms(self):
        pass
    @property
    def number_of_office(self):
        pass
    @property
    def number_of_livingspace(self):
        pass

    def is_person_in_dojo(self, person):
        """
        returns True if person in Dojo
        """
        pass

    def remove_office(self, old_space):
        """
        Removes Office from the Dojo
        """
        if old_space in self.__rooms['offices']:
            del self.__rooms['offices'][self.__rooms['offices'].index(old_space)]

    def remove_livingspace(self, old_space):
        """
        Removes LivingSpace from the Dojo
        """
        if old_space in self.__rooms['livingspace']:
            del self.__rooms['livingspace'][self.__rooms['livingspace'].index(old_space)]

    def remove_fellow(self, old_fellow):
        """
        Remove Fellow fro the Dojo
        """
        if old_fellow in self.__person['fellow']:
            del self.__person['fellow'][self.__person['fellow'].index(old_fellow)]
    def remove_staff(self, old_staff):
        """
        Remove staff from the Dojo
        """
        if old_staff in self.__person['staff']:
            del self.__person['staff'][self.__person['staff'].index(old_staff)]

#exception throw for duplicates insertions
class DuplicateError(Exception):
    pass

################################################################################
class Person():
    #number of Person
    number_of_person = 0

    def __init__(self, name):
        Person.number_of_person += 1
        self.__id = Person.number_of_person
        self.__name = name
        self.__office = None

    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, new_name):
        self.__name = new_name

    @property
    def id(self):
        return self.__id

    @property
    def office(self):
        return self.__office

    @office.setter
    def office(self, office):
        self.__office = office

    def remove_office(self):
        self.office = None

    def is_allocated_office(self):
        return not (not self.office)

class Fellow(Person):
    #number of fellows
    number_of_fellows = 0

    def __init__(self, name, wants_living = False):
        Fellow.number_of_fellows += 1
        Person.__init__(self, name)
        self.__wants_living = wants_living
        self.__livingspace = None

    def is_allocated_living(self):
        return not not self.__livingspace

    @property
    def wants_living(self):
        return self.__wants_living
    @property
    def livingspace(self):
        return self.__livingspace
    @livingspace.setter
    def livingspace(self, space):
        if self.__wants_living:
            self.__livingspace = space
        #throw value error
    def remove_livingspace(self):
        self.__livingspace = None

class Staff(Person):
    #number of Staff
    number_of_staff = 0
    def __init__(self, name):
        Staff.number_of_staff += 1
        Person.__init__(self, name)
<commit_msg>Chore: refactore model, clean code<commit_after>#room base
class Room():
    '''
    models abstract data type Room, not intended to be instanciated
    '''
    #keep track of all rooms created
    number_of_rooms = 0

    def __init__(self, max_occupants, name):
        '''
        return Room with no occupats
        '''
        Room.number_of_rooms += 1
        self.name = name
        self.__max_occupants = max_occupants
        self.__occupants = []
        self.__id = Room.number_of_rooms

    @property
    def max_occupants(self):
        return self.__max_occupants

    @property
    def current_population(self):
        '''
        return number of ppl in room
        '''
        return len(self.__occupants)

    def is_full(self):
        '''
        return True if room is full, else false
        '''
        return len(self.__occupants) == self.max_occupants

    def is_in_room(self, person):
        '''
        returns true if person in room_name
        '''
        return person in self.__occupants

    def add_occupant(self, person):
        '''
        adds person to room_name
        '''
        if self.current_population == self.max_occupants:
            pass
            #raise full error
        if not self.is_in_room(person):
            self.__occupants.append(person)

        #raise some error

    def remove_occupant(self, person):
        '''
        removes person from room
        '''
        if self.is_in_room(person):
            del self.__occupants[self.__occupants.index(person)]
        #raise some error
    def get_occupants(self):
        '''
        returns a generator with all occupants
        '''
        occupants = self.__occupants[:]
        def occupants():
            for person in occupants:
                yield person
        return occupants()

#create a Office
class Office(Room):
    """
    input name -> string
    models Offices space
    """
    #number of offices a
    number_of_offices = 0

    max_occupants = 6
    def __init__(self, name):
        Office.number_of_offices += 1
        Room.__init__(self, Office.max_occupants, name)

#create a LivingSpace
class LivingSpace(Room):
    """
    input : name -> string
    models a LivingSpace
    """
    #number of LivingSpaces
    number_of_livingspace = 0

    max_occupants = 4
    def __init__(self, name):
        LivingSpace.number_of_livingspace += 1
        Room.__init__(self, LivingSpace.max_occupants, name)

################################################################################
class Dojo():
    """
    input name -> string
    models Dojo facillity
    """
    facillity_names = []
    def __init__(self, name):
        if type(name) != type("str"):
            raise TypeError

        if name in Dojo.facillity_names:
            raise DuplicateError

        self.__cleaned_name = self.clean_name(name)

        if not self.__cleaned_name:
            raise TypeError

        self.__number_rooms = 0
        self.__number_office = 0
        self.__number_livingspace = 0
        self.__rooms = {'offices' : [], 'livingspace' : []}
        self.__person = {'fellow' : [], 'staff' : []}
        self.name = self.__cleaned_name
        Dojo.facillity_names.append(self.__cleaned_name)

    #validate name
    def clean_name(self, name):
        clean_name = ''
        name_stripped = name.split()
        if len(name_stripped) == 0:
            return ''

        cleaned_name = name_stripped[0]

        #check for atleat one letter

        if cleaned_name:
            return cleaned_name

    @property
    def room(self, room):
        """
        returns a copy  all rooms
        """
        return self.__rooms['offices'] + self.__rooms['livingspace']

    @property
    def office(self):
        """
        returns a copy of all offices
        """
        return self.__rooms['offices'][:]
    @office.setter
    def office(self, new_office):
        """
        Adds new office to dojo
        """
        self.__rooms['offices'].append(new_office)
    @property
    def livingspace(self):
        """
        returns a copy of all the lving space
        """

        return self.__rooms['livingspace'][:]
    @livingspace.setter
    def livingspace(self, new_livingspace):
        """
        Adds new livingspace to the dojo
        """
        self.__rooms['livingspace'].append(new_livingspace)

    @property
    def fellow(self):
        """
        returns a copy of all fellows
        """
        return self.__person['fellow'][:]
    @fellow.setter
    def fellow(self, new_fellow):
        """
        Adds a new fellow to dojo
        """
        self.__person['fellow'].append(new_fellow)
    def is_fellow(self, person):
        """
        returns true if person is fellow @ Dojo else False
        """
        return person in self.__person['fellow']

    @property
    def staff(self):
        """
        returns a copy of the staff
        """
        return self.__person['staff'][:]
    @staff.setter
    def staff(self, new_staff):
        """
        Adds new staff to the Dojo
        """
        self.__person['staff'].append(new_staff)
    def is_staff(self, person):
        """
        returns True if person is staff @ Dojo else false
        """
        return person in self.__person["staff"]

    def remove_office(self, old_space):
        """
        Removes Office from the Dojo
        """
        if old_space in self.__rooms['offices']:
            del self.__rooms['offices'][self.__rooms['offices'].index(old_space)]

    def remove_livingspace(self, old_space):
        """
        Removes LivingSpace from the Dojo
        """
        if old_space in self.__rooms['livingspace']:
            del self.__rooms['livingspace'][self.__rooms['livingspace'].index(old_space)]

    def remove_fellow(self, old_fellow):
        """
        Remove Fellow fro the Dojo
        """
        if old_fellow in self.__person['fellow']:
            del self.__person['fellow'][self.__person['fellow'].index(old_fellow)]
    def remove_staff(self, old_staff):
        """
        Remove staff from the Dojo
        """
        if old_staff in self.__person['staff']:
            del self.__person['staff'][self.__person['staff'].index(old_staff)]

#exception throw for duplicates insertions
class DuplicateError(Exception):
    pass

################################################################################
class Person():
    #number of Person
    number_of_person = 0

    def __init__(self, name):
        Person.number_of_person += 1
        self.__id = Person.number_of_person
        self.__name = name
        self.office = None

    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, new_name):
        self.__name = new_name

    @property
    def id(self):
        return self.__id

    def remove_office(self):
        self.office = None

    def is_allocated_office(self):
        return not (not self.office)

class Fellow(Person):
    #number of fellows
    number_of_fellows = 0

    def __init__(self, name, wants_living = False):
        Fellow.number_of_fellows += 1
        Person.__init__(self, name)
        self.wants_living = wants_living
        self.__livingspace = None

    def is_allocated_living(self):
        return not not self.__livingspace

    @property
    def livingspace(self):
        return self.__livingspace
    @livingspace.setter
    def livingspace(self, space):
        if self.wants_living:
            self.__livingspace = space
        #throw value error
    def remove_livingspace(self):
        self.__livingspace = None

class Staff(Person):
    #number of Staff
    number_of_staff = 0
    def __init__(self, name):
        Staff.number_of_staff += 1
        Person.__init__(self, name)
<|endoftext|>


<commit_before>import argparse
from contextlib import contextmanager
import hashlib
import os
from random import Random
import shutil
import sys
import tempfile

import boto
from sqlalchemy import text

from ichnaea.config import read_config
from ichnaea.db import Database
from ichnaea.heka_logging import configure_heka

@contextmanager
def tempdir():
    workdir = tempfile.mkdtemp()
    try:
        yield workdir
    finally:
        shutil.rmtree(workdir)

def export_to_csv(db, filename):
    session = db.session()
    # Order by id to keep a stable ordering.
    stmt = text('select lat, lon from mapstat '
                'order by id limit :l offset :o')

    # Set up a pseudo random generator with a fixed seed to prevent
    # datamap tiles from changing with every generation.
    pseudorandom = Random()
    pseudorandom.seed(42)
    random = pseudorandom.random
    offset = 0
    batch = 200000
    pattern = '%.6f,%.6f\n'

    # export mapstat mysql table as csv to local file
    with open(filename, 'w') as fd:
        while True:
            result = session.execute(stmt.bindparams(o=offset, l=batch))
            rows = result.fetchall()
            result.close()
            if not rows:
                break
            lines = []
            append = lines.append
            for r in rows:
                for i in xrange(5):
                    lat = (r[0] + random()) / 1000.0
                    lon = (r[1] + random()) / 1000.0
                    append(pattern % (lat, lon))
            fd.writelines(lines)
            offset += batch

def upload_to_s3(bucketname, tiles):
    tiles = os.path.abspath(tiles)

    conn = boto.connect_s3()
    bucket = conn.get_bucket(bucketname, validate=False)
    result = {'changed': 0, 'unchanged': 0, 'new': 0}

    def _key(name):
        try:
            return int(name)
        except Exception:
            return -1

    for name in sorted(os.listdir(tiles), key=_key):
        folder = os.path.join(tiles, name)
        if not os.path.isdir(folder):
            continue

        for root, dirs, files in os.walk(folder):
            rel_root = 'tiles/' + root.lstrip(tiles) + '/'
            for f in files:
                if not f.endswith('.png'):
                    continue
                filename = root + os.sep + f
                keyname = rel_root + f
                key = bucket.get_key(keyname)
                changed = True
                if key is not None:
                    if os.path.getsize(filename) != key.size:
                        # do the file sizes match?
                        changed = True
                    else:
                        remote_md5 = key.etag.strip('"')
                        with open(filename, 'rb') as fd:
                            local_md5 = hashlib.md5(fd.read()).hexdigest()
                        if local_md5 == remote_md5:
                            # do the md5/etags match?
                            changed = False
                if changed:
                    if key is None:
                        result['new'] += 1
                        key = boto.s3.key.Key(bucketname)
                        key.key = keyname
                    else:
                        result['changed'] += 1
                    # TODO: activate once tested
                    # set correct metadata, acl, RR storage policy
                    # key.set_contents_from_filename(filename)
                else:
                    result['unchanged'] += 1

    return result

def generate(db, bucketname,
             upload=True, concurrency=2, datamaps='', output=None):
    datamaps_encode = os.path.join(datamaps, 'encode')
    datamaps_enumerate = os.path.join(datamaps, 'enumerate')
    datamaps_render = os.path.join(datamaps, 'render')

    with tempdir() as workdir:
        csv = os.path.join(workdir, 'map.csv')
        export_to_csv(db, csv)

        # create shapefile / quadtree
        shapes = os.path.join(workdir, 'shapes')
        cmd = '{encode} -z15 -o {output} {input}'.format(
            encode=datamaps_encode,
            output=shapes,
            input=csv)
        os.system(cmd)

        # render tiles
        if output:
            tiles = output
        else:
            tiles = os.path.join(workdir, 'tiles')
        cmd = ('{enumerate} -z13 {shapes} | xargs -L1 -P{concurrency} '
               '{render} -o {output} -B 12:0.0379:0.874 -c0088FF -t0 '
               '-O 16:1600:1.5 -G 0.5')
        cmd = cmd.format(
            enumerate=datamaps_enumerate,
            shapes=shapes,
            concurrency=concurrency,
            render=datamaps_render,
            output=tiles)
        os.system(cmd)

        if upload:
            result = upload_to_s3(bucketname, tiles)
            sys.stdout.write('Upload to S3: %s' % result)

def main(argv, _db_master=None, _heka_client=None):
    # run for example via:
    # bin/location_map --create --datamaps=/path/to/datamaps/ \
    #   --output=ichnaea/content/static/tiles/

    parser = argparse.ArgumentParser(
        prog=argv[0], description='Generate and upload datamap tiles.')

    parser.add_argument('--create', action='store_true',
                        help='Create tiles.')
    parser.add_argument('--upload', action='store_true',
                        help='Upload tiles to S3.')
    parser.add_argument('--concurrency', default=2,
                        help='How many concurrent render processes to use?')
    parser.add_argument('--datamaps',
                        help='Directory of the datamaps tools.')
    parser.add_argument('--output',
                        help='Optional directory for local tile output.')

    args = parser.parse_args(argv[1:])

    if args.create:
        conf = read_config()
        db = Database(conf.get('ichnaea', 'db_master'))
        bucketname = conf.get('ichnaea', 's3_assets_bucket').strip('/')
        configure_heka(conf.filename, _heka_client=_heka_client)

        upload = False
        if args.upload:
            upload = bool(args.upload)

        concurrency = 2
        if args.concurrency:
            concurrency = int(args.concurrency)

        datamaps = ''
        if args.datamaps:
            datamaps = os.path.abspath(args.datamaps)

        output = None
        if args.output:
            output = os.path.abspath(args.output)

        generate(db, bucketname,
                 upload=upload,
                 concurrency=concurrency,
                 datamaps=datamaps,
                 output=output)
    else:
        parser.print_help()

def console_entry():  # pragma: no cover
    main(sys.argv)
<commit_msg>Update map tiles upload script to use `bucket.list`.<commit_after>import argparse
from contextlib import contextmanager
import hashlib
import os
from random import Random
import shutil
import sys
import tempfile

import boto
from sqlalchemy import text

from ichnaea.config import read_config
from ichnaea.db import Database
from ichnaea.heka_logging import configure_heka

@contextmanager
def tempdir():
    workdir = tempfile.mkdtemp()
    try:
        yield workdir
    finally:
        shutil.rmtree(workdir)

def export_to_csv(db, filename):
    session = db.session()
    # Order by id to keep a stable ordering.
    stmt = text('select lat, lon from mapstat '
                'order by id limit :l offset :o')

    # Set up a pseudo random generator with a fixed seed to prevent
    # datamap tiles from changing with every generation.
    pseudorandom = Random()
    pseudorandom.seed(42)
    random = pseudorandom.random
    offset = 0
    batch = 200000
    pattern = '%.6f,%.6f\n'

    # export mapstat mysql table as csv to local file
    with open(filename, 'w') as fd:
        while True:
            result = session.execute(stmt.bindparams(o=offset, l=batch))
            rows = result.fetchall()
            result.close()
            if not rows:
                break
            lines = []
            append = lines.append
            for r in rows:
                for i in xrange(5):
                    lat = (r[0] + random()) / 1000.0
                    lon = (r[1] + random()) / 1000.0
                    append(pattern % (lat, lon))
            fd.writelines(lines)
            offset += batch

def upload_to_s3(bucketname, tiles):
    tiles = os.path.abspath(tiles)

    conn = boto.connect_s3()
    bucket = conn.get_bucket(bucketname, validate=False)
    result = {'changed': 0, 'unchanged': 0, 'new': 0}

    def _key(name):
        try:
            return int(name)
        except Exception:
            return -1

    for name in sorted(os.listdir(tiles), key=_key):
        folder = os.path.join(tiles, name)
        if not os.path.isdir(folder):
            continue

        for root, dirs, files in os.walk(folder):
            rel_root = 'tiles/' + root.lstrip(tiles) + '/'
            rel_root_len = len(rel_root)
            filtered_files = [f for f in files if f.endswith('.png')]
            if not filtered_files:
                continue
            # get all the keys
            keys = {}
            for key in bucket.list(prefix=rel_root):
                rel_name = key.name[rel_root_len:]
                keys[rel_name] = key
            for f in filtered_files:
                filename = root + os.sep + f
                keyname = rel_root + f
                key = keys.get(f, None)
                changed = True
                if key is not None:
                    if os.path.getsize(filename) != key.size:
                        # do the file sizes match?
                        changed = True
                    else:
                        remote_md5 = key.etag.strip('"')
                        with open(filename, 'rb') as fd:
                            local_md5 = hashlib.md5(fd.read()).hexdigest()
                        if local_md5 == remote_md5:
                            # do the md5/etags match?
                            changed = False
                if changed:
                    if key is None:
                        result['new'] += 1
                        key = boto.s3.key.Key(bucketname)
                        key.key = keyname
                    else:
                        result['changed'] += 1
                    # TODO: activate once tested
                    # set correct metadata, acl, RR storage policy
                    # key.set_contents_from_filename(filename)
                else:
                    result['unchanged'] += 1

    return result

def generate(db, bucketname,
             upload=True, concurrency=2, datamaps='', output=None):
    datamaps_encode = os.path.join(datamaps, 'encode')
    datamaps_enumerate = os.path.join(datamaps, 'enumerate')
    datamaps_render = os.path.join(datamaps, 'render')

    with tempdir() as workdir:
        csv = os.path.join(workdir, 'map.csv')
        export_to_csv(db, csv)

        # create shapefile / quadtree
        shapes = os.path.join(workdir, 'shapes')
        cmd = '{encode} -z15 -o {output} {input}'.format(
            encode=datamaps_encode,
            output=shapes,
            input=csv)
        os.system(cmd)

        # render tiles
        if output:
            tiles = output
        else:
            tiles = os.path.join(workdir, 'tiles')
        cmd = ('{enumerate} -z13 {shapes} | xargs -L1 -P{concurrency} '
               '{render} -o {output} -B 12:0.0379:0.874 -c0088FF -t0 '
               '-O 16:1600:1.5 -G 0.5')
        cmd = cmd.format(
            enumerate=datamaps_enumerate,
            shapes=shapes,
            concurrency=concurrency,
            render=datamaps_render,
            output=tiles)
        os.system(cmd)

        if upload:
            result = upload_to_s3(bucketname, tiles)
            sys.stdout.write('Upload to S3: %s' % result)

def main(argv, _db_master=None, _heka_client=None):
    # run for example via:
    # bin/location_map --create --datamaps=/path/to/datamaps/ \
    #   --output=ichnaea/content/static/tiles/

    parser = argparse.ArgumentParser(
        prog=argv[0], description='Generate and upload datamap tiles.')

    parser.add_argument('--create', action='store_true',
                        help='Create tiles.')
    parser.add_argument('--upload', action='store_true',
                        help='Upload tiles to S3.')
    parser.add_argument('--concurrency', default=2,
                        help='How many concurrent render processes to use?')
    parser.add_argument('--datamaps',
                        help='Directory of the datamaps tools.')
    parser.add_argument('--output',
                        help='Optional directory for local tile output.')

    args = parser.parse_args(argv[1:])

    if args.create:
        conf = read_config()
        db = Database(conf.get('ichnaea', 'db_master'))
        bucketname = conf.get('ichnaea', 's3_assets_bucket').strip('/')
        configure_heka(conf.filename, _heka_client=_heka_client)

        upload = False
        if args.upload:
            upload = bool(args.upload)

        concurrency = 2
        if args.concurrency:
            concurrency = int(args.concurrency)

        datamaps = ''
        if args.datamaps:
            datamaps = os.path.abspath(args.datamaps)

        output = None
        if args.output:
            output = os.path.abspath(args.output)

        generate(db, bucketname,
                 upload=upload,
                 concurrency=concurrency,
                 datamaps=datamaps,
                 output=output)
    else:
        parser.print_help()

def console_entry():  # pragma: no cover
    main(sys.argv)
<|endoftext|>


<commit_before>from iris.tests.stock import lat_lon_cube

from geoviews.element import Image
from geoviews.element.comparison import ComparisonTestCase
from geoviews.plotting.mpl import GeoImagePlot

class TestGeoImagePlot(ComparisonTestCase):
    def test_auto_guess_bounds(self):
        # Check that the `get_data()` method automatically adds bounds
        # when they're missing.
        cube = lat_lon_cube()
        element = Image(cube.copy())
        plot = GeoImagePlot(element)
        ranges = {}
        style = {'interpolation': None}
        plot_args, style, axis_kwargs = plot.get_data(element, ranges, style)
        for name in ('latitude', 'longitude'):
            cube.coord(name).guess_bounds()
        self.assertEqual(plot_args, (cube,))
        self.assertEqual(style, {'vmax': 11, 'vmin': 0})
        self.assertEqual(axis_kwargs, {})

    def test_auto_guess_bounds_not_needed(self):
        # Check that the `get_data()` method *doesn't* try to add or
        # modify the bounds when they're already present.
        cube = lat_lon_cube()
        for name in ('latitude', 'longitude'):
            coord = cube.coord(name)
            coord.guess_bounds()
            coord.bounds = coord.bounds + 0.1
        element = Image(cube.copy())
        plot = GeoImagePlot(element)
        ranges = {}
        style = {'interpolation': None}
        plot_args, style, axis_kwargs = plot.get_data(element, ranges, style)
        self.assertEqual(plot_args, (cube,))
        self.assertEqual(style, {'vmax': 11, 'vmin': 0})
        self.assertEqual(axis_kwargs, {})

if __name__ == '__main__':
    import unittest
    unittest.main()
<commit_msg>Removed unncessary bound guessing tests<commit_after><|endoftext|>


<commit_before>#-*- coding: utf-8 -*-
from __future__ import with_statement
from shop.prices import modifiers_pool
from shop.tests.utils.context_managers import SettingsOverride
from unittest import TestCase

class PricesTestCase(TestCase):

    def test_01_price_modifier_pool_loads_modifiers_properly(self):
        '''
        Let's add a price modifier to the settings, then load it,
        then call a method on it to make sure it works.
        '''
        MODIFIERS = ['shop.prices.modifiers.taxes_percentage.TaxPercentageModifier']
        with SettingsOverride(SHOP_PRICE_MODIFIERS=MODIFIERS):
            thelist = modifiers_pool.price_modifiers_pool.get_modifiers_list()
            self.assertEqual(len(thelist), 1)
            instance = thelist[0]
            self.assertTrue(hasattr(instance,'TAX_PERCENTAGE'))
            <commit_msg>Fixed wrong path bug...<commit_after>#-*- coding: utf-8 -*-
from __future__ import with_statement
from shop.prices import modifiers_pool
from shop.tests.utils.context_managers import SettingsOverride
from unittest import TestCase

class PricesTestCase(TestCase):

    def test_01_price_modifier_pool_loads_modifiers_properly(self):
        '''
        Let's add a price modifier to the settings, then load it,
        then call a method on it to make sure it works.
        '''
        MODIFIERS = ['shop.prices.modifiers.tax_modifiers.TenPercentTaxModifier']
        with SettingsOverride(SHOP_PRICE_MODIFIERS=MODIFIERS):
            thelist = modifiers_pool.price_modifiers_pool.get_modifiers_list()
            self.assertEqual(len(thelist), 1)
            instance = thelist[0]
            self.assertTrue(hasattr(instance,'TAX_PERCENTAGE'))
            <|endoftext|>


<commit_before>from shopify.base import ShopifyResource
import shopify.mixins as mixins
import base64
import re

class Shop(ShopifyResource):
    @classmethod
    def current(cls):
        return cls.find_one("/admin/shop." + cls.format.extension)

    def metafields(self):
        return Metafield.find()

    def add_metafield(self, metafield):
        if self.is_new():
            raise ValueError("You can only add metafields to a resource that has been saved")
        metafield.save()
        return metafield

    def events(self):
        return Event.find()

class CustomCollection(ShopifyResource):
    def products(self):
        return Product.find(collection_id=self.id)

    def add_product(self, product):
        return Collect.create(dict(collection_id=self.id, product_id=product.id))

    def remove_product(self, product):
        collect = Collect.find_first(collection_id=self.id, product_id=product.id)
        if collect:
            collect.destroy()

class SmartCollection(ShopifyResource):
    def products(self):
        return Product.find(collection_id=self.id)

class Collect(ShopifyResource):
    pass

class ShippingAddress(ShopifyResource):
    pass

class BillingAddress(ShopifyResource):
    pass

class LineItem(ShopifyResource):
    pass

class ShippingLine(ShopifyResource):
    pass

class NoteAttribute(ShopifyResource):
    pass

class Order(ShopifyResource):
    def close(self):
        self._load_attributes_from_response(self.post("close"))

    def open(self):
        self._load_attributes_from_response(self.post("open"))

    def cancel(self, **kwargs):
        self._load_attributes_from_response(self.post("cancel", **kwargs))

    def transactions(self):
        return Transaction.find(order_id=self.id)

    def capture(self, amount=""):
        return Transaction.create(amount=amount, kind="capture", order_id=self.id)

class Product(ShopifyResource):
    def price_range(self):
        prices = [variant.price for variant in self.variants]
        f = "%0.2f"
        min_price = min(prices)
        max_price = max(prices)
        if min_price != max_price:
            return "%s - %s" % (f % min_price, f % max_price)
        else:
            return f % min_price

    def collections(self):
        return CustomCollection.find(product_id = self.id)

    def smart_collections(self):
        return SmartCollection.find(product_id = self.id)

    def add_to_collection(self, collection):
        return collection.add_product(self)

    def remove_from_collection(self, collection):
        return collection.remove_product(self)

class Variant(ShopifyResource):
    _prefix_source = "/admin/products/$product_id/"

    @classmethod
    def _prefix(cls, options={}):
        product_id = options.get("product_id")
        return "/admin/" if product_id is None else "/admin/products/%s" % (product_id)

class Image(ShopifyResource):
    _prefix_source = "/admin/products/$product_id/"

    def __getattr__(self, name):
        if name in ["pico", "icon", "thumb", "small", "compact", "medium", "large", "grande", "original"]:
            return re.sub(r"/(.*)\.(\w{2,4})", r"/\1_%s.\2" % (name), self.src)
        else:
            return super(Image, self).__getattr__(name)

    def attach_image(self, data, filename=None):
        self.attributes["attachment"] = base64.b64encode(data)
        if filename is not None:
            self.attributes["filename"] = filename

class Transaction(ShopifyResource):
    _prefix_source = "/admin/orders/$order_id/"

class Fulfillment(ShopifyResource):
    _prefix_source = "/admin/orders/$order_id/"

class Country(ShopifyResource):
    pass

class Page(ShopifyResource):
    pass

class Blog(ShopifyResource):
    def articles(self):
        return Article.find(blog_id=self.id)

class Article(ShopifyResource):
    _prefix_source = "/admin/blogs/$blog_id/"

    def comments(self):
        return Comment.find(article_id=self.id)

class Metafield(ShopifyResource):
    _prefix_source = "/admin/$resource/$resource_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("resource") is None else "/admin/%s/%s" % (options["resource"], options["resource_id"])

class Comment(ShopifyResource):
    def remove(self):
        self._load_attributes_from_response(self.post("remove"))

    def spam(self):
        self._load_attributes_from_response(self.post("spam"))

    def approve(self):
        self._load_attributes_from_response(self.post("approve"))

    def restore(self):
        self._load_attributes_from_response(self.post("restore"))

    def not_spam(self):
        self._load_attributes_from_response(self.post("not_spam"))

class Province(ShopifyResource):
    _prefix_source = "/admin/countries/$country_id/"

class Redirect(ShopifyResource):
    pass

class Webhook(ShopifyResource):
    def __get_format(self):
        return self.attributes.get("format")

    def __set_format(self, data):
        self.attributes["format"] = data

    format = property(__get_format, __set_format, None, "Format attribute")

class Event(ShopifyResource):
    _prefix_source = "/admin/$resource/$resource_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("resource") is None else "/admin/%s/%s/" % (options["resource"], options["resource_id"])

class Customer(ShopifyResource):
    @classmethod
    def search(cls, **kwargs):
        """Search for customers matching supplied query

        Args:
           q: Text to search for customers ("q" is short for query)
           f: Filters to apply to customers ("f" is short for query)
           page: Page to show (default: 1)
           limit: Maximum number of results to show (default: 50, maximum: 250)
        Returns:
           An array of customers.
        """
        return cls._build_list(cls.get("search", **kwargs))

class CustomerGroup(ShopifyResource):
    def customers(cls, **kwargs):
        """Get a list of customers matching a customer group

        Args:
           page: Page to show (default: 1)
           limit: Maximum number of results to show (default: 50, maximum: 250)
        Returns:
           An array of customers.
        """
        return Customer._build_list(cls.get("customers", **kwargs))

class Theme(ShopifyResource):
    pass

class Asset(ShopifyResource):
    _primary_key = "key"
    _prefix_source = "/admin/themes/$theme_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("theme_id") is None else "/admin/themes/%s/" % (options["theme_id"])

    @classmethod
    def _element_path(cls, id, prefix_options={}, query_options=None):
        if query_options is None:
            prefix_options, query_options = cls._split_options(prefix_options)
        return "%s%s.%s%s" % (cls._prefix(prefix_options), cls.plural,
                              cls.format.extension, cls._query_string(query_options))

    @classmethod
    def find(cls, key=None, **kwargs):
        """Find an asset by key
        E.g.
            shopify.Asset.find('layout/theme.liquid', theme_id=99)
        """
        if not key:
            return super(Asset, cls).find(**kwargs)
        params = {"asset[key]": key}
        params.update(kwargs)
        theme_id = params.get("theme_id")
        path_prefix = "/admin/themes/%s" % (theme_id) if theme_id else "/admin"
        resource = cls.find_one("%s/assets.%s" % (path_prefix, cls.format.extension), **params)
        if theme_id and resource:
            resource._prefix_options["theme_id"] = theme_id
        return resource

    def __get_value(self):
        data = self.attributes.get("value")
        if data:
            return data
        data = self.attributes.get("attachment")
        if data:
            return base64.b64decode(data)

    def __set_value(self, data):
        self.__wipe_value_attributes()
        self.attributes["value"] = data

    value = property(__get_value, __set_value, None, "The asset's value or attachment")

    def attach(self, data):
        self.attachment = base64.b64encode(data)

    def destroy(self):
        options = {"asset[key]": self.key}
        options.update(self._prefix_options)
        return self.__class__.connection.delete(self._element_path(self.key, options), self.__class__.headers)

    def is_new(self):
        return False

    def __setattr__(self, name, value):
        if name in ("value", "attachment", "src", "source_key"):
            self.__wipe_value_attributes()
        return super(Asset, self).__setattr__(name, value)

    def __wipe_value_attributes(self):
        for attr in ("value", "attachment", "src", "source_key"):
            if self.attributes.has_key(attr):
                del self.attributes[attr]

class RecurringApplicationCharge(ShopifyResource):
    @classmethod
    def current(cls):
        return cls.find_first(status="active")

    def cancel(self):
        self._load_attributes_from_response(self.destroy)

    def activate(self):
        self._load_attributes_from_response(self.post("activate"))

class ApplicationCharge(ShopifyResource):
    def activate(self):
        self._load_attributes_from_response(self.post("activate"))

class ProductSearchEngine(ShopifyResource):
    pass

class ScriptTag(ShopifyResource):
    pass

# attribute of Customer
class Address(ShopifyResource):
    pass

# attribute of Product
class Option(ShopifyResource):
    pass

# attribute of Order
class PaymentDetails(ShopifyResource):
    pass

# attribute of Fulfillment and Transaction
class Receipt(ShopifyResource):
    pass

# attribute of SmartCollection
class Rule(ShopifyResource):
    pass

# attribute of Order
class TaxLine(ShopifyResource):
    pass

METAFIELD_ENABLED_CLASSES = (Article, Blog, CustomCollection, Customer, Order, Page, Product, SmartCollection, Variant)
EVENT_ENABLED_CLASSES = (Order, Product, CustomCollection, SmartCollection, Page, Blog, Article)

for cls in METAFIELD_ENABLED_CLASSES:
    cls.__bases__ += (mixins.Metafields,)

for cls in EVENT_ENABLED_CLASSES:
    cls.__bases__ += (mixins.Events,)
<commit_msg>Declare mixins used by resource on class declaration.<commit_after>from shopify.base import ShopifyResource
import shopify.mixins as mixins
import base64
import re

class Shop(ShopifyResource):
    @classmethod
    def current(cls):
        return cls.find_one("/admin/shop." + cls.format.extension)

    def metafields(self):
        return Metafield.find()

    def add_metafield(self, metafield):
        if self.is_new():
            raise ValueError("You can only add metafields to a resource that has been saved")
        metafield.save()
        return metafield

    def events(self):
        return Event.find()

class CustomCollection(ShopifyResource, mixins.Metafields, mixins.Events):
    def products(self):
        return Product.find(collection_id=self.id)

    def add_product(self, product):
        return Collect.create(dict(collection_id=self.id, product_id=product.id))

    def remove_product(self, product):
        collect = Collect.find_first(collection_id=self.id, product_id=product.id)
        if collect:
            collect.destroy()

class SmartCollection(ShopifyResource, mixins.Metafields, mixins.Events):
    def products(self):
        return Product.find(collection_id=self.id)

class Collect(ShopifyResource):
    pass

class ShippingAddress(ShopifyResource):
    pass

class BillingAddress(ShopifyResource):
    pass

class LineItem(ShopifyResource):
    pass

class ShippingLine(ShopifyResource):
    pass

class NoteAttribute(ShopifyResource):
    pass

class Order(ShopifyResource, mixins.Metafields, mixins.Events):
    def close(self):
        self._load_attributes_from_response(self.post("close"))

    def open(self):
        self._load_attributes_from_response(self.post("open"))

    def cancel(self, **kwargs):
        self._load_attributes_from_response(self.post("cancel", **kwargs))

    def transactions(self):
        return Transaction.find(order_id=self.id)

    def capture(self, amount=""):
        return Transaction.create(amount=amount, kind="capture", order_id=self.id)

class Product(ShopifyResource, mixins.Metafields, mixins.Events):
    def price_range(self):
        prices = [variant.price for variant in self.variants]
        f = "%0.2f"
        min_price = min(prices)
        max_price = max(prices)
        if min_price != max_price:
            return "%s - %s" % (f % min_price, f % max_price)
        else:
            return f % min_price

    def collections(self):
        return CustomCollection.find(product_id = self.id)

    def smart_collections(self):
        return SmartCollection.find(product_id = self.id)

    def add_to_collection(self, collection):
        return collection.add_product(self)

    def remove_from_collection(self, collection):
        return collection.remove_product(self)

class Variant(ShopifyResource, mixins.Metafields):
    _prefix_source = "/admin/products/$product_id/"

    @classmethod
    def _prefix(cls, options={}):
        product_id = options.get("product_id")
        return "/admin/" if product_id is None else "/admin/products/%s" % (product_id)

class Image(ShopifyResource):
    _prefix_source = "/admin/products/$product_id/"

    def __getattr__(self, name):
        if name in ["pico", "icon", "thumb", "small", "compact", "medium", "large", "grande", "original"]:
            return re.sub(r"/(.*)\.(\w{2,4})", r"/\1_%s.\2" % (name), self.src)
        else:
            return super(Image, self).__getattr__(name)

    def attach_image(self, data, filename=None):
        self.attributes["attachment"] = base64.b64encode(data)
        if filename is not None:
            self.attributes["filename"] = filename

class Transaction(ShopifyResource):
    _prefix_source = "/admin/orders/$order_id/"

class Fulfillment(ShopifyResource):
    _prefix_source = "/admin/orders/$order_id/"

class Country(ShopifyResource):
    pass

class Page(ShopifyResource, mixins.Metafields, mixins.Events):
    pass

class Blog(ShopifyResource, mixins.Metafields, mixins.Events):
    def articles(self):
        return Article.find(blog_id=self.id)

class Article(ShopifyResource, mixins.Metafields, mixins.Events):
    _prefix_source = "/admin/blogs/$blog_id/"

    def comments(self):
        return Comment.find(article_id=self.id)

class Metafield(ShopifyResource):
    _prefix_source = "/admin/$resource/$resource_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("resource") is None else "/admin/%s/%s" % (options["resource"], options["resource_id"])

class Comment(ShopifyResource):
    def remove(self):
        self._load_attributes_from_response(self.post("remove"))

    def spam(self):
        self._load_attributes_from_response(self.post("spam"))

    def approve(self):
        self._load_attributes_from_response(self.post("approve"))

    def restore(self):
        self._load_attributes_from_response(self.post("restore"))

    def not_spam(self):
        self._load_attributes_from_response(self.post("not_spam"))

class Province(ShopifyResource):
    _prefix_source = "/admin/countries/$country_id/"

class Redirect(ShopifyResource):
    pass

class Webhook(ShopifyResource):
    def __get_format(self):
        return self.attributes.get("format")

    def __set_format(self, data):
        self.attributes["format"] = data

    format = property(__get_format, __set_format, None, "Format attribute")

class Event(ShopifyResource):
    _prefix_source = "/admin/$resource/$resource_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("resource") is None else "/admin/%s/%s/" % (options["resource"], options["resource_id"])

class Customer(ShopifyResource, mixins.Metafields):
    @classmethod
    def search(cls, **kwargs):
        """Search for customers matching supplied query

        Args:
           q: Text to search for customers ("q" is short for query)
           f: Filters to apply to customers ("f" is short for query)
           page: Page to show (default: 1)
           limit: Maximum number of results to show (default: 50, maximum: 250)
        Returns:
           An array of customers.
        """
        return cls._build_list(cls.get("search", **kwargs))

class CustomerGroup(ShopifyResource):
    def customers(cls, **kwargs):
        """Get a list of customers matching a customer group

        Args:
           page: Page to show (default: 1)
           limit: Maximum number of results to show (default: 50, maximum: 250)
        Returns:
           An array of customers.
        """
        return Customer._build_list(cls.get("customers", **kwargs))

class Theme(ShopifyResource):
    pass

class Asset(ShopifyResource):
    _primary_key = "key"
    _prefix_source = "/admin/themes/$theme_id/"

    @classmethod
    def _prefix(cls, options={}):
        return "/admin/" if options.get("theme_id") is None else "/admin/themes/%s/" % (options["theme_id"])

    @classmethod
    def _element_path(cls, id, prefix_options={}, query_options=None):
        if query_options is None:
            prefix_options, query_options = cls._split_options(prefix_options)
        return "%s%s.%s%s" % (cls._prefix(prefix_options), cls.plural,
                              cls.format.extension, cls._query_string(query_options))

    @classmethod
    def find(cls, key=None, **kwargs):
        """Find an asset by key
        E.g.
            shopify.Asset.find('layout/theme.liquid', theme_id=99)
        """
        if not key:
            return super(Asset, cls).find(**kwargs)
        params = {"asset[key]": key}
        params.update(kwargs)
        theme_id = params.get("theme_id")
        path_prefix = "/admin/themes/%s" % (theme_id) if theme_id else "/admin"
        resource = cls.find_one("%s/assets.%s" % (path_prefix, cls.format.extension), **params)
        if theme_id and resource:
            resource._prefix_options["theme_id"] = theme_id
        return resource

    def __get_value(self):
        data = self.attributes.get("value")
        if data:
            return data
        data = self.attributes.get("attachment")
        if data:
            return base64.b64decode(data)

    def __set_value(self, data):
        self.__wipe_value_attributes()
        self.attributes["value"] = data

    value = property(__get_value, __set_value, None, "The asset's value or attachment")

    def attach(self, data):
        self.attachment = base64.b64encode(data)

    def destroy(self):
        options = {"asset[key]": self.key}
        options.update(self._prefix_options)
        return self.__class__.connection.delete(self._element_path(self.key, options), self.__class__.headers)

    def is_new(self):
        return False

    def __setattr__(self, name, value):
        if name in ("value", "attachment", "src", "source_key"):
            self.__wipe_value_attributes()
        return super(Asset, self).__setattr__(name, value)

    def __wipe_value_attributes(self):
        for attr in ("value", "attachment", "src", "source_key"):
            if self.attributes.has_key(attr):
                del self.attributes[attr]

class RecurringApplicationCharge(ShopifyResource):
    @classmethod
    def current(cls):
        return cls.find_first(status="active")

    def cancel(self):
        self._load_attributes_from_response(self.destroy)

    def activate(self):
        self._load_attributes_from_response(self.post("activate"))

class ApplicationCharge(ShopifyResource):
    def activate(self):
        self._load_attributes_from_response(self.post("activate"))

class ProductSearchEngine(ShopifyResource):
    pass

class ScriptTag(ShopifyResource):
    pass

# attribute of Customer
class Address(ShopifyResource):
    pass

# attribute of Product
class Option(ShopifyResource):
    pass

# attribute of Order
class PaymentDetails(ShopifyResource):
    pass

# attribute of Fulfillment and Transaction
class Receipt(ShopifyResource):
    pass

# attribute of SmartCollection
class Rule(ShopifyResource):
    pass

# attribute of Order
class TaxLine(ShopifyResource):
    pass
<|endoftext|>


<commit_before># -*- coding: utf-8; -*-
#
# This file is part of Superdesk.
#
# Copyright 2013, 2014 Sourcefabric z.u. and contributors.
#
# For the full copyright and license information, please see the
# AUTHORS and LICENSE files distributed with this source code, or
# at https://www.sourcefabric.org/superdesk/license

import logging
import json

from flask import request, current_app as app
from eve.utils import config
from eve.methods.common import serialize_value

from superdesk import privilege
from superdesk.notification import push_notification
from superdesk.resource import Resource
from superdesk.services import BaseService
from superdesk.users import get_user_from_request
from superdesk.utc import utcnow
from superdesk.errors import SuperdeskApiError
from superdesk.default_schema import DEFAULT_SCHEMA, DEFAULT_EDITOR

logger = logging.getLogger(__name__)

privilege(name="vocabularies", label="Vocabularies Management",
          description="User can manage vocabularies' contents.")

# TODO(petr): add api to specify vocabulary schema
vocab_schema = {
    'crop_sizes': {
        'width': {'type': 'integer'},
        'height': {'type': 'integer'},
    }
}

class VocabulariesResource(Resource):
    schema = {
        '_id': {
            'type': 'string',
            'required': True,
            'unique': True
        },
        'display_name': {
            'type': 'string',
            'required': True
        },
        'type': {
            'type': 'string',
            'required': True,
            'allowed': ['manageable', 'unmanageable'],
        },
        'items': {
            'type': 'list',
            'required': True
        },
        'single_value': {
            'type': 'boolean',
        },
        'schema_field': {
            'type': 'string',
            'required': False,
            'nullable': True
        },
        'dependent': {
            'type': 'boolean',
        },
        'service': {
            'type': 'dict',
        },
        'priority': {
            'type': 'integer'
        },
        'unique_field': {
            'type': 'string',
            'required': False,
            'nullable': True
        },
        'schema': {
            'type': 'dict'
        },
        'field_type': {
            'type': 'string',
            'nullable': True,
        },
        'field_options': {
            'type': 'dict',
        },
    }

    item_url = 'regex("[\w]+")'
    item_methods = ['GET', 'PATCH', 'DELETE']
    resource_methods = ['GET', 'POST']
    privileges = {'PATCH': 'vocabularies', 'POST': 'vocabularies', 'DELETE': 'vocabularies'}
    mongo_indexes = {'field_type': [('field_type', 1)]}

class VocabulariesService(BaseService):

    system_keys = set(DEFAULT_SCHEMA.keys()).union(set(DEFAULT_EDITOR.keys()))

    def on_create(self, docs):
        for doc in docs:
            if doc.get('field_type') and doc['_id'] in self.system_keys:
                raise SuperdeskApiError(
                    message='{} is in use'.format(doc['_id']),
                    payload={'_id': {'conflict': 1}})

    def on_replace(self, document, original):
        document[app.config['LAST_UPDATED']] = utcnow()
        document[app.config['DATE_CREATED']] = original.get(app.config['DATE_CREATED'],
                                                            utcnow()) if original else utcnow()
        logger.info("updating vocabulary item: %s", document["_id"])

    def on_fetched(self, doc):
        """Overriding to filter out inactive vocabularies and pops out 'is_active' property from the response.

        It keeps it when requested for manageable vocabularies.
        """

        if request and hasattr(request, 'args') and request.args.get('where'):
            where_clause = json.loads(request.args.get('where'))
            if where_clause.get('type') == 'manageable':
                return doc

        for item in doc[config.ITEMS]:
            self._filter_inactive_vocabularies(item)
            self._cast_items(item)

    def on_fetched_item(self, doc):
        """
        Overriding to filter out inactive vocabularies and pops out 'is_active' property from the response.
        """
        self._filter_inactive_vocabularies(doc)
        self._cast_items(doc)

    def on_update(self, updates, original):
        """Checks the duplicates if a unique field is defined"""
        unique_field = original.get('unique_field')
        if unique_field:
            self._check_uniqueness(updates.get('items', []), unique_field)

    def on_updated(self, updates, original):
        """
        Overriding this to send notification about the replacement
        """
        self._send_notification(original)

    def on_replaced(self, document, original):
        """
        Overriding this to send notification about the replacement
        """
        self._send_notification(document)

    def _check_uniqueness(self, items, unique_field):
        """Checks the uniqueness if a unique field is defined

        :param items: list of items to check for uniqueness
        :param unique_field: name of the unique field
        """
        unique_values = []
        for item in items:
            # compare only the active items
            if not item.get('is_active'):
                continue

            if not item.get(unique_field):
                raise SuperdeskApiError.badRequestError("{} cannot be empty".format(unique_field))

            unique_value = str(item.get(unique_field)).upper()

            if unique_value in unique_values:
                raise SuperdeskApiError.badRequestError("Value {} for field {} is not unique".
                                                        format(item.get(unique_field), unique_field))

            unique_values.append(unique_value)

    def _filter_inactive_vocabularies(self, item):
        vocs = item['items']
        active_vocs = ({k: voc[k] for k in voc.keys() if k != 'is_active'}
                       for voc in vocs if voc.get('is_active', True))

        item['items'] = list(active_vocs)

    def _cast_items(self, vocab):
        """Cast values in vocabulary items using predefined schema.

        :param vocab
        """
        schema = vocab_schema.get(vocab.get('_id'), {})
        for item in vocab.get('items', []):
            for field, field_schema in schema.items():
                if field in item:
                    item[field] = serialize_value(field_schema['type'], item[field])

    def _send_notification(self, updated_vocabulary):
        """
        Sends notification about the updated vocabulary to all the connected clients.
        """

        user = get_user_from_request()
        push_notification('vocabularies:updated', vocabulary=updated_vocabulary.get('display_name'),
                          user=str(user[config.ID_FIELD]) if user else None)

    def get_rightsinfo(self, item):
        rights_key = item.get('source', item.get('original_source', 'default'))
        all_rights = self.find_one(req=None, _id='rightsinfo')
        if not all_rights or not all_rights.get('items'):
            return {}
        try:
            default_rights = next(info for info in all_rights['items'] if info['name'] == 'default')
        except StopIteration:
            default_rights = None
        try:
            rights = next(info for info in all_rights['items'] if info['name'] == rights_key)
        except StopIteration:
            rights = default_rights
        if rights:
            return {
                'copyrightholder': rights.get('copyrightHolder'),
                'copyrightnotice': rights.get('copyrightNotice'),
                'usageterms': rights.get('usageTerms'),
            }
        else:
            return {}

    def get_extra_fields(self):
        return list(self.get(req=None, lookup={'field_type': {'$exists': True}}))

    def get_custom_vocabularies(self):
        return list(self.get(req=None, lookup={
            'field_type': {'$exists': False},
            'service': {'$exists': True},
        }))
<commit_msg>vocabularies helper text support (#1017)<commit_after># -*- coding: utf-8; -*-
#
# This file is part of Superdesk.
#
# Copyright 2013, 2014 Sourcefabric z.u. and contributors.
#
# For the full copyright and license information, please see the
# AUTHORS and LICENSE files distributed with this source code, or
# at https://www.sourcefabric.org/superdesk/license

import logging
import json

from flask import request, current_app as app
from eve.utils import config
from eve.methods.common import serialize_value

from superdesk import privilege
from superdesk.notification import push_notification
from superdesk.resource import Resource
from superdesk.services import BaseService
from superdesk.users import get_user_from_request
from superdesk.utc import utcnow
from superdesk.errors import SuperdeskApiError
from superdesk.default_schema import DEFAULT_SCHEMA, DEFAULT_EDITOR

logger = logging.getLogger(__name__)

privilege(name="vocabularies", label="Vocabularies Management",
          description="User can manage vocabularies' contents.")

# TODO(petr): add api to specify vocabulary schema
vocab_schema = {
    'crop_sizes': {
        'width': {'type': 'integer'},
        'height': {'type': 'integer'},
    }
}

class VocabulariesResource(Resource):
    schema = {
        '_id': {
            'type': 'string',
            'required': True,
            'unique': True
        },
        'display_name': {
            'type': 'string',
            'required': True
        },
        'helper_text': {
            'type': 'string',
            'maxlength': 120
        },
        'type': {
            'type': 'string',
            'required': True,
            'allowed': ['manageable', 'unmanageable'],
        },
        'items': {
            'type': 'list',
            'required': True
        },
        'single_value': {
            'type': 'boolean',
        },
        'schema_field': {
            'type': 'string',
            'required': False,
            'nullable': True
        },
        'dependent': {
            'type': 'boolean',
        },
        'service': {
            'type': 'dict',
        },
        'priority': {
            'type': 'integer'
        },
        'unique_field': {
            'type': 'string',
            'required': False,
            'nullable': True
        },
        'schema': {
            'type': 'dict'
        },
        'field_type': {
            'type': 'string',
            'nullable': True,
        },
        'field_options': {
            'type': 'dict',
        },
    }

    item_url = 'regex("[\w]+")'
    item_methods = ['GET', 'PATCH', 'DELETE']
    resource_methods = ['GET', 'POST']
    privileges = {'PATCH': 'vocabularies', 'POST': 'vocabularies', 'DELETE': 'vocabularies'}
    mongo_indexes = {'field_type': [('field_type', 1)]}

class VocabulariesService(BaseService):

    system_keys = set(DEFAULT_SCHEMA.keys()).union(set(DEFAULT_EDITOR.keys()))

    def on_create(self, docs):
        for doc in docs:
            if doc.get('field_type') and doc['_id'] in self.system_keys:
                raise SuperdeskApiError(
                    message='{} is in use'.format(doc['_id']),
                    payload={'_id': {'conflict': 1}})

    def on_replace(self, document, original):
        document[app.config['LAST_UPDATED']] = utcnow()
        document[app.config['DATE_CREATED']] = original.get(app.config['DATE_CREATED'],
                                                            utcnow()) if original else utcnow()
        logger.info("updating vocabulary item: %s", document["_id"])

    def on_fetched(self, doc):
        """Overriding to filter out inactive vocabularies and pops out 'is_active' property from the response.

        It keeps it when requested for manageable vocabularies.
        """

        if request and hasattr(request, 'args') and request.args.get('where'):
            where_clause = json.loads(request.args.get('where'))
            if where_clause.get('type') == 'manageable':
                return doc

        for item in doc[config.ITEMS]:
            self._filter_inactive_vocabularies(item)
            self._cast_items(item)

    def on_fetched_item(self, doc):
        """
        Overriding to filter out inactive vocabularies and pops out 'is_active' property from the response.
        """
        self._filter_inactive_vocabularies(doc)
        self._cast_items(doc)

    def on_update(self, updates, original):
        """Checks the duplicates if a unique field is defined"""
        unique_field = original.get('unique_field')
        if unique_field:
            self._check_uniqueness(updates.get('items', []), unique_field)

    def on_updated(self, updates, original):
        """
        Overriding this to send notification about the replacement
        """
        self._send_notification(original)

    def on_replaced(self, document, original):
        """
        Overriding this to send notification about the replacement
        """
        self._send_notification(document)

    def _check_uniqueness(self, items, unique_field):
        """Checks the uniqueness if a unique field is defined

        :param items: list of items to check for uniqueness
        :param unique_field: name of the unique field
        """
        unique_values = []
        for item in items:
            # compare only the active items
            if not item.get('is_active'):
                continue

            if not item.get(unique_field):
                raise SuperdeskApiError.badRequestError("{} cannot be empty".format(unique_field))

            unique_value = str(item.get(unique_field)).upper()

            if unique_value in unique_values:
                raise SuperdeskApiError.badRequestError("Value {} for field {} is not unique".
                                                        format(item.get(unique_field), unique_field))

            unique_values.append(unique_value)

    def _filter_inactive_vocabularies(self, item):
        vocs = item['items']
        active_vocs = ({k: voc[k] for k in voc.keys() if k != 'is_active'}
                       for voc in vocs if voc.get('is_active', True))

        item['items'] = list(active_vocs)

    def _cast_items(self, vocab):
        """Cast values in vocabulary items using predefined schema.

        :param vocab
        """
        schema = vocab_schema.get(vocab.get('_id'), {})
        for item in vocab.get('items', []):
            for field, field_schema in schema.items():
                if field in item:
                    item[field] = serialize_value(field_schema['type'], item[field])

    def _send_notification(self, updated_vocabulary):
        """
        Sends notification about the updated vocabulary to all the connected clients.
        """

        user = get_user_from_request()
        push_notification('vocabularies:updated', vocabulary=updated_vocabulary.get('display_name'),
                          user=str(user[config.ID_FIELD]) if user else None)

    def get_rightsinfo(self, item):
        rights_key = item.get('source', item.get('original_source', 'default'))
        all_rights = self.find_one(req=None, _id='rightsinfo')
        if not all_rights or not all_rights.get('items'):
            return {}
        try:
            default_rights = next(info for info in all_rights['items'] if info['name'] == 'default')
        except StopIteration:
            default_rights = None
        try:
            rights = next(info for info in all_rights['items'] if info['name'] == rights_key)
        except StopIteration:
            rights = default_rights
        if rights:
            return {
                'copyrightholder': rights.get('copyrightHolder'),
                'copyrightnotice': rights.get('copyrightNotice'),
                'usageterms': rights.get('usageTerms'),
            }
        else:
            return {}

    def get_extra_fields(self):
        return list(self.get(req=None, lookup={'field_type': {'$exists': True}}))

    def get_custom_vocabularies(self):
        return list(self.get(req=None, lookup={
            'field_type': {'$exists': False},
            'service': {'$exists': True},
        }))
<|endoftext|>


<commit_before>r"""Represents a ShutIt background command.

    - options to:
        - cancel command
        - get status (running, suspended etc)
        - check_timeout
"""

import time
import logging
import shutit_global
import shutit_util

class ShutItBackgroundCommand(object):
	"""Background command in ShutIt
	"""
	def __init__(self,
	             sendspec):
		# Stub this with a simple command for now
		self.sendspec               = sendspec
		self.block_other_commands   = sendspec.block_other_commands
		self.retry                  = sendspec.retry
		self.tries                  = 0
		self.pid                    = None
		self.return_value           = None
		self.start_time             = None
		self.run_state              = 'N' # State as per ps man page, but 'C' == Complete, 'N' == not started, 'F' == failed, 'S' == sleeping/running, 'T' == timed out by ShutIt
		self.cwd                    = self.sendspec.shutit_pexpect_child.send_and_get_output(' command pwd', ignore_background=True)
		self.id                     = shutit_util.random_id()
		self.output_file            = '/tmp/shutit_background_' + self.id + '_output.log'
		self.exit_code_file         = '/tmp/shutit_background_' + self.id + '_exit_code_file.log'
		self.command_file           = '/tmp/shutit_background_' + self.id + '_command.log'
		if self.sendspec.run_in_background:
			self.sendspec.send          = ' set +m && { : echo ' + self.sendspec.original_send + ' >' + self.command_file + ' && $(command cd ' + self.cwd + '>' + self.output_file + ' && ' + self.sendspec.send + ' >>' + self.output_file + ' 2>&1; echo $? >>' + self.exit_code_file + ') & } 2>/dev/null'

	def __str__(self):
		string = str(self.sendspec)
		string += '\n---- Background object ----'
		string += '\nblock_other_commands: ' + str(self.block_other_commands)
		string += '\ncwd:                  ' + str(self.cwd)
		string += '\npid:                  ' + str(self.pid)
		string += '\nretry:                ' + str(self.retry)
		string += '\nreturn_value:         ' + str(self.return_value)
		string += '\nrun_state:            ' + str(self.run_state)
		string += '\nstart_time:           ' + str(self.start_time)
		string += '\ntries:                ' + str(self.tries)
		string += '\n----                   ----'
		return string

	def run_background_command(self):
		# reset object
		self.pid              = None
		self.return_value     = None
		self.run_state        = 'N'
		self.start_time = time.time() # record start time

		# run command
		self.tries            += 1
		if self.sendspec.run_in_background:
			# Run in the background
			self.sendspec.shutit_pexpect_child.quick_send(self.sendspec.send)
			# Put into an 'S' state as that means 'running'
			self.run_state        = 'S'
			# Required to reset terminal after a background send. (TODO: why?)
			self.sendspec.shutit_pexpect_child.reset_terminal()
			# record pid
			self.pid = self.sendspec.shutit_pexpect_child.send_and_get_output(" echo ${!}",ignore_background=True)
		else:
			# Run synchronously and mark complete
			# We need to set this to ignore background before we run it, so that
			# it does not block itself and end up in an infinite loop.
			self.sendspec.ignore_background = True
			self.sendspec.shutit_pexpect_child.send(self.sendspec)
			self.run_state = 'C'

		self.sendspec.started = True

		assert self.run_state in ('C','S','F')
		return True

	def check_background_command_state(self):
		shutit_pexpect_child = self.sendspec.shutit_pexpect_child
		# Check the command has been started
		if not self.sendspec.started:
			assert self.run_state == 'N'
			return self.run_state
		if self.run_state in ('C','F'):
			assert self.sendspec.started
			return self.run_state
		assert self.run_state in ('S',), 'State should be in S, is in fact: ' + self.run_state
		assert self.start_time is not None
		run_state = shutit_pexpect_child.send_and_get_output(""" command ps -o stat """ + self.pid + """ | command sed '1d' """, ignore_background=True)
		# Ensure we get the first character only, if one exists.
		if len(run_state) > 0:
			self.run_state = run_state[0]
			# TODO: handle these other states more correctly; from ps man page
     		#state     The state is given by a sequence of characters, for example, ``RWNA''.  The first character indicates the run state of the process:
            #   I       Marks a process that is idle (sleeping for longer than about 20 seconds).
            #   R       Marks a runnable process.
            #   S       Marks a process that is sleeping for less than about 20 seconds.
            #   T       Marks a stopped process.
            #   U       Marks a process in uninterruptible wait.
            #   Z       Marks a dead process (a ``zombie'').
			if self.run_state in ('I','R','T','U','Z'):
				self.run_state = 'S'
			# honour sendspec.timeout
			assert self.run_state in ('S',)
			if self.sendspec.timeout is not None:
				current_time = time.time()
				time_taken = current_time - self.start_time
				if time_taken > self.sendspec.timeout:
					self.sendspec.shutit_pexpect_child.quick_send(' kill -9 ' + self.pid)
					self.run_state = 'T'
			return self.run_state
		else:
			shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ', id: ' + self.id + ' complete')
			self.run_state = 'C'
			# Stop this from blocking other commands from here.
			assert self.return_value is None, 'check_background_command_state called with self.return_value already set?' + str(self)
			shutit_pexpect_child.quick_send(' wait ' + self.pid)
			self.return_value = shutit_pexpect_child.send_and_get_output(' cat ' + self.exit_code_file, ignore_background=True)
			# TODO: options for return values
			if self.return_value not in self.sendspec.exit_values:
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' failed with exit code: ' + self.return_value, level=logging.DEBUG)
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' failed with output: ' + self.sendspec.shutit_pexpect_child.send_and_get_output(' cat ' + self.output_file, ignore_background=True), level=logging.DEBUG)
				if self.retry > 0:
					shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' retrying',level=logging.DEBUG)
					self.retry -= 1
					self.run_background_command()
					# recurse
					return self.check_background_command_state()
				else:
					shutit_global.shutit_global_object.log('background task final failure: ' + self.sendspec.send + ' failed with exit code: ' + self.return_value, level=logging.DEBUG)
					self.run_state = 'F'
				return self.run_state
			else:
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' succeeded with exit code: ' + self.return_value, level=logging.DEBUG)
			return self.run_state
		assert False
<commit_msg>overwrite last exit code<commit_after>r"""Represents a ShutIt background command.

    - options to:
        - cancel command
        - get status (running, suspended etc)
        - check_timeout
"""

import time
import logging
import shutit_global
import shutit_util

class ShutItBackgroundCommand(object):
	"""Background command in ShutIt
	"""
	def __init__(self,
	             sendspec):
		# Stub this with a simple command for now
		self.sendspec               = sendspec
		self.block_other_commands   = sendspec.block_other_commands
		self.retry                  = sendspec.retry
		self.tries                  = 0
		self.pid                    = None
		self.return_value           = None
		self.start_time             = None
		self.run_state              = 'N' # State as per ps man page, but 'C' == Complete, 'N' == not started, 'F' == failed, 'S' == sleeping/running, 'T' == timed out by ShutIt
		self.cwd                    = self.sendspec.shutit_pexpect_child.send_and_get_output(' command pwd', ignore_background=True)
		self.id                     = shutit_util.random_id()
		self.output_file            = '/tmp/shutit_background_' + self.id + '_output.log'
		self.exit_code_file         = '/tmp/shutit_background_' + self.id + '_exit_code_file.log'
		self.command_file           = '/tmp/shutit_background_' + self.id + '_command.log'
		if self.sendspec.run_in_background:
			self.sendspec.send          = ' set +m && { : $(echo "' + self.sendspec.original_send + '" >' + self.command_file + ' && command cd ' + self.cwd + '>' + self.output_file + ' && ' + self.sendspec.send + ' >>' + self.output_file + ' 2>&1; echo $? >' + self.exit_code_file + ') & } 2>/dev/null'

	def __str__(self):
		string = str(self.sendspec)
		string += '\n---- Background object ----'
		string += '\nblock_other_commands: ' + str(self.block_other_commands)
		string += '\ncwd:                  ' + str(self.cwd)
		string += '\npid:                  ' + str(self.pid)
		string += '\nretry:                ' + str(self.retry)
		string += '\nreturn_value:         ' + str(self.return_value)
		string += '\nrun_state:            ' + str(self.run_state)
		string += '\nstart_time:           ' + str(self.start_time)
		string += '\ntries:                ' + str(self.tries)
		string += '\n----                   ----'
		return string

	def run_background_command(self):
		# reset object
		self.pid              = None
		self.return_value     = None
		self.run_state        = 'N'
		self.start_time = time.time() # record start time

		# run command
		self.tries            += 1
		if self.sendspec.run_in_background:
			# Run in the background
			self.sendspec.shutit_pexpect_child.quick_send(self.sendspec.send)
			# Put into an 'S' state as that means 'running'
			self.run_state        = 'S'
			# Required to reset terminal after a background send. (TODO: why?)
			self.sendspec.shutit_pexpect_child.reset_terminal()
			# record pid
			self.pid = self.sendspec.shutit_pexpect_child.send_and_get_output(" echo ${!}",ignore_background=True)
		else:
			# Run synchronously and mark complete
			# We need to set this to ignore background before we run it, so that
			# it does not block itself and end up in an infinite loop.
			self.sendspec.ignore_background = True
			self.sendspec.shutit_pexpect_child.send(self.sendspec)
			self.run_state = 'C'

		self.sendspec.started = True

		assert self.run_state in ('C','S','F')
		return True

	def check_background_command_state(self):
		shutit_pexpect_child = self.sendspec.shutit_pexpect_child
		# Check the command has been started
		if not self.sendspec.started:
			assert self.run_state == 'N'
			return self.run_state
		if self.run_state in ('C','F'):
			assert self.sendspec.started
			return self.run_state
		assert self.run_state in ('S',), 'State should be in S, is in fact: ' + self.run_state
		assert self.start_time is not None
		run_state = shutit_pexpect_child.send_and_get_output(""" command ps -o stat """ + self.pid + """ | command sed '1d' """, ignore_background=True)
		# Ensure we get the first character only, if one exists.
		if len(run_state) > 0:
			self.run_state = run_state[0]
			# TODO: handle these other states more correctly; from ps man page
     		#state     The state is given by a sequence of characters, for example, ``RWNA''.  The first character indicates the run state of the process:
            #   I       Marks a process that is idle (sleeping for longer than about 20 seconds).
            #   R       Marks a runnable process.
            #   S       Marks a process that is sleeping for less than about 20 seconds.
            #   T       Marks a stopped process.
            #   U       Marks a process in uninterruptible wait.
            #   Z       Marks a dead process (a ``zombie'').
			if self.run_state in ('I','R','T','U','Z'):
				self.run_state = 'S'
			# honour sendspec.timeout
			assert self.run_state in ('S',)
			if self.sendspec.timeout is not None:
				current_time = time.time()
				time_taken = current_time - self.start_time
				if time_taken > self.sendspec.timeout:
					self.sendspec.shutit_pexpect_child.quick_send(' kill -9 ' + self.pid)
					self.run_state = 'T'
			return self.run_state
		else:
			shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ', id: ' + self.id + ' complete')
			self.run_state = 'C'
			# Stop this from blocking other commands from here.
			assert self.return_value is None, 'check_background_command_state called with self.return_value already set?' + str(self)
			shutit_pexpect_child.quick_send(' wait ' + self.pid)
			self.return_value = shutit_pexpect_child.send_and_get_output(' cat ' + self.exit_code_file, ignore_background=True)
			# TODO: options for return values
			if self.return_value not in self.sendspec.exit_values:
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' failed with exit code: ' + self.return_value, level=logging.DEBUG)
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' failed with output: ' + self.sendspec.shutit_pexpect_child.send_and_get_output(' cat ' + self.output_file, ignore_background=True), level=logging.DEBUG)
				if self.retry > 0:
					shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' retrying',level=logging.DEBUG)
					self.retry -= 1
					self.run_background_command()
					# recurse
					return self.check_background_command_state()
				else:
					shutit_global.shutit_global_object.log('background task final failure: ' + self.sendspec.send + ' failed with exit code: ' + self.return_value, level=logging.DEBUG)
					self.run_state = 'F'
				return self.run_state
			else:
				shutit_global.shutit_global_object.log('background task: ' + self.sendspec.send + ' succeeded with exit code: ' + self.return_value, level=logging.DEBUG)
			return self.run_state
		assert False
<|endoftext|>


<commit_before># Django settings for sikteeri project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    # ('Your Name', 'your_email@domain.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default' : {
        'NAME': 'sikteeri_test.sqlite',
        'ENGINE': 'django.db.backends.sqlite3',
        'USER': '',
        'PASSWORD' : '',
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'Europe/Helsinki'
SHORT_DATE_FORMAT = 'd.m.Y'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'fi-fi'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = 'static/'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

LOGIN_URL = '/login/'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
#     'django.template.loaders.eggs.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'sikteeri.ForceDefaultLanguageMiddleware.ForceDefaultLanguageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

ROOT_URLCONF = 'sikteeri.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    "templates/",
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.humanize',
    'django.contrib.comments',
    'membership',
    'services',
)

SESSION_COOKIE_SECURE = True

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

from local_settings import *

# Is this the right way to do this?
assert(IBAN_ACCOUNT_NUMBER != None)
assert(BIC_CODE != None)
assert(BILLING_FROM_EMAIL != None)
BILLING_CC_EMAIL
assert(FROM_EMAIL != None)
assert(SYSADMIN_EMAIL != None)
assert(SECRET_KEY != None)
assert(BILL_SUBJECT != None)
assert(ENABLE_REMINDERS != None)
assert(REMINDER_GRACE_DAYS != None)
assert(BILL_DAYS_BEFORE_CYCLE != None)
assert(BILL_DAYS_TO_DUE != None)
assert(TRUSTED_HOSTS != None)
MAINTENANCE_MESSAGE
<commit_msg>Update settings.py (Django 1.1->1.3). Fixes deprecation warnings.<commit_after># Django settings for sikteeri project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    # ('Your Name', 'your_email@domain.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default' : {
        'NAME': 'sikteeri_test.sqlite',
        'ENGINE': 'django.db.backends.sqlite3',
        'USER': '',
        'PASSWORD' : '',
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'Europe/Helsinki'
SHORT_DATE_FORMAT = 'd.m.Y'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'fi-fi'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = 'static/'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

LOGIN_URL = '/login/'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'sikteeri.ForceDefaultLanguageMiddleware.ForceDefaultLanguageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

ROOT_URLCONF = 'sikteeri.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    "templates/",
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.humanize',
    'django.contrib.comments',
    'membership',
    'services',
)

SESSION_COOKIE_SECURE = True

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

from local_settings import *

# Is this the right way to do this?
assert(IBAN_ACCOUNT_NUMBER != None)
assert(BIC_CODE != None)
assert(BILLING_FROM_EMAIL != None)
BILLING_CC_EMAIL
assert(FROM_EMAIL != None)
assert(SYSADMIN_EMAIL != None)
assert(SECRET_KEY != None)
assert(BILL_SUBJECT != None)
assert(ENABLE_REMINDERS != None)
assert(REMINDER_GRACE_DAYS != None)
assert(BILL_DAYS_BEFORE_CYCLE != None)
assert(BILL_DAYS_TO_DUE != None)
assert(TRUSTED_HOSTS != None)
MAINTENANCE_MESSAGE
<|endoftext|>