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

from datetime import datetime
import simplejson
import sys

from const import *
from model import *
from utils import *
import const
import reveal
import tasks

class Handler(BaseHandler):
    # After a repository is deactivated, we still need the admin page to be
    # accessible so we can edit its settings.
    ignore_deactivation = True

    # We show global admin page, if a repo is not specified.
    repo_required = False

    def get(self):
        user = users.get_current_user()
        simplejson.encoder.FLOAT_REPR = str
        encoder = simplejson.encoder.JSONEncoder(ensure_ascii=False)
        view_config = self.__model_config_to_view_config(self.config)
        view_config_json = dict(
                (name, encoder.encode(value))
                for name, value in view_config.iteritems())
        #sorts languages by exonym; to sort by code, remove the key argument
        sorted_exonyms = sorted(list(const.LANGUAGE_EXONYMS.items()),
                                key= lambda lang: lang[1])
        sorted_exonyms = map(lambda elem: {'code' : elem[0],
                                           'exonym' : elem[1]}, sorted_exonyms)
        sorted_exonyms_json = encoder.encode(sorted_exonyms)
        repo_options = [Struct(repo=repo, url=self.get_url('/admin', repo))
                        for repo in sorted(Repo.list())]
        self.render('admin.html',
                    user=user,
                    repo_options=repo_options,
                    view_config=view_config,
                    view_config_json=view_config_json,
                    login_url=users.create_login_url(self.request.url),
                    logout_url=users.create_logout_url(self.request.url),
                    language_exonyms_json=sorted_exonyms_json,
                    onload_function="add_initial_languages()",
                    id=self.env.domain + '/person.',
                    test_mode_min_age_hours=
                        tasks.CleanUpInTestMode.DELETION_AGE_SECONDS / 3600.0)

    def post(self):
        if self.params.operation == 'delete':
            # Redirect to the deletion handler with a valid signature.
            action = ('delete', str(self.params.id))
            self.redirect('/delete', id=self.params.id,
                          signature=reveal.sign(action))

        elif self.params.operation == 'create_repo':
            new_repo = self.params.new_repo
            Repo(key_name=new_repo).put()
            config.set_for_repo(  # Provide some defaults.
                new_repo,
                language_menu_options=['en', 'fr'],
                repo_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'},
                keywords='person finder, people finder, person, people, ' +
                    'crisis, survivor, family',
                use_family_name=True,
                use_alternate_names=True,
                use_postal_code=True,
                allow_believed_dead_via_ui=False,
                min_query_word_length=2,
                show_profile_entry=False,
                profile_websites=DEFAULT_PROFILE_WEBSITES,
                map_default_zoom=6,
                map_default_center=[0, 0],
                map_size_pixels=[400, 280],
                read_auth_key_required=True,
                search_auth_key_required=True,
                deactivated=False,
                launched=False,
                deactivation_message_html='',
                start_page_custom_htmls={'en': '', 'fr': ''},
                results_page_custom_htmls={'en': '', 'fr': ''},
                view_page_custom_htmls={'en': '', 'fr': ''},
                seek_query_form_custom_htmls={'en': '', 'fr': ''},
                footer_custom_htmls={'en': '', 'fr': ''},
                bad_words='',
                published_date=get_utcnow_timestamp(),
                updated_date=get_utcnow_timestamp(),
                test_mode=False,
                force_https=False,
            )
            self.redirect('/admin', new_repo)

        elif self.params.operation == 'save_repo':
            if not self.repo:
                self.redirect('/admin')
                return

            if self.__update_config(
                    self.repo,
                    # These settings are all entered in JSON.
                    json_config_names=[
                        'allow_believed_dead_via_ui',
                        'family_name_first',
                        'footer_custom_htmls',
                        'force_https',
                        'language_menu_options',
                        'map_default_center',
                        'map_default_zoom',
                        'map_size_pixels',
                        'min_query_word_length',
                        'profile_websites',
                        'read_auth_key_required',
                        'repo_titles',
                        'results_page_custom_htmls',
                        'search_auth_key_required',
                        'seek_query_form_custom_htmls',
                        'show_profile_entry',
                        'start_page_custom_htmls',
                        'test_mode',
                        'use_alternate_names',
                        'use_family_name',
                        'use_postal_code',
                        'view_page_custom_htmls',
                    ],
                    # These settings are literal strings (not JSON).
                    literal_config_names=[
                        'bad_words',
                        'deactivation_message_html',
                        'keywords',
                        'launch_status',
                    ],
                    # Update updated_date if any of the following settings are
                    # changed.
                    updating_config_names=[
                        'launch_status',
                        'test_mode',
                    ]):
                self.redirect('/admin')

        elif self.params.operation == 'save_global':
            if self.__update_config(
                    '*',
                    # These settings are all entered in JSON.
                    json_config_names=[
                        'sms_number_to_repo',
                    ],
                    # These settings are literal strings (not JSON).
                    literal_config_names=[
                    ]):
                self.redirect('/admin')

    def __update_config(
            self,
            repo,
            json_config_names,
            literal_config_names,
            updating_config_names=[]):
        values = {}
        for name in json_config_names:
            try:
                values[name] = simplejson.loads(self.request.get(name))
            except:
                self.error(
                    400, 'The setting for %s was not valid JSON.' % name)
                return False

        for name in literal_config_names:
            values[name] = self.request.get(name)

        orig_view_config = self.__model_config_to_view_config(
                config.Configuration(repo))
        for name in updating_config_names:
            if orig_view_config.get(name) != values[name]:
                values['updated_date'] = get_utcnow_timestamp()
                break

        config.set_for_repo(repo, **self.__view_config_to_model_config(values))
        return True

    def __model_config_to_view_config(self, model_config):
        """Converts the config in the database to the config for admin page
        rendering."""
        view_config = {}
        for name, value in model_config.iteritems():
            if name not in ['deactivated', 'launched']:
                view_config[name] = value

        if model_config.deactivated:
            view_config['launch_status'] = 'deactivated'
        elif model_config.launched:
            view_config['launch_status'] = 'activated'
        else:
            view_config['launch_status'] = 'staging'

        return view_config

    def __view_config_to_model_config(self, view_config):
        """Converts the config for admin page rendering to the config in the
        database."""
        model_config = {}
        for name, value in view_config.iteritems():
            if name == 'launch_status':
                if value == 'staging':
                    model_config['deactivated'] = False
                    model_config['launched'] = False
                elif value == 'activated':
                    model_config['deactivated'] = False
                    model_config['launched'] = True
                elif value == 'deactivated':
                    model_config['deactivated'] = True
                    model_config['launched'] = False
                else:
                    raise Exception(
                            'Invalid value for config.launch_status: %p'
                            % value)
            else:
                model_config[name] = value
        return model_config
<commit_msg>Add repo_aliases to json_config_names<commit_after>#!/usr/bin/python2.7
# Copyright 2011 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from datetime import datetime
import simplejson
import sys

from const import *
from model import *
from utils import *
import const
import reveal
import tasks

class Handler(BaseHandler):
    # After a repository is deactivated, we still need the admin page to be
    # accessible so we can edit its settings.
    ignore_deactivation = True

    # We show global admin page, if a repo is not specified.
    repo_required = False

    def get(self):
        user = users.get_current_user()
        simplejson.encoder.FLOAT_REPR = str
        encoder = simplejson.encoder.JSONEncoder(ensure_ascii=False)
        view_config = self.__model_config_to_view_config(self.config)
        view_config_json = dict(
                (name, encoder.encode(value))
                for name, value in view_config.iteritems())
        #sorts languages by exonym; to sort by code, remove the key argument
        sorted_exonyms = sorted(list(const.LANGUAGE_EXONYMS.items()),
                                key= lambda lang: lang[1])
        sorted_exonyms = map(lambda elem: {'code' : elem[0],
                                           'exonym' : elem[1]}, sorted_exonyms)
        sorted_exonyms_json = encoder.encode(sorted_exonyms)
        repo_options = [Struct(repo=repo, url=self.get_url('/admin', repo))
                        for repo in sorted(Repo.list())]
        self.render('admin.html',
                    user=user,
                    repo_options=repo_options,
                    view_config=view_config,
                    view_config_json=view_config_json,
                    login_url=users.create_login_url(self.request.url),
                    logout_url=users.create_logout_url(self.request.url),
                    language_exonyms_json=sorted_exonyms_json,
                    onload_function="add_initial_languages()",
                    id=self.env.domain + '/person.',
                    test_mode_min_age_hours=
                        tasks.CleanUpInTestMode.DELETION_AGE_SECONDS / 3600.0)

    def post(self):
        if self.params.operation == 'delete':
            # Redirect to the deletion handler with a valid signature.
            action = ('delete', str(self.params.id))
            self.redirect('/delete', id=self.params.id,
                          signature=reveal.sign(action))

        elif self.params.operation == 'create_repo':
            new_repo = self.params.new_repo
            Repo(key_name=new_repo).put()
            config.set_for_repo(  # Provide some defaults.
                new_repo,
                language_menu_options=['en', 'fr'],
                repo_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'},
                keywords='person finder, people finder, person, people, ' +
                    'crisis, survivor, family',
                use_family_name=True,
                use_alternate_names=True,
                use_postal_code=True,
                allow_believed_dead_via_ui=False,
                min_query_word_length=2,
                show_profile_entry=False,
                profile_websites=DEFAULT_PROFILE_WEBSITES,
                map_default_zoom=6,
                map_default_center=[0, 0],
                map_size_pixels=[400, 280],
                read_auth_key_required=True,
                search_auth_key_required=True,
                deactivated=False,
                launched=False,
                deactivation_message_html='',
                start_page_custom_htmls={'en': '', 'fr': ''},
                results_page_custom_htmls={'en': '', 'fr': ''},
                view_page_custom_htmls={'en': '', 'fr': ''},
                seek_query_form_custom_htmls={'en': '', 'fr': ''},
                footer_custom_htmls={'en': '', 'fr': ''},
                bad_words='',
                published_date=get_utcnow_timestamp(),
                updated_date=get_utcnow_timestamp(),
                test_mode=False,
                force_https=False,
            )
            self.redirect('/admin', new_repo)

        elif self.params.operation == 'save_repo':
            if not self.repo:
                self.redirect('/admin')
                return

            if self.__update_config(
                    self.repo,
                    # These settings are all entered in JSON.
                    json_config_names=[
                        'allow_believed_dead_via_ui',
                        'family_name_first',
                        'footer_custom_htmls',
                        'force_https',
                        'language_menu_options',
                        'map_default_center',
                        'map_default_zoom',
                        'map_size_pixels',
                        'min_query_word_length',
                        'profile_websites',
                        'read_auth_key_required',
                        'repo_titles',
                        'results_page_custom_htmls',
                        'search_auth_key_required',
                        'seek_query_form_custom_htmls',
                        'show_profile_entry',
                        'start_page_custom_htmls',
                        'test_mode',
                        'use_alternate_names',
                        'use_family_name',
                        'use_postal_code',
                        'view_page_custom_htmls',
                    ],
                    # These settings are literal strings (not JSON).
                    literal_config_names=[
                        'bad_words',
                        'deactivation_message_html',
                        'keywords',
                        'launch_status',
                    ],
                    # Update updated_date if any of the following settings are
                    # changed.
                    updating_config_names=[
                        'launch_status',
                        'test_mode',
                    ]):
                self.redirect('/admin')

        elif self.params.operation == 'save_global':
            if self.__update_config(
                    '*',
                    # These settings are all entered in JSON.
                    json_config_names=[
                        'sms_number_to_repo',
                        'repo_aliases',
                    ],
                    # These settings are literal strings (not JSON).
                    literal_config_names=[
                    ]):
                self.redirect('/admin')

    def __update_config(
            self,
            repo,
            json_config_names,
            literal_config_names,
            updating_config_names=[]):
        values = {}
        for name in json_config_names:
            try:
                values[name] = simplejson.loads(self.request.get(name))
            except:
                self.error(
                    400, 'The setting for %s was not valid JSON.' % name)
                return False

        for name in literal_config_names:
            values[name] = self.request.get(name)

        orig_view_config = self.__model_config_to_view_config(
                config.Configuration(repo))
        for name in updating_config_names:
            if orig_view_config.get(name) != values[name]:
                values['updated_date'] = get_utcnow_timestamp()
                break

        config.set_for_repo(repo, **self.__view_config_to_model_config(values))
        return True

    def __model_config_to_view_config(self, model_config):
        """Converts the config in the database to the config for admin page
        rendering."""
        view_config = {}
        for name, value in model_config.iteritems():
            if name not in ['deactivated', 'launched']:
                view_config[name] = value

        if model_config.deactivated:
            view_config['launch_status'] = 'deactivated'
        elif model_config.launched:
            view_config['launch_status'] = 'activated'
        else:
            view_config['launch_status'] = 'staging'

        return view_config

    def __view_config_to_model_config(self, view_config):
        """Converts the config for admin page rendering to the config in the
        database."""
        model_config = {}
        for name, value in view_config.iteritems():
            if name == 'launch_status':
                if value == 'staging':
                    model_config['deactivated'] = False
                    model_config['launched'] = False
                elif value == 'activated':
                    model_config['deactivated'] = False
                    model_config['launched'] = True
                elif value == 'deactivated':
                    model_config['deactivated'] = True
                    model_config['launched'] = False
                else:
                    raise Exception(
                            'Invalid value for config.launch_status: %p'
                            % value)
            else:
                model_config[name] = value
        return model_config
<|endoftext|>


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

# update_thrift_file.py language src_path_for_thrift_file dest_path_folder

'''
The client has to be built using Apache thrift. In order to build the client, thrift needs
a thrift file. If it is being built for java or python, thrift needs the file as-is.
If it is being built in scala, it needs an additional line

This file uses the template thrift file (that works for the entire project) and adds
a line if it is needed for scala.

Usage:
update_thrift_file.py language src_path_for_thrift_file destination_folder_of_modified_file

language:
One of [python, scala, java] to generate the thrift file for

src_path_for_thrift_file:
Where the original thrift file (modeldb/thrift/ModelDB.thrift) is located.

destination_folder_of_modified_file:
Where to store the new thrift file, which may or may not be modified.
'''

#os to make directories
import os

#sys to read command line arguments
import sys

# The language to generate for
lang = sys.argv[1]

# The original thrift file
src_path = sys.argv[2]

# The folder to output the potentially modified thrift file too
dest_path = sys.argv[3]

# Make the directory if it needs to be made
try:
    os.makedirs(dest_path)
except:
    pass

# read the source file
data = open(src_path, "r").read()

# Open the output file (where to copy to)
f = open(dest_path + "/ModelDB.thrift", "wb")

# If it's in scala, write the namespace first, else do nothing
if lang == "scala":
    f.write("namespace scala modeldb\n")

# Write the thrift file out into the new destination
f.write(data)

# Close and save the file
f.close()<commit_msg>wb to w mode for thrift file writing<commit_after>#!/usr/bin/env python

# update_thrift_file.py language src_path_for_thrift_file dest_path_folder

'''
The client has to be built using Apache thrift. In order to build the client, thrift needs
a thrift file. If it is being built for java or python, thrift needs the file as-is.
If it is being built in scala, it needs an additional line

This file uses the template thrift file (that works for the entire project) and adds
a line if it is needed for scala.

Usage:
update_thrift_file.py language src_path_for_thrift_file destination_folder_of_modified_file

language:
One of [python, scala, java] to generate the thrift file for

src_path_for_thrift_file:
Where the original thrift file (modeldb/thrift/ModelDB.thrift) is located.

destination_folder_of_modified_file:
Where to store the new thrift file, which may or may not be modified.
'''

#os to make directories
import os

#sys to read command line arguments
import sys

# The language to generate for
lang = sys.argv[1]

# The original thrift file
src_path = sys.argv[2]

# The folder to output the potentially modified thrift file too
dest_path = sys.argv[3]

# Make the directory if it needs to be made
try:
    os.makedirs(dest_path)
except:
    pass

# read the source file
data = open(src_path, "r").read()

# Open the output file (where to copy to)
f = open(dest_path + "/ModelDB.thrift", "w")

# If it's in scala, write the namespace first, else do nothing
if lang == "scala":
    f.write("namespace scala modeldb\n")

# Write the thrift file out into the new destination
f.write(data)

# Close and save the file
f.close()
<|endoftext|>


<commit_before>from django.contrib.gis.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from enhydris.hcore.models import Gpoint, Gline, Garea
import sys

models_lst = ['GISBorehole', 'GISPump', 'GISRefinery',
              'GISSpring', 'GISAqueductNode',
              'GISAqueductLine', 'GISReservoir',]

class Lookup(models.Model):
    descr = models.CharField(max_length=200, blank=True)
    descr_alt = models.CharField(max_length=200, blank=True)
    class Meta:
        abstract = True
        ordering = ('descr',)

    def __unicode__(self):
        return self.descr or self.descr_alt

class GISEntity(models.Model):
    gis_id = models.IntegerField(blank=True, null=True)
    original_gentity_id = models.IntegerField(blank=True, null=True)
    gtype = models.ForeignKey('GISEntityType', blank=True, null=True)
#   Geo manager is needed for some geo filtering operations
    objects = models.GeoManager()
    def gis_model(self):
        model = getattr(sys.modules[__name__], models_lst[self.gtype.id-1])
        try:
            return model.objects.get(gisentity_ptr=self.id)
        except model.DoesNotExist:
            return None
    def name(self):
        self.gis_model().name

class GISEntityType(Lookup): pass

class GISBoreholeSpring(Gpoint):
    water_use = models.ForeignKey('GISBoreholeSpringWaterUse',
                                  blank=True, null=True)
    water_user = models.ForeignKey('GISBoreholeSpringWaterUser',
                                  blank=True, null=True)
    land_use = models.ForeignKey('GISBoreholeSpringLandUse',
                                  blank=True, null=True)
    continuous_flow = models.FloatField(blank=True, null=True)

class GISBoreholeSpringWaterUse(Lookup):  pass
class GISBoreholeSpringWaterUser(Lookup): pass
class GISBoreholeSpringLandUse(Lookup):   pass

class GISBorehole(GISBoreholeSpring, GISEntity):
    code = models.IntegerField(blank=True, null=True)
    group = models.CharField(max_length=80, blank=True)
    objects = models.GeoManager()
    has_pmeter = models.BooleanField(default=False)
    pmeter_type = models.ForeignKey('GISBoreholePmeterType',
                                    blank=True, null=True)
    pmeter_length = models.FloatField(blank=True, null=True)
    pmeter_diameter = models.FloatField(blank=True, null=True)
    borehole_depth = models.FloatField(blank=True, null=True)
    pipe_depth = models.FloatField(blank=True, null=True)
    water_depth = models.FloatField(blank=True, null=True)
    value_t = models.FloatField(blank=True, null=True)
    value_s = models.FloatField(blank=True, null=True)
    value_b = models.FloatField(blank=True, null=True)
    value_k = models.FloatField(blank=True, null=True)
    threshold_a = models.FloatField(blank=True, null=True)
    threshold_b = models.FloatField(blank=True, null=True)
    continuous_stage = models.FloatField(blank=True, null=True)
    test_flow = models.FloatField(blank=True, null=True)
    test_stage = models.FloatField(blank=True, null=True)
    begin_works = models.DateTimeField(blank=True, null=True)
    end_works = models.DateTimeField(blank=True, null=True)
    drill_type = models.ForeignKey('GISBoreholeDrillType',
                                   blank=True, null=True)
    pipe_mat = models.ForeignKey('GISBoreholePipeMat',
                                 blank=True, null=True)
    pump_discharge = models.FloatField(blank=True, null=True)
    pump_ratio = models.FloatField(blank=True, null=True)

    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=1)
        super(GISBorehole, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Borehole group: ')+self.group

class GISBoreholePmeterType(Lookup): pass
class GISBoreholeDrillType(Lookup): pass
class GISBoreholePipeMat(Lookup): pass

class GISPump(Gpoint, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    pump_type = models.ForeignKey('GISPumpType', blank=True, null=True);
    is_irrig = models.BooleanField(default=False)
    is_pump = models.BooleanField(default=False)
    pump_active = models.BooleanField(default=False)
    is_generator = models.BooleanField(default=False)
    generator_active = models.BooleanField(default=False)
    pump_num = models.IntegerField(blank=True, null=True)
    pump_discharge = models.FloatField(blank=True, null=True)
    generator_num = models.IntegerField(blank=True, null=True)
    total_power = models.FloatField(blank=True, null=True)
    generator_discharge = models.FloatField(blank=True, null=True)
    pump_energy = models.FloatField(blank=True, null=True)
    generator_energy = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=2)
        super(GISPump, self).save(*args, **kwargs)
    def extra_info(self):
        return ', '.join( (_('Pump active') if self.pump_active else '',
                           _('Generator') if self.is_generator else '',
                        ))

class GISPumpType(Lookup): pass

class GISRefinery(Gpoint, GISEntity):
    capacity = models.FloatField(blank=True, null=True)
    peak_capacity = models.FloatField(blank=True, null=True)
    storage = models.FloatField(blank=True, null=True)
    overflow_stage = models.FloatField(blank=True, null=True)
    outlet_level = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=3)
        super(GISRefinery, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Capacity: ')+str(self.capacity)

class GISSpring(GISBoreholeSpring, GISEntity):
    dstype = models.ForeignKey('GISSpringDstype',
                               null=True, blank=True)
    hgeo_info = models.ForeignKey('GISSpringHgeoInfo',
                               null=True, blank=True)
    is_continuous = models.BooleanField(default=False)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=4)
        super(GISSpring, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Spring type: ')+self.dstype.descr

class GISSpringDstype(Lookup): pass
class GISSpringHgeoInfo(Lookup): pass

class GISAqueductNode(Gpoint, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    type_name = models.CharField(max_length=80, blank=True)
    measure_discharge = models.BooleanField(default=False)
    measure_stage = models.BooleanField(default=False)
    start_position = models.FloatField(blank=True, null=True)
    end_position = models.FloatField(blank=True, null=True)
    duct_segment_type = models.ForeignKey('GISDuctSegmentType',
                                          blank=True, null=True)
    duct_status = models.ForeignKey('GISDuctStatusType',
                                    blank=True, null=True)
    repers = models.CharField(max_length=40, blank=True)
    repers_en = models.CharField(max_length=40, blank=True)
    group = models.ForeignKey('GISAqueductGroup', blank=True,
                              null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=5)
        super(GISAqueductNode, self).save(*args, **kwargs)
    def extra_info(self):
        if self.group:
            return _('In aqueduct group: ')+self.group.descr
        else:
            return ''

class GISAqueductLine(Gline, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    q = models.FloatField(blank=True, null=True)
    exs = models.IntegerField(blank=True, null=True)
    remarks = models.TextField(blank=True)
    type_name = models.CharField(max_length=80, blank=True)
    group = models.ForeignKey('GISAqueductGroup', blank=True,
                              null=True)
    xsection = models.ForeignKey('GISXSection', blank=True,
                                 null=True)
    area = models.FloatField(blank=True, null=True)
    width = models.FloatField(blank=True, null=True)
    depth = models.FloatField(blank=True, null=True)
    slope = models.FloatField(blank=True, null=True)
    roughness_coef = models.FloatField(blank=True, null=True)
    roughness_coef_type = models.ForeignKey('GISRoughnessCoefType',
                                            blank=True, null=True)
    bank_slope = models.FloatField(blank=True, null=True)
    leakage_coef = models.FloatField(blank=True, null=True)
    measure_discharge = models.BooleanField(default=False)
    measure_stage = models.BooleanField(default=False)
    start_position = models.FloatField(blank=True, null=True)
    end_position = models.FloatField(blank=True, null=True)
    duct_segment_type = models.ForeignKey('GISDuctSegmentType',
                                          blank=True, null=True)
    discharge_capacity = models.FloatField(blank=True, null=True)
    duct_flow_type = models.ForeignKey('GISDuctFlowType',
                                       blank=True, null=True)
    duct_status = models.ForeignKey('GISDuctStatusType',
                                    blank=True, null=True)
    repers = models.CharField(max_length=40, blank=True)
    repers_en = models.CharField(max_length=40, blank=True)
    pipe_mat = models.ForeignKey('GISBoreholePipeMat',
                                 blank=True, null=True)
    alt1 = models.FloatField(blank=True, null=True)
    alt2 = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=6)
        super(GISAqueductLine, self).save(*args, **kwargs)
    def extra_info(self):
        if self.group:
            return _('In aqueduct group: ')+self.group.descr
        else:
            return ''

GENTITYFILEDIR = settings.GENTITYFILE_DIR

class GISXSection(models.Model):
    xsection_type = models.ForeignKey('GISXSectionType', blank=True,
                                      null=True)
    closed = models.BooleanField(default=False)
    dimensions = models.CharField(blank=True, max_length=40)
    drawing_file = models.FileField(upload_to=GENTITYFILEDIR)
    def __unicode__(self):
        return 'XSection with id=%d, %s, %s'%(self.id,
                            self.xsection_type.descr, self.dimensions)

class GISAqueductGroup(Lookup): pass
class GISXSectionType(Lookup): pass
class GISDuctSegmentType(Lookup): pass
class GISDuctFlowType(Lookup): pass
class GISDuctStatusType(Lookup): pass
class GISRoughnessCoefType(Lookup): pass

class GISReservoir(Garea, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    inflow_mean = models.FloatField(blank=True, null=True)
    inflow_max = models.FloatField(blank=True, null=True)
    inflow_min = models.FloatField(blank=True, null=True)
    runoff_mean = models.FloatField(blank=True, null=True)
    runoff_max = models.FloatField(blank=True, null=True)
    runoff_min = models.FloatField(blank=True, null=True)
    volume_max = models.FloatField(blank=True, null=True)
    dead_volume = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=7)
        super(GISReservoir, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Area: ')+str(self.area)

<commit_msg>Minor fix<commit_after>from django.contrib.gis.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from enhydris.hcore.models import Gpoint, Gline, Garea
import sys

models_lst = ['GISBorehole', 'GISPump', 'GISRefinery',
              'GISSpring', 'GISAqueductNode',
              'GISAqueductLine', 'GISReservoir',]

class Lookup(models.Model):
    descr = models.CharField(max_length=200, blank=True)
    descr_alt = models.CharField(max_length=200, blank=True)
    class Meta:
        abstract = True
        ordering = ('descr',)

    def __unicode__(self):
        return self.descr or self.descr_alt

class GISEntity(models.Model):
    gis_id = models.IntegerField(blank=True, null=True)
    original_gentity_id = models.IntegerField(blank=True, null=True)
    gtype = models.ForeignKey('GISEntityType', blank=True, null=True)
#   Geo manager is needed for some geo filtering operations
    objects = models.GeoManager()
    def gis_model(self):
        model = getattr(sys.modules[__name__], models_lst[self.gtype.id-1])
        try:
            return model.objects.get(gisentity_ptr=self.id)
        except model.DoesNotExist:
            return None
    def name(self):
        self.gis_model().name

class GISEntityType(Lookup): pass

class GISBoreholeSpring(Gpoint):
    water_use = models.ForeignKey('GISBoreholeSpringWaterUse',
                                  blank=True, null=True)
    water_user = models.ForeignKey('GISBoreholeSpringWaterUser',
                                  blank=True, null=True)
    land_use = models.ForeignKey('GISBoreholeSpringLandUse',
                                  blank=True, null=True)
    continuous_flow = models.FloatField(blank=True, null=True)

class GISBoreholeSpringWaterUse(Lookup):  pass
class GISBoreholeSpringWaterUser(Lookup): pass
class GISBoreholeSpringLandUse(Lookup):   pass

class GISBorehole(GISBoreholeSpring, GISEntity):
    code = models.IntegerField(blank=True, null=True)
    group = models.CharField(max_length=80, blank=True)
    objects = models.GeoManager()
    has_pmeter = models.BooleanField(default=False)
    pmeter_type = models.ForeignKey('GISBoreholePmeterType',
                                    blank=True, null=True)
    pmeter_length = models.FloatField(blank=True, null=True)
    pmeter_diameter = models.FloatField(blank=True, null=True)
    borehole_depth = models.FloatField(blank=True, null=True)
    pipe_depth = models.FloatField(blank=True, null=True)
    water_depth = models.FloatField(blank=True, null=True)
    value_t = models.FloatField(blank=True, null=True)
    value_s = models.FloatField(blank=True, null=True)
    value_b = models.FloatField(blank=True, null=True)
    value_k = models.FloatField(blank=True, null=True)
    threshold_a = models.FloatField(blank=True, null=True)
    threshold_b = models.FloatField(blank=True, null=True)
    continuous_stage = models.FloatField(blank=True, null=True)
    test_flow = models.FloatField(blank=True, null=True)
    test_stage = models.FloatField(blank=True, null=True)
    begin_works = models.DateTimeField(blank=True, null=True)
    end_works = models.DateTimeField(blank=True, null=True)
    drill_type = models.ForeignKey('GISBoreholeDrillType',
                                   blank=True, null=True)
    pipe_mat = models.ForeignKey('GISBoreholePipeMat',
                                 blank=True, null=True)
    pump_discharge = models.FloatField(blank=True, null=True)
    pump_ratio = models.FloatField(blank=True, null=True)

    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=1)
        super(GISBorehole, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Borehole group: ')+self.group

class GISBoreholePmeterType(Lookup): pass
class GISBoreholeDrillType(Lookup): pass
class GISBoreholePipeMat(Lookup): pass

class GISPump(Gpoint, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    pump_type = models.ForeignKey('GISPumpType', blank=True, null=True);
    is_irrig = models.BooleanField(default=False)
    is_pump = models.BooleanField(default=False)
    pump_active = models.BooleanField(default=False)
    is_generator = models.BooleanField(default=False)
    generator_active = models.BooleanField(default=False)
    pump_num = models.IntegerField(blank=True, null=True)
    pump_discharge = models.FloatField(blank=True, null=True)
    generator_num = models.IntegerField(blank=True, null=True)
    total_power = models.FloatField(blank=True, null=True)
    generator_discharge = models.FloatField(blank=True, null=True)
    pump_energy = models.FloatField(blank=True, null=True)
    generator_energy = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=2)
        super(GISPump, self).save(*args, **kwargs)
    def extra_info(self):
        if self.is_generator:
            return _('Generator')
        else:
            return _('Pump active') if self.pump_active else ''

class GISPumpType(Lookup): pass

class GISRefinery(Gpoint, GISEntity):
    capacity = models.FloatField(blank=True, null=True)
    peak_capacity = models.FloatField(blank=True, null=True)
    storage = models.FloatField(blank=True, null=True)
    overflow_stage = models.FloatField(blank=True, null=True)
    outlet_level = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=3)
        super(GISRefinery, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Capacity: ')+str(self.capacity)

class GISSpring(GISBoreholeSpring, GISEntity):
    dstype = models.ForeignKey('GISSpringDstype',
                               null=True, blank=True)
    hgeo_info = models.ForeignKey('GISSpringHgeoInfo',
                               null=True, blank=True)
    is_continuous = models.BooleanField(default=False)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=4)
        super(GISSpring, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Spring type: ')+self.dstype.descr

class GISSpringDstype(Lookup): pass
class GISSpringHgeoInfo(Lookup): pass

class GISAqueductNode(Gpoint, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    type_name = models.CharField(max_length=80, blank=True)
    measure_discharge = models.BooleanField(default=False)
    measure_stage = models.BooleanField(default=False)
    start_position = models.FloatField(blank=True, null=True)
    end_position = models.FloatField(blank=True, null=True)
    duct_segment_type = models.ForeignKey('GISDuctSegmentType',
                                          blank=True, null=True)
    duct_status = models.ForeignKey('GISDuctStatusType',
                                    blank=True, null=True)
    repers = models.CharField(max_length=40, blank=True)
    repers_en = models.CharField(max_length=40, blank=True)
    group = models.ForeignKey('GISAqueductGroup', blank=True,
                              null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=5)
        super(GISAqueductNode, self).save(*args, **kwargs)
    def extra_info(self):
        if self.group:
            return _('In aqueduct group: ')+self.group.descr
        else:
            return ''

class GISAqueductLine(Gline, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    q = models.FloatField(blank=True, null=True)
    exs = models.IntegerField(blank=True, null=True)
    remarks = models.TextField(blank=True)
    type_name = models.CharField(max_length=80, blank=True)
    group = models.ForeignKey('GISAqueductGroup', blank=True,
                              null=True)
    xsection = models.ForeignKey('GISXSection', blank=True,
                                 null=True)
    area = models.FloatField(blank=True, null=True)
    width = models.FloatField(blank=True, null=True)
    depth = models.FloatField(blank=True, null=True)
    slope = models.FloatField(blank=True, null=True)
    roughness_coef = models.FloatField(blank=True, null=True)
    roughness_coef_type = models.ForeignKey('GISRoughnessCoefType',
                                            blank=True, null=True)
    bank_slope = models.FloatField(blank=True, null=True)
    leakage_coef = models.FloatField(blank=True, null=True)
    measure_discharge = models.BooleanField(default=False)
    measure_stage = models.BooleanField(default=False)
    start_position = models.FloatField(blank=True, null=True)
    end_position = models.FloatField(blank=True, null=True)
    duct_segment_type = models.ForeignKey('GISDuctSegmentType',
                                          blank=True, null=True)
    discharge_capacity = models.FloatField(blank=True, null=True)
    duct_flow_type = models.ForeignKey('GISDuctFlowType',
                                       blank=True, null=True)
    duct_status = models.ForeignKey('GISDuctStatusType',
                                    blank=True, null=True)
    repers = models.CharField(max_length=40, blank=True)
    repers_en = models.CharField(max_length=40, blank=True)
    pipe_mat = models.ForeignKey('GISBoreholePipeMat',
                                 blank=True, null=True)
    alt1 = models.FloatField(blank=True, null=True)
    alt2 = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=6)
        super(GISAqueductLine, self).save(*args, **kwargs)
    def extra_info(self):
        if self.group:
            return _('In aqueduct group: ')+self.group.descr
        else:
            return ''

GENTITYFILEDIR = settings.GENTITYFILE_DIR

class GISXSection(models.Model):
    xsection_type = models.ForeignKey('GISXSectionType', blank=True,
                                      null=True)
    closed = models.BooleanField(default=False)
    dimensions = models.CharField(blank=True, max_length=40)
    drawing_file = models.FileField(upload_to=GENTITYFILEDIR)
    def __unicode__(self):
        return 'XSection with id=%d, %s, %s'%(self.id,
                            self.xsection_type.descr, self.dimensions)

class GISAqueductGroup(Lookup): pass
class GISXSectionType(Lookup): pass
class GISDuctSegmentType(Lookup): pass
class GISDuctFlowType(Lookup): pass
class GISDuctStatusType(Lookup): pass
class GISRoughnessCoefType(Lookup): pass

class GISReservoir(Garea, GISEntity):
    entity_type = models.IntegerField(blank=True, null=True)
    inflow_mean = models.FloatField(blank=True, null=True)
    inflow_max = models.FloatField(blank=True, null=True)
    inflow_min = models.FloatField(blank=True, null=True)
    runoff_mean = models.FloatField(blank=True, null=True)
    runoff_max = models.FloatField(blank=True, null=True)
    runoff_min = models.FloatField(blank=True, null=True)
    volume_max = models.FloatField(blank=True, null=True)
    dead_volume = models.FloatField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name or 'id=%d'%(self.id,)
    def save(self, *args, **kwargs):
        self.gtype = GISEntityType.objects.get(pk=7)
        super(GISReservoir, self).save(*args, **kwargs)
    def extra_info(self):
        return _('Area: ')+str(self.area)

<|endoftext|>


<commit_before>from app import app
from flask import current_app
from flask.ext.wtf import Form
from wtforms.validators import InputRequired, Length, URL, Email
from variables import opening_times
from wtforms import TextField, TextAreaField, validators, PasswordField, \
    StringField, BooleanField, SubmitField, HiddenField, SelectField
from flask_user.forms import RegisterForm, unique_email_validator
from flask_user.translations import lazy_gettext as _

# Information about a new food resource.
class AddNewFoodResourceForm(Form):
    website = TextField(
        label = 'Food Resource Website',
        validators = [
            URL(True, "Invalid website URL.")
        ])
    name = TextField(
        label = 'Food Resource Name',
        validators = [
            InputRequired("Please provide the food resource's name.")
        ])
    phone_number = TextField(
        label = 'Phone Number')
    address_line1 = TextField(
        label = 'Address Line 1',
        validators = [
            InputRequired("Please provide the food resource's address."),
            Length(1, 100) # same max length as in Address model.
        ])
    address_line2 = TextField(
        label = 'Address Line 2',
        validators = [
            Length(0, 100) # Same max length as in Address model.
        ])
    address_city = TextField(
        label = 'City',
        validators = [
            InputRequired("Please provide the food resource's city."),
            Length(1, 35) # Same max length as in Address model.
        ])
    address_state = TextField(
        label = 'State',
        validators = [
            InputRequired("Please provide the food resource's state."),
            Length(1, 2) # Same max length as in Address model.
        ])
    address_zip_code = TextField(
        label = 'Zip Code',
        validators = [
            InputRequired("Please provide the food resource's zip code."),
            Length(1, 5) # Same max length as in Address model.
        ])
    additional_information = TextAreaField(
        label = 'Any additional information?',
        validators = [
            Length(0, 300)
        ])

    def validate(self):
        return super(Form, self).validate()

# Information about the person submitting the food resource for evaluation.
# Subclassed from 'AddNewFoodResourceForm'
class RequestNewFoodResourceForm(AddNewFoodResourceForm):
    your_first_name = TextField(
        label = 'Your First Name',
        validators = [
            InputRequired("Please provide your first name."),
            Length(0, 35)
        ])
    your_last_name = TextField(
        label = 'Your Last Name',
        validators = [
            InputRequired("Please provide your last name."),
            Length(0, 35)
        ])
    your_email_address = TextField(
        label = 'Your Email Address',
        validators = [
            InputRequired("Please provide an email address at which we can contact you."),
            Email("Invalid email address."),
            Length(1, 35)
        ])
    your_phone_number = TextField(
        label = 'Your Phone Number',
        validators = [
            InputRequired("Please provide a phone number at which we can contact you.")
        ])

# Form to invite new admin.
# Subclassed from 'flask_user.forms.RegisterForm'
class InviteForm(RegisterForm):
    first_name = StringField(_('First Name'), validators=[
        validators.Required(_('First Name is required'))
        ])

    last_name = StringField(_('Last Name'), validators=[
        validators.Required(_('First Name is required'))
        ])

    submit = SubmitField(_('Invite'))

    # Override RegisterForm's validate function so that a temporary password
    # can be set
    def validate(self):
        # remove certain form fields depending on user manager config
        user_manager =  current_app.user_manager
        delattr(self, 'password')
        delattr(self, 'retype_password')

        if not user_manager.enable_username:
            delattr(self, 'username')
        if not user_manager.enable_email:
            delattr(self, 'email')

        # Add custom username validator if needed
        if user_manager.enable_username:
            has_been_added = False
            for v in self.username.validators:
                if v==user_manager.username_validator:
                    has_been_added = True
            if not has_been_added:
                self.username.validators.append(user_manager.username_validator)

        # Validate field-validators
        if not super(RegisterForm, self).validate():
            return False

        return True
<commit_msg>Removed import call to 'opening_times' variable (already removed)<commit_after>from app import app
from flask import current_app
from flask.ext.wtf import Form
from wtforms.validators import InputRequired, Length, URL, Email
from wtforms import TextField, TextAreaField, validators, PasswordField, \
    StringField, BooleanField, SubmitField, HiddenField, SelectField
from flask_user.forms import RegisterForm, unique_email_validator
from flask_user.translations import lazy_gettext as _

# Information about a new food resource.
class AddNewFoodResourceForm(Form):
    website = TextField(
        label = 'Food Resource Website',
        validators = [
            URL(True, "Invalid website URL.")
        ])
    name = TextField(
        label = 'Food Resource Name',
        validators = [
            InputRequired("Please provide the food resource's name.")
        ])
    phone_number = TextField(
        label = 'Phone Number')
    address_line1 = TextField(
        label = 'Address Line 1',
        validators = [
            InputRequired("Please provide the food resource's address."),
            Length(1, 100) # same max length as in Address model.
        ])
    address_line2 = TextField(
        label = 'Address Line 2',
        validators = [
            Length(0, 100) # Same max length as in Address model.
        ])
    address_city = TextField(
        label = 'City',
        validators = [
            InputRequired("Please provide the food resource's city."),
            Length(1, 35) # Same max length as in Address model.
        ])
    address_state = TextField(
        label = 'State',
        validators = [
            InputRequired("Please provide the food resource's state."),
            Length(1, 2) # Same max length as in Address model.
        ])
    address_zip_code = TextField(
        label = 'Zip Code',
        validators = [
            InputRequired("Please provide the food resource's zip code."),
            Length(1, 5) # Same max length as in Address model.
        ])
    additional_information = TextAreaField(
        label = 'Any additional information?',
        validators = [
            Length(0, 300)
        ])

    def validate(self):
        return super(Form, self).validate()

# Information about the person submitting the food resource for evaluation.
# Subclassed from 'AddNewFoodResourceForm'
class RequestNewFoodResourceForm(AddNewFoodResourceForm):
    your_first_name = TextField(
        label = 'Your First Name',
        validators = [
            InputRequired("Please provide your first name."),
            Length(0, 35)
        ])
    your_last_name = TextField(
        label = 'Your Last Name',
        validators = [
            InputRequired("Please provide your last name."),
            Length(0, 35)
        ])
    your_email_address = TextField(
        label = 'Your Email Address',
        validators = [
            InputRequired("Please provide an email address at which we can contact you."),
            Email("Invalid email address."),
            Length(1, 35)
        ])
    your_phone_number = TextField(
        label = 'Your Phone Number',
        validators = [
            InputRequired("Please provide a phone number at which we can contact you.")
        ])

# Form to invite new admin.
# Subclassed from 'flask_user.forms.RegisterForm'
class InviteForm(RegisterForm):
    first_name = StringField(_('First Name'), validators=[
        validators.Required(_('First Name is required'))
        ])

    last_name = StringField(_('Last Name'), validators=[
        validators.Required(_('First Name is required'))
        ])

    submit = SubmitField(_('Invite'))

    # Override RegisterForm's validate function so that a temporary password
    # can be set
    def validate(self):
        # remove certain form fields depending on user manager config
        user_manager =  current_app.user_manager
        delattr(self, 'password')
        delattr(self, 'retype_password')

        if not user_manager.enable_username:
            delattr(self, 'username')
        if not user_manager.enable_email:
            delattr(self, 'email')

        # Add custom username validator if needed
        if user_manager.enable_username:
            has_been_added = False
            for v in self.username.validators:
                if v==user_manager.username_validator:
                    has_been_added = True
            if not has_been_added:
                self.username.validators.append(user_manager.username_validator)

        # Validate field-validators
        if not super(RegisterForm, self).validate():
            return False

        return True
<|endoftext|>


<commit_before>import sys
import os
import subprocess
import time
import argparse

def ingest_dirs(top):
    for (dirpath, dirnames, filenames) in os.walk(top):
        if len(dirnames) == 0 and len(filenames) > 0:
            yield dirpath

def ingest(ns):
    procs = dict()
    def spawn(adir):
        print "Ingest %s" % adir
        proc = subprocess.Popen([ns.script, adir])
        procs[proc.pid] = proc

    def reap_some():
        done = []
        while True:
            for (pid, proc) in procs.items():
                if proc.poll() is not None:
                    done.append(pid)

            if len(done) > 0:
                for pid in done:
                    del procs[pid]
                break
            else:
                time.sleep(1)

    for adir in ingest_dirs(ns.dir):
        if (len(procs) < ns.procs):
            spawn(adir)
        else:
            reap_some()
            spawn(adir)

    while len(pids) > 0:
        reap_some()

def main(args):
    parser = argparse.ArgumentParser(
        prog = "ingest-parallel.py",
        description = "run parallel ingestion scripts in the leaf directories of a dataset"
    )
    parser.add_argument('-n', '--processes',
                        type = int,
                        default = 10,
                        dest = 'procs',
                        help = "Number of parallel ingestion processes")
    parser.add_argument('script',
                        type = str,
                        help = "Ingest script; must accept a directory and be nice!")
    parser.add_argument('dir',
                        type = str,
                        help = "Top dataset directory")
    ns = parser.parse_args(args)
    ingest(ns)

if __name__ == '__main__':
    main(sys.argv[1:])
<commit_msg>ingest-parallel script: fix end loop condition<commit_after>import sys
import os
import subprocess
import time
import argparse

def ingest_dirs(top):
    for (dirpath, dirnames, filenames) in os.walk(top):
        if len(dirnames) == 0 and len(filenames) > 0:
            yield dirpath

def ingest(ns):
    procs = dict()
    def spawn(adir):
        print "Ingest %s" % adir
        proc = subprocess.Popen([ns.script, adir])
        procs[proc.pid] = proc

    def reap_some():
        done = []
        while True:
            for (pid, proc) in procs.items():
                if proc.poll() is not None:
                    done.append(pid)

            if len(done) > 0:
                for pid in done:
                    del procs[pid]
                break
            else:
                time.sleep(1)

    for adir in ingest_dirs(ns.dir):
        if (len(procs) < ns.procs):
            spawn(adir)
        else:
            reap_some()
            spawn(adir)

    while len(procs) > 0:
        reap_some()

def main(args):
    parser = argparse.ArgumentParser(
        prog = "ingest-parallel.py",
        description = "run parallel ingestion scripts in the leaf directories of a dataset"
    )
    parser.add_argument('-n', '--processes',
                        type = int,
                        default = 10,
                        dest = 'procs',
                        help = "Number of parallel ingestion processes")
    parser.add_argument('script',
                        type = str,
                        help = "Ingest script; must accept a directory and be nice!")
    parser.add_argument('dir',
                        type = str,
                        help = "Top dataset directory")
    ns = parser.parse_args(args)
    ingest(ns)

if __name__ == '__main__':
    main(sys.argv[1:])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import

from teamsupport import config
from teamsupport.models import Action, Ticket
from teamsupport.services import TeamSupportService

__author__ = 'Yola Engineers'
__email__ = 'engineers@yola.com'
__version__ = '0.2.2'

__all__ = (Action, TeamSupportService, Ticket, config)

def init(org_id, auth_key):
    config.ORG_ID = org_id
    config.AUTH_KEY = auth_key
<commit_msg>Bump version.<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import

from teamsupport import config
from teamsupport.models import Action, Ticket
from teamsupport.services import TeamSupportService

__author__ = 'Yola Engineers'
__email__ = 'engineers@yola.com'
__version__ = '0.3.0'

__all__ = (Action, TeamSupportService, Ticket, config)

def init(org_id, auth_key):
    config.ORG_ID = org_id
    config.AUTH_KEY = auth_key
<|endoftext|>


<commit_before>#!/usr/bin/env python
import argparse
import subprocess
import os
import sys

def run(command, ignore_rc=False, **kwargs):
    defaults = {
        'shell': True
    }
    defaults.update(kwargs)

    return_code = subprocess.call(command, **defaults)
    if return_code:
        if not ignore_rc:
            sys.exit(return_code)

def run_bg(command, **kwargs):
    defaults = {
        'shell': True
    }
    defaults.update(kwargs)

    return subprocess.Popen(command, **defaults)

print 'starting...'
run('pkill -f envs/cla_.*integration', ignore_rc=True)

PROJECT_NAME = "cla_public"
BACKEND_PROJECT_NAME = "cla_backend"

# use python scripts/jenkins/build.py integration

# args
parser = argparse.ArgumentParser(
    description='Build project ready for testing by Jenkins.')
parser.add_argument('envname', metavar='envname', type=str, nargs=1,
                    help='e.g. integration, production, etc.')

parser.add_argument('--backend-dir', metavar='backend_dir', type=str, nargs=1,
                    help='path to backend project')
args = parser.parse_args()

env = args.envname[0]
backend_workspace = args.backend_dir[0]

env_name = "%s-%s" % (PROJECT_NAME, env)
env_path = "/tmp/jenkins/envs/%s" % env_name
bin_path = "%s/bin" % env_path

backend_env_name = "%s-%s" % (BACKEND_PROJECT_NAME, env)
backend_env_path = "/tmp/jenkins/envs/%s" % backend_env_name
backend_bin_path = "%s/bin" % backend_env_path

# Remove .pyc files from the project
run("find . -name '*.pyc' -delete")

# build js assets
run('npm install')
run("bower install")
run("gulp build")
run( "%s/python manage.py collectstatic --noinput" % bin_path)

# run tests
backend_process = run_bg(
    "cd %s && %s/python manage.py testserver initial_category.json test_auth_clients.json --addrport 8000 --noinput --settings=cla_backend.settings.jenkins" % (backend_workspace.replace(' ', '\ '),backend_bin_path, ))
run("wget http://localhost:8000/admin/ -t 20 --retry-connrefused --waitretry=2 -T 60")

public_process = run_bg( "%s/python manage.py runserver 8001" % bin_path)
run("wget http://localhost:8001/ -t 20 --retry-connrefused --waitretry=2 -T 60")

run('make test')

print 'exiting...'
run('pkill -f envs/cla_.*integration', ignore_rc=True)
<commit_msg>Added Selenium server .jar download to jenkins JS build script.<commit_after>#!/usr/bin/env python
import argparse
import subprocess
import os
import sys

def run(command, ignore_rc=False, **kwargs):
    defaults = {
        'shell': True
    }
    defaults.update(kwargs)

    return_code = subprocess.call(command, **defaults)
    if return_code:
        if not ignore_rc:
            sys.exit(return_code)

def run_bg(command, **kwargs):
    defaults = {
        'shell': True
    }
    defaults.update(kwargs)

    return subprocess.Popen(command, **defaults)

print 'starting...'
run('pkill -f envs/cla_.*integration', ignore_rc=True)

PROJECT_NAME = "cla_public"
BACKEND_PROJECT_NAME = "cla_backend"
SELENIUM_ZIP_NAME = "selenium-java-2.41.0.zip"
SELENIUM_ZIP_URL = "http://selenium-release.storage.googleapis.com/2.41/%s" % SELENIUM_ZIP_NAME
SELENIUM_JAR_NAME = "selenium-java-2.41.0.jar"

# use python scripts/jenkins/build.py integration

# args
parser = argparse.ArgumentParser(
    description='Build project ready for testing by Jenkins.')
parser.add_argument('envname', metavar='envname', type=str, nargs=1,
                    help='e.g. integration, production, etc.')

parser.add_argument('--backend-dir', metavar='backend_dir', type=str, nargs=1,
                    help='path to backend project')
args = parser.parse_args()

env = args.envname[0]
backend_workspace = args.backend_dir[0]

env_name = "%s-%s" % (PROJECT_NAME, env)
env_path = "/tmp/jenkins/envs/%s" % env_name
bin_path = "%s/bin" % env_path

backend_env_name = "%s-%s" % (BACKEND_PROJECT_NAME, env)
backend_env_path = "/tmp/jenkins/envs/%s" % backend_env_name
backend_bin_path = "%s/bin" % backend_env_path

# Install Selenium .jar if not already present
if not os.path.isfile("%s/%s" % backend_bin_path, SELENIUM_JAR_NAME):
    run("wget %s" % SELENIUM_ZIP_URL)
    run("unzip %s" % SELENIUM_ZIP_NAME)
    run("mv %s %s" % (SELENIUM_JAR_NAME, backend_bin_path))

# Remove .pyc files from the project
run("find . -name '*.pyc' -delete")

# build js assets
run('npm install')
run("bower install")
run("gulp build")
run( "%s/python manage.py collectstatic --noinput" % bin_path)

# run tests
backend_process = run_bg(
    "cd %s && %s/python manage.py testserver initial_category.json test_auth_clients.json --addrport 8000 --noinput --settings=cla_backend.settings.jenkins" % (backend_workspace.replace(' ', '\ '),backend_bin_path, ))
run("wget http://localhost:8000/admin/ -t 20 --retry-connrefused --waitretry=2 -T 60")

public_process = run_bg( "%s/python manage.py runserver 8001" % bin_path)
run("wget http://localhost:8001/ -t 20 --retry-connrefused --waitretry=2 -T 60")

run('make test')

print 'exiting...'
run('pkill -f envs/cla_.*integration', ignore_rc=True)
<|endoftext|>


<commit_before>import logging
import time

class Timer(object):
    def __init__(self, tabs = 0, silent = False, prefix = "", logger = None):
        self.tabs = tabs
        self.silent = silent
        self.start = time.time()
        self.prefix = prefix
        self.logger = logger
        if self.logger is None:
            self.logger = logging.getLogger(__name__)

    def restart(self):
        self.start = time.time()

    def report(self, name, should_restart = True):
        if not self.silent:
            text = '    ' * self.tabs
            if self.prefix is not "":
                text += self.prefix + ' -- '
            text += name + " took "
            text += str(time.time() - self.start)
            self.logger.debug(text)
        if should_restart:
            self.restart()
<commit_msg>Timer uses logger of calling module.<commit_after>import logging
import time

class Timer(object):
    def __init__(self, tabs = 0, silent = False, prefix = "", logger = None):
        self.tabs = tabs
        self.silent = silent
        self.start = time.time()
        self.prefix = prefix
        self.logger = logger
        if self.logger is None:
            import inspect
            frm = inspect.stack()[1]
            mod_name = inspect.getmodule(frm[0]).__name__
            self.logger = logging.getLogger(mod_name)

    def restart(self):
        self.start = time.time()

    def report(self, name, should_restart = True):
        if not self.silent:
            text = '    ' * self.tabs
            if self.prefix is not "":
                text += self.prefix + ' -- '
            text += name + " took "
            text += str(time.time() - self.start)
            self.logger.debug(text)
        if should_restart:
            self.restart()
<|endoftext|>


<commit_before># Lint as: python3
# Copyright 2020 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Create custom error class and centrally define all errors."""

from typing import List, Optional, Type, Union

class GlazierError(Exception):
  """Creates an error object.

  This error object can be interacted with via it's attributes directly. For
  example, the following code can be used to determine the attributes of this
  class:

  try:
    raise GlazierError('SomeException', [
                       'SomeReplacement', 'SomeOtherReplacement'])
  except GlazierError as e:
    for att in dir(e):
        print(att, getattr(e, att))

  The default code if all fails is 4000. This acts as a fallback for when there
  is an unknown exception.

  Attributes:
    code: Error code with an associated message
    message: Error message string with an associated code
    exception: Exception message string
    replacements: Any number of values that the error message should contain
  """

  def __init__(self,
               exception: Optional[str] = '',
               replacements: Optional[List[Union[bool, int, str]]] = None):
    self.code = 4000
    self.message = ''
    self.exception = exception
    self.replacements = replacements
    super().__init__(exception, replacements)

  def __str__(self) -> str:
    string = ''

    if self.message:
      string = f'{self.message} '

    string += f'({self.code})'

    # TODO: Add exception file and lineno.
    if self.exception:
      string += f': {self.exception}'

    return string

def _new_err(code: int, message: str) -> Type[GlazierError]:
  """Captures code and message pairs for every error.

  This method acts to store the error codes and the associated messages to be
  passed to the GlazierException class.

  Args:
    code: Error code with an associated message
    message: Error message string with an associated code

  Returns:
    GlazierError exception with all required attributes.
  """

  class Error(GlazierError):
    """Stores error information used in GlazierError."""

    def __init__(self,
                 exception: Optional[str] = '',
                 replacements: Optional[List[Union[bool, int, str]]] = None):
      super().__init__(exception, replacements)
      self.code: int = code
      if message and replacements:
        # Asterisk is used to unpack the values of the list
        self.message: str = f'{message.format(*replacements)}'
      elif message:
        self.message: str = message

  return Error

################################################################################
# ERROR CODES (https://google.github.io/glazier/error_codes)             #
################################################################################
GReservedError = _new_err(1337, 'Reserved {} {} {}')
GUncaughtError = _new_err(4000, 'Uncaught exception')
GCollectLogsError = _new_err(4301, 'Failed to collect logs')
GWebServerError = _new_err(5000, 'Failed to reach web server')
GServiceError = _new_err(5300, 'Service unavailable')
<commit_msg>Add WinPE errors<commit_after># Lint as: python3
# Copyright 2020 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Create custom error class and centrally define all errors."""

from typing import List, Optional, Type, Union

class GlazierError(Exception):
  """Creates an error object.

  This error object can be interacted with via it's attributes directly. For
  example, the following code can be used to determine the attributes of this
  class:

  try:
    raise GlazierError('SomeException', [
                       'SomeReplacement', 'SomeOtherReplacement'])
  except GlazierError as e:
    for att in dir(e):
        print(att, getattr(e, att))

  The default code if all fails is 4000. This acts as a fallback for when there
  is an unknown exception.

  Attributes:
    code: Error code with an associated message
    message: Error message string with an associated code
    exception: Exception message string
    replacements: Any number of values that the error message should contain
  """

  def __init__(self,
               exception: Optional[str] = '',
               replacements: Optional[List[Union[bool, int, str]]] = None):
    self.code = 4000
    self.message = ''
    self.exception = exception
    self.replacements = replacements
    super().__init__(exception, replacements)

  def __str__(self) -> str:
    string = ''

    if self.message:
      string = f'{self.message} '

    string += f'({self.code})'

    # TODO: Add exception file and lineno.
    if self.exception:
      string += f': {self.exception}'

    return string

def _new_err(code: int, message: str) -> Type[GlazierError]:
  """Captures code and message pairs for every error.

  This method acts to store the error codes and the associated messages to be
  passed to the GlazierException class.

  Args:
    code: Error code with an associated message
    message: Error message string with an associated code

  Returns:
    GlazierError exception with all required attributes.
  """

  class Error(GlazierError):
    """Stores error information used in GlazierError."""

    def __init__(self,
                 exception: Optional[str] = '',
                 replacements: Optional[List[Union[bool, int, str]]] = None):
      super().__init__(exception, replacements)
      self.code: int = code
      if message and replacements:
        # Asterisk is used to unpack the values of the list
        self.message: str = f'{message.format(*replacements)}'
      elif message:
        self.message: str = message

  return Error

################################################################################
# ERROR CODES (https://google.github.io/glazier/error_codes)             #
################################################################################
GReservedError = _new_err(1337, 'Reserved {} {} {}')
GUncaughtError = _new_err(4000, 'Uncaught exception')
GUnsupportedPEError = _new_err(4100, """
                  !!!!! Warning !!!!!

    This image is not running the latest WinPE version.

    This scenario typically occurs when you are booting off of an outdated
    .iso file. Please update before continuing.

    """)
GUnsupportedModelError = _new_err(
    4101, 'System OS/model does not have imaging support {}')
GConfigBuilderError = _new_err(4300, 'Failed to build the task list')
GConfigRunnerError = _new_err(4301, 'Failed to execute the task list')
GRegSetError = _new_err(4340, 'Failed to set registry value')
GWebServerError = _new_err(5000, 'Failed to reach web server')
GServiceError = _new_err(5300, 'Service unavailable')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (C) 2007-2010 Samalyse SARL

# This software is a computer program whose purpose is to backup, analyse,
# transcode and stream any audio content with its metadata over a web frontend.

# This software is governed by the CeCILL  license under French law and
# abiding by the rules of distribution of free software.  You can  use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".

# As a counterpart to the access to the source code and  rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty  and the software's author,  the holder of the
# economic rights,  and the successive licensors  have only  limited
# liability.

# In this respect, the user's attention is drawn to the risks associated
# with loading,  using,  modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean  that it is complicated to manipulate,  and  that  also
# therefore means  that it is reserved for developers  and  experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and,  more generally, to use and operate it in the
# same conditions as regards security.

# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
#
# Authors: Olivier Guilyardi <olivier@samalyse.com>
#          David LIPSZYC <davidlipszyc@gmail.com>

from telemeta.models.core import *
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes import generic
from notes.models import Note

class Enumeration(ModelCore):
    "Abstract enumerations base class"
    value = CharField(_('value'), required=True, unique=True)

    def __unicode__(self):
        return self.value

    class Meta(MetaCore):
        abstract = True

class MetaEnumeration(MetaCore):
    ordering = ['value']

class PhysicalFormat(Enumeration):
    "Collection physical format"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'physical_formats'
        verbose_name = _("archive format")

class PublishingStatus(Enumeration):
    "Collection publishing status"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'publishing_status'
        verbose_name = _("secondary edition")

class AcquisitionMode(Enumeration):
    "Mode of acquisition of the collection"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'acquisition_modes'
        verbose_name = _("mode of acquisition")

class MetadataAuthor(Enumeration):
    "Collection metadata author"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'metadata_authors'
        verbose_name = _("record author")

class MetadataWriter(Enumeration):
    "Collection metadata writer"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'metadata_writers'
        verbose_name = _("record writer")

class LegalRight(Enumeration):
    "Collection legal rights"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'legal_rights'
        verbose_name = _("legal rights")

class RecordingContext(Enumeration):
    "Collection recording context"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'recording_contexts'
        verbose_name = _("recording context")

class AdConversion(Enumeration):
    "Collection digital to analog conversion status"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'ad_conversions'
        verbose_name = _("A/D conversion")

class VernacularStyle(Enumeration):
    "Item vernacular style"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'vernacular_styles'
        verbose_name = _("vernacular style")

class GenericStyle(Enumeration):
    "Item generic style"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'generic_styles'
        verbose_name = _("generic style")

class ContextKeyword(Enumeration):
    "Keyword"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'context_keywords'
        verbose_name = _("keyword")

class Publisher(Enumeration):
    "Collection publisher"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'publishers'
        verbose_name = _("publisher / status")

class PublisherCollection(ModelCore):
    "Collection which belongs to publisher"

    publisher = ForeignKey('Publisher', related_name="publisher_collections", verbose_name=_('publisher'))
    value     = CharField(_('value'), required=True)
    notes     = generic.GenericRelation(Note)

    def __unicode__(self):
        return self.value

    class Meta(MetaCore):
        db_table = 'publisher_collections'
        ordering = ['value']

class EthnicGroup(Enumeration):
    "Item ethnic group"

    notes = generic.GenericRelation(Note)

    class Meta(MetaEnumeration):
        db_table = 'ethnic_groups'
        verbose_name = _('population / social group')

class EthnicGroupAlias(ModelCore):
    "Item ethnic group other name"

    ethnic_group = ForeignKey('EthnicGroup', related_name="aliases", verbose_name=_('population / social group'))
    value        = CharField(_('name'), required=True)
    notes        = generic.GenericRelation(Note)

    class Meta(MetaCore):
        db_table = 'ethnic_group_aliases'
        unique_together = (('ethnic_group', 'value'),)
        ordering = ['ethnic_group__value']

# Tape formats
class TapeWheelDiameter(Enumeration):
    "Tape wheel diameter (cm)"

    class Meta(MetaEnumeration):
        db_table = 'tape_wheel_diameter'
        verbose_name = _("tape wheel diameter (cm)")

class TapeLength(Enumeration):
    "Tape length (cm)"

    class Meta(MetaEnumeration):
        db_table = 'tape_length'
        verbose_name = _("tape length (cm)")

class TapeWidth(Enumeration):
    "Tape width (inch)"

    class Meta(MetaEnumeration):
        db_table = 'tape_width'
        verbose_name = _("tape width (inch)")

class TapeSpeed(Enumeration):
    "Tape speed (cm/s)"

    class Meta(MetaEnumeration):
        db_table = 'tape_speed'
        verbose_name = _("tape speed (cm/s)")

class TapeVendor(Enumeration):
    "Tape vendor"

    class Meta(MetaEnumeration):
        db_table = 'tape_vendor'
        verbose_name = _("tape vendor")

class NumberOfChannels(Enumeration):
    "Number of channels"

    class Meta(MetaEnumeration):
        db_table = 'original_channel_number'
        verbose_name = _("number of channels")

class Organization(Enumeration):
    "Organization"

    class Meta(MetaEnumeration):
        db_table = 'organization'
        verbose_name = _("organization")

class Rights(Enumeration):
    "Archive rights"

    class Meta(MetaEnumeration):
        db_table = 'rights'
        verbose_name = _("rights")

class Topic(Enumeration):
    "Topic, subject of the study, research, etc.."

    class Meta(MetaEnumeration):
        db_table = 'topic'
        verbose_name = _("topic")
<commit_msg>no notes but chat<commit_after># -*- coding: utf-8 -*-
# Copyright (C) 2007-2010 Samalyse SARL

# This software is a computer program whose purpose is to backup, analyse,
# transcode and stream any audio content with its metadata over a web frontend.

# This software is governed by the CeCILL  license under French law and
# abiding by the rules of distribution of free software.  You can  use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".

# As a counterpart to the access to the source code and  rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty  and the software's author,  the holder of the
# economic rights,  and the successive licensors  have only  limited
# liability.

# In this respect, the user's attention is drawn to the risks associated
# with loading,  using,  modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean  that it is complicated to manipulate,  and  that  also
# therefore means  that it is reserved for developers  and  experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and,  more generally, to use and operate it in the
# same conditions as regards security.

# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
#
# Authors: Olivier Guilyardi <olivier@samalyse.com>
#          David LIPSZYC <davidlipszyc@gmail.com>

from telemeta.models.core import *
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes import generic

class Enumeration(ModelCore):
    "Abstract enumerations base class"
    value = CharField(_('value'), required=True, unique=True)

    def __unicode__(self):
        return self.value

    class Meta(MetaCore):
        abstract = True

class MetaEnumeration(MetaCore):
    ordering = ['value']

class PhysicalFormat(Enumeration):
    "Collection physical format"

    class Meta(MetaEnumeration):
        db_table = 'physical_formats'
        verbose_name = _("archive format")

class PublishingStatus(Enumeration):
    "Collection publishing status"

    class Meta(MetaEnumeration):
        db_table = 'publishing_status'
        verbose_name = _("secondary edition")

class AcquisitionMode(Enumeration):
    "Mode of acquisition of the collection"

    class Meta(MetaEnumeration):
        db_table = 'acquisition_modes'
        verbose_name = _("mode of acquisition")

class MetadataAuthor(Enumeration):
    "Collection metadata author"

    class Meta(MetaEnumeration):
        db_table = 'metadata_authors'
        verbose_name = _("record author")

class MetadataWriter(Enumeration):
    "Collection metadata writer"

    class Meta(MetaEnumeration):
        db_table = 'metadata_writers'
        verbose_name = _("record writer")

class LegalRight(Enumeration):
    "Collection legal rights"

    class Meta(MetaEnumeration):
        db_table = 'legal_rights'
        verbose_name = _("legal rights")

class RecordingContext(Enumeration):
    "Collection recording context"

    class Meta(MetaEnumeration):
        db_table = 'recording_contexts'
        verbose_name = _("recording context")

class AdConversion(Enumeration):
    "Collection digital to analog conversion status"

    class Meta(MetaEnumeration):
        db_table = 'ad_conversions'
        verbose_name = _("A/D conversion")

class VernacularStyle(Enumeration):
    "Item vernacular style"

    class Meta(MetaEnumeration):
        db_table = 'vernacular_styles'
        verbose_name = _("vernacular style")

class GenericStyle(Enumeration):
    "Item generic style"

    class Meta(MetaEnumeration):
        db_table = 'generic_styles'
        verbose_name = _("generic style")

class ContextKeyword(Enumeration):
    "Keyword"

    class Meta(MetaEnumeration):
        db_table = 'context_keywords'
        verbose_name = _("keyword")

class Publisher(Enumeration):
    "Collection publisher"

    class Meta(MetaEnumeration):
        db_table = 'publishers'
        verbose_name = _("publisher / status")

class PublisherCollection(ModelCore):
    "Collection which belongs to publisher"

    publisher = ForeignKey('Publisher', related_name="publisher_collections", verbose_name=_('publisher'))
    value     = CharField(_('value'), required=True)

    def __unicode__(self):
        return self.value

    class Meta(MetaCore):
        db_table = 'publisher_collections'
        ordering = ['value']

class EthnicGroup(Enumeration):
    "Item ethnic group"

    class Meta(MetaEnumeration):
        db_table = 'ethnic_groups'
        verbose_name = _('population / social group')

class EthnicGroupAlias(ModelCore):
    "Item ethnic group other name"

    ethnic_group = ForeignKey('EthnicGroup', related_name="aliases", verbose_name=_('population / social group'))
    value        = CharField(_('name'), required=True)

    class Meta(MetaCore):
        db_table = 'ethnic_group_aliases'
        unique_together = (('ethnic_group', 'value'),)
        ordering = ['ethnic_group__value']

# Tape formats
class TapeWheelDiameter(Enumeration):
    "Tape wheel diameter (cm)"

    class Meta(MetaEnumeration):
        db_table = 'tape_wheel_diameter'
        verbose_name = _("tape wheel diameter (cm)")

class TapeLength(Enumeration):
    "Tape length (cm)"

    class Meta(MetaEnumeration):
        db_table = 'tape_length'
        verbose_name = _("tape length (cm)")

class TapeWidth(Enumeration):
    "Tape width (inch)"

    class Meta(MetaEnumeration):
        db_table = 'tape_width'
        verbose_name = _("tape width (inch)")

class TapeSpeed(Enumeration):
    "Tape speed (cm/s)"

    class Meta(MetaEnumeration):
        db_table = 'tape_speed'
        verbose_name = _("tape speed (cm/s)")

class TapeVendor(Enumeration):
    "Tape vendor"

    class Meta(MetaEnumeration):
        db_table = 'tape_vendor'
        verbose_name = _("tape vendor")

class NumberOfChannels(Enumeration):
    "Number of channels"

    class Meta(MetaEnumeration):
        db_table = 'original_channel_number'
        verbose_name = _("number of channels")

class Organization(Enumeration):
    "Organization"

    class Meta(MetaEnumeration):
        db_table = 'organization'
        verbose_name = _("organization")

class Rights(Enumeration):
    "Archive rights"

    class Meta(MetaEnumeration):
        db_table = 'rights'
        verbose_name = _("rights")

class Topic(Enumeration):
    "Topic, subject of the study, research, etc.."

    class Meta(MetaEnumeration):
        db_table = 'topic'
        verbose_name = _("topic")
<|endoftext|>


<commit_before>VERSION = (0, 0, 3)

def get_version():
    """Returns the version as a human-format string."""
    v = '.'.join([str(i) for i in VERSION])
    return v
<commit_msg>Bumped version to 0.0.4.<commit_after>VERSION = (0, 0, 4)

def get_version():
    """Returns the version as a human-format string."""
    v = '.'.join([str(i) for i in VERSION])
    return v
<|endoftext|>