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

import sys, os
import logging
import argparse
import json

import zlib
import zmq

from distutils.version import LooseVersion

import simplejson
from jsonschema import validate
import re

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, text
from sqlalchemy.sql.sqltypes import TIMESTAMP
from sqlalchemy.dialects.postgresql.json import JSON, JSONB

"""
 "  Configuration
"""
__relayEDDN       = 'tcp://eddn-relay.elite-markets.net:9500'
__timeoutEDDN       = 600000

# Set False to listen to production stream
__debugEDDN       = False

###########################################################################
# Configuration
###########################################################################
configfile_fd = os.open("eddnlistener-config.json", os.O_RDONLY)
configfile = os.fdopen(configfile_fd)
__config = json.load(configfile)
###########################################################################

"""
 "  Start
"""

###########################################################################
# Setup SQLAlchemy-related classes/data
###########################################################################
Base = declarative_base()
class Message(Base):
  __tablename__ = 'messages'

  id = Column(Integer, autoincrement=True, primary_key=True)
  received = Column(TIMESTAMP, nullable=False, server_default=text('NOW()'), index=True)
  message_raw = Column(JSON)
  message = Column(JSONB)
###########################################################################

###########################################################################
# Logging
###########################################################################
os.environ['TZ'] = 'UTC'
__default_loglevel = logging.INFO
logger = logging.getLogger('eddnlistener')
logger.setLevel(__default_loglevel)
logger_ch = logging.StreamHandler()
logger_ch.setLevel(__default_loglevel)
logger_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger_formatter.default_time_format = '%Y-%m-%d %H:%M:%S';
logger_formatter.default_msec_format = '%s.%03d'
logger_ch.setFormatter(logger_formatter)
logger.addHandler(logger_ch)
###########################################################################

###########################################################################
# Command-Line Arguments
###########################################################################
parser = argparse.ArgumentParser()
parser.add_argument("--loglevel", help="set the log level to one of: DEBUG, INFO (default), WARNING, ERROR, CRITICAL")
args = parser.parse_args()
if args.loglevel:
  level = getattr(logging, args.loglevel.upper())
  logger.setLevel(level)
  logger_ch.setLevel(level)
###########################################################################

def main():
  logger.info('Initialising Database Connection')
  db_engine = create_engine(__config['database']['url'])
  Base.metadata.create_all(db_engine)
  Session = sessionmaker(bind=db_engine)

  logger.info('Starting EDDN Subscriber')

  context   = zmq.Context()
  subscriber  = context.socket(zmq.SUB)

  subscriber.setsockopt(zmq.SUBSCRIBE, b"")
  subscriber.setsockopt(zmq.RCVTIMEO, __timeoutEDDN)

  while True:
    try:
      subscriber.connect(__relayEDDN)
      logger.info('Connect to ' + __relayEDDN)

      while True:
        __message   = subscriber.recv()

        if __message == False:
          subscriber.disconnect(__relayEDDN)
          logger.warning('Disconnect from ' + __relayEDDN)
          break

        logger.debug('Got a message')

        __message   = zlib.decompress(__message)
        if __message == False:
          logger.warning('Failed to decompress message')
          continue

        __json    = simplejson.loads(__message)
        if __json == False:
          logger.warning('Failed to parse message as json')
          continue
        #logger.info(__json)

        ###############################################################
        # Validate message against relevant schema
        ###############################################################
        if not '$schemaRef' in __json:
          logger.warning("Message doesn't have a $schemaRef")
          continue

        # Pull the schema part out
        __schema = re.match('^http:\/\/schemas\.elite-markets\.net\/eddn\/(?P<part>[^\/]+)\/[0-9]+', __json['$schemaRef'])
        if not __schema:
          logger.warning("$schemaRef did not match regex: " + __json['$schemaRef'])
          continue

        if not __schema.group('part'):
          logger.warning("Couldn't find 'part' in $schemaRef" + __json['$schemaRef'])
          continue

        __knownSchema = False
        for s in __config['schemas']:
          if __schema.group('part') == s.get('name'):
            __knownSchema = True
            schemainfo = s
            break
        if not __knownSchema:
          logger.warning("Unknown schema: " + __json['$schemaRef'])
          continue

        if not schemainfo['message_schema'] == __json['$schemaRef']:
          logger.warning("In-message %schemaRef (" + __json['$schemaRef'] + ") doesn't precisely match expected schemaRef (" + schemainfo['message_schema'] + ")")
          continue

        if not schemainfo.get('schema'):
          logger.debug("Schema '" + __schema.group('part') + "' not yet loaded, doing so...")
          filename = "schemas/" + schemainfo['local_schema']
          schema_fd = open(filename, 'rt')
          schema_str = schema_fd.read(None)
          schemainfo['schema'] = simplejson.loads(schema_str)
          schema_fd.close()
          #logger.debug("loaded schema: " + schemainfo['schema'])

        #logger.debug("validate on received json: " + str(__json))
        try:
          validate(__json, schemainfo['schema'])
          logger.debug("Message validates against schema.")
        except SchemaError as e:
          logger.warning("Schema for " + __schema.group('part') + " wasn't valid")
          continue
        except ValidationError as e:
          logger.warning("Message failed to validate against schema")
        ###############################################################

        ###############################################################
        # Check against blacklist
        ###############################################################
        blackListed = False
        logger.debug('Checking softwareName: ' + __json['header']['softwareName'])
        for b in __config['blacklist']:
          logger.debug('Checking softwareName against' + b.get('softwarename'))
          if __json['header']['softwareName'].lower() == b.get('softwarename').lower():
            logger.debug('Matching softwareName found, checking if we have version preference')
            if b.get('goodversion'):
              logger.debug('We have known good version of: ' + b.get('goodversion'))
              if LooseVersion(__json['header']['softwareVersion']) < LooseVersion(b.get('goodversion')):
                logger.debug(__json['header']['softwareVersion'] + ' < ' + b.get('goodversion'))
                blackListed = True
            else:
              blackListed = True

          if blackListed == True:
            logger.info("Blacklisted softwareName: " + __json['header']['softwareName'])
            break
        ###############################################################

        ###############################################################
        # Insert data into database
        ###############################################################
        db_msg = Message(message_raw=__json, message=__json)
        session = Session()
        session.add(db_msg)
        session.commit()
        ###############################################################

    except zmq.ZMQError as e:
      logger.error('ZMQSocketException: ' + str(e))
      subscriber.disconnect(__relayEDDN)
      logger.warning('Disconnect from ' + __relayEDDN)
      time.sleep(5)

if __name__ == '__main__':
  main()
<commit_msg>Cleans up logger.debug() use for softwareName/Version checking<commit_after>#!/usr/bin/env python3
#
#
#

import sys, os
import logging
import argparse
import json

import zlib
import zmq

from distutils.version import LooseVersion

import simplejson
from jsonschema import validate
import re

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, text
from sqlalchemy.sql.sqltypes import TIMESTAMP
from sqlalchemy.dialects.postgresql.json import JSON, JSONB

"""
 "  Configuration
"""
__relayEDDN       = 'tcp://eddn-relay.elite-markets.net:9500'
__timeoutEDDN       = 600000

# Set False to listen to production stream
__debugEDDN       = False

###########################################################################
# Configuration
###########################################################################
configfile_fd = os.open("eddnlistener-config.json", os.O_RDONLY)
configfile = os.fdopen(configfile_fd)
__config = json.load(configfile)
###########################################################################

"""
 "  Start
"""

###########################################################################
# Setup SQLAlchemy-related classes/data
###########################################################################
Base = declarative_base()
class Message(Base):
  __tablename__ = 'messages'

  id = Column(Integer, autoincrement=True, primary_key=True)
  received = Column(TIMESTAMP, nullable=False, server_default=text('NOW()'), index=True)
  message_raw = Column(JSON)
  message = Column(JSONB)
###########################################################################

###########################################################################
# Logging
###########################################################################
os.environ['TZ'] = 'UTC'
__default_loglevel = logging.INFO
logger = logging.getLogger('eddnlistener')
logger.setLevel(__default_loglevel)
logger_ch = logging.StreamHandler()
logger_ch.setLevel(__default_loglevel)
logger_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger_formatter.default_time_format = '%Y-%m-%d %H:%M:%S';
logger_formatter.default_msec_format = '%s.%03d'
logger_ch.setFormatter(logger_formatter)
logger.addHandler(logger_ch)
###########################################################################

###########################################################################
# Command-Line Arguments
###########################################################################
parser = argparse.ArgumentParser()
parser.add_argument("--loglevel", help="set the log level to one of: DEBUG, INFO (default), WARNING, ERROR, CRITICAL")
args = parser.parse_args()
if args.loglevel:
  level = getattr(logging, args.loglevel.upper())
  logger.setLevel(level)
  logger_ch.setLevel(level)
###########################################################################

def main():
  logger.info('Initialising Database Connection')
  db_engine = create_engine(__config['database']['url'])
  Base.metadata.create_all(db_engine)
  Session = sessionmaker(bind=db_engine)

  logger.info('Starting EDDN Subscriber')

  context   = zmq.Context()
  subscriber  = context.socket(zmq.SUB)

  subscriber.setsockopt(zmq.SUBSCRIBE, b"")
  subscriber.setsockopt(zmq.RCVTIMEO, __timeoutEDDN)

  while True:
    try:
      subscriber.connect(__relayEDDN)
      logger.info('Connect to ' + __relayEDDN)

      while True:
        __message   = subscriber.recv()

        if __message == False:
          subscriber.disconnect(__relayEDDN)
          logger.warning('Disconnect from ' + __relayEDDN)
          break

        logger.debug('Got a message')

        __message   = zlib.decompress(__message)
        if __message == False:
          logger.warning('Failed to decompress message')
          continue

        __json    = simplejson.loads(__message)
        if __json == False:
          logger.warning('Failed to parse message as json')
          continue
        #logger.info(__json)

        ###############################################################
        # Validate message against relevant schema
        ###############################################################
        if not '$schemaRef' in __json:
          logger.warning("Message doesn't have a $schemaRef")
          continue

        # Pull the schema part out
        __schema = re.match('^http:\/\/schemas\.elite-markets\.net\/eddn\/(?P<part>[^\/]+)\/[0-9]+', __json['$schemaRef'])
        if not __schema:
          logger.warning("$schemaRef did not match regex: " + __json['$schemaRef'])
          continue

        if not __schema.group('part'):
          logger.warning("Couldn't find 'part' in $schemaRef" + __json['$schemaRef'])
          continue

        __knownSchema = False
        for s in __config['schemas']:
          if __schema.group('part') == s.get('name'):
            __knownSchema = True
            schemainfo = s
            break
        if not __knownSchema:
          logger.warning("Unknown schema: " + __json['$schemaRef'])
          continue

        if not schemainfo['message_schema'] == __json['$schemaRef']:
          logger.warning("In-message %schemaRef (" + __json['$schemaRef'] + ") doesn't precisely match expected schemaRef (" + schemainfo['message_schema'] + ")")
          continue

        if not schemainfo.get('schema'):
          logger.debug("Schema '" + __schema.group('part') + "' not yet loaded, doing so...")
          filename = "schemas/" + schemainfo['local_schema']
          schema_fd = open(filename, 'rt')
          schema_str = schema_fd.read(None)
          schemainfo['schema'] = simplejson.loads(schema_str)
          schema_fd.close()
          #logger.debug("loaded schema: " + schemainfo['schema'])

        #logger.debug("validate on received json: " + str(__json))
        try:
          validate(__json, schemainfo['schema'])
          logger.debug("Message validates against schema.")
        except SchemaError as e:
          logger.warning("Schema for " + __schema.group('part') + " wasn't valid")
          continue
        except ValidationError as e:
          logger.warning("Message failed to validate against schema")
        ###############################################################

        ###############################################################
        # Check against blacklist
        ###############################################################
        blackListed = False
        logger.debug('Checking softwareName: ' + __json['header']['softwareName'])
        for b in __config['blacklist']:
          #logger.debug('Checking softwareName against' + b.get('softwarename'))
          if __json['header']['softwareName'].lower() == b.get('softwarename').lower():
            #logger.debug('Matching softwareName "' + b.get('softwarename') + '"found, checking if we have version preference')
            if b.get('goodversion'):
              #logger.debug('We have known good version of: ' + b.get('goodversion'))
              if LooseVersion(__json['header']['softwareVersion']) < LooseVersion(b.get('goodversion')):
                logger.debug('Blacklisted as ' + __json['header']['softwareVersion'] + ' < ' + b.get('goodversion'))
                blackListed = True
            else:
              logger.debug('Blacklisted ALL versions')
              blackListed = True

          if blackListed == True:
            logger.info('Blacklisted ' + __json['header']['softwareName'] + '(' + __json['header']['softwareVersion'] + ')')
            break
        ###############################################################

        ###############################################################
        # Insert data into database
        ###############################################################
        db_msg = Message(message_raw=__json, message=__json)
        session = Session()
        session.add(db_msg)
        session.commit()
        ###############################################################

    except zmq.ZMQError as e:
      logger.error('ZMQSocketException: ' + str(e))
      subscriber.disconnect(__relayEDDN)
      logger.warning('Disconnect from ' + __relayEDDN)
      time.sleep(5)

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


<commit_before>import unittest
import os
import uuid

from studio.gcloud_worker import GCloudWorkerManager
from studio.ec2cloud_worker import EC2WorkerManager
from local_worker_test import stubtest_worker

from timeout_decorator import timeout
from studio.util import has_aws_credentials

@unittest.skipIf(
    'GOOGLE_APPLICATION_CREDENTIALS' not in os.environ.keys(),
    'GOOGLE_APPLICATION_CREDENTIALS environment ' +
    'variable not set, won'' be able to use google cloud')
class GCloudWorkerTest(unittest.TestCase):
    _multiprocess_shared_ = True

    def get_worker_manager(self):
        project = 'studio-ed756'
        return GCloudWorkerManager(project)

    @timeout(600, use_signals=False)
    def test_worker(self):
        experiment_name = 'test_gcloud_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcloud', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot(self):
        experiment_name = 'test_gcloud_spot_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcspot', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot_container(self):
        experiment_name = 'test_gcloud_spot_simg_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcspot',
                         '--force-git',
                         '--cloud-timeout=120',
                         '--container=shub://vsoch/hello-world'],

            config_name='test_config_http_client.yaml',
            test_script='',
            script_args=[],
            expected_output='RaawwWWWWWRRRR!!',
            test_workspace=False
        ):
            pass

@unittest.skipIf(
    not has_aws_credentials(),
    'boto3 not present, won\'t be able to use AWS API')
class EC2WorkerTest(unittest.TestCase):
    _multiprocess_shared_ = True

    def get_worker_manager(self):
        return EC2WorkerManager()

    @timeout(600, use_signals=False)
    def test_worker(self):
        experiment_name = 'test_ec2_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=ec2', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot(self):
        experiment_name = 'test_ec2_worker_' + str(uuid.uuid4())
        stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=[
                '--cloud=ec2spot',
                '--force-git',
                '--bid=50%',
                '--cloud-timeout=120',
            ],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        )

    def test_get_ondemand_prices(self):
        wm = self.get_worker_manager()
        prices = wm._get_ondemand_prices(['c4.large', 'p2.xlarge'])

        expected_prices = {'c4.large': 0.1, 'p2.xlarge': 0.9}
        self.assertEquals(prices, expected_prices)

    @timeout(600, use_signals=False)
    def test_worker_spot_container(self):
        experiment_name = 'test_gcloud_spot_simg_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=ec2spot',
                         '--force-git',
                         '--cloud-timeout=120',
                         '--container=shub://vsoch/hello-world'],

            config_name='test_config_http_client.yaml',
            test_script='',
            script_args=[],
            expected_output='RaawwWWWWWRRRR!!',
            test_workspace=False
        ):
            pass

if __name__ == '__main__':
    unittest.main()
<commit_msg>added key to cloud_worker_test.EC2WorkerTest.test_worker_spot_container for debugging<commit_after>import unittest
import os
import uuid

from studio.gcloud_worker import GCloudWorkerManager
from studio.ec2cloud_worker import EC2WorkerManager
from local_worker_test import stubtest_worker

from timeout_decorator import timeout
from studio.util import has_aws_credentials

@unittest.skipIf(
    'GOOGLE_APPLICATION_CREDENTIALS' not in os.environ.keys(),
    'GOOGLE_APPLICATION_CREDENTIALS environment ' +
    'variable not set, won'' be able to use google cloud')
class GCloudWorkerTest(unittest.TestCase):
    _multiprocess_shared_ = True

    def get_worker_manager(self):
        project = 'studio-ed756'
        return GCloudWorkerManager(project)

    @timeout(600, use_signals=False)
    def test_worker(self):
        experiment_name = 'test_gcloud_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcloud', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot(self):
        experiment_name = 'test_gcloud_spot_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcspot', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot_container(self):
        experiment_name = 'test_gcloud_spot_simg_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=gcspot',
                         '--force-git',
                         '--cloud-timeout=120',
                         '--container=shub://vsoch/hello-world'],

            config_name='test_config_http_client.yaml',
            test_script='',
            script_args=[],
            expected_output='RaawwWWWWWRRRR!!',
            test_workspace=False
        ):
            pass

@unittest.skipIf(
    not has_aws_credentials(),
    'boto3 not present, won\'t be able to use AWS API')
class EC2WorkerTest(unittest.TestCase):
    _multiprocess_shared_ = True

    def get_worker_manager(self):
        return EC2WorkerManager()

    @timeout(600, use_signals=False)
    def test_worker(self):
        experiment_name = 'test_ec2_worker_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=ec2', '--force-git',
                         '--cloud-timeout=120'],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        ):
            pass

    @timeout(600, use_signals=False)
    def test_worker_spot(self):
        experiment_name = 'test_ec2_worker_' + str(uuid.uuid4())
        stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=[
                '--cloud=ec2spot',
                '--force-git',
                '--bid=50%',
                '--cloud-timeout=120',
            ],
            config_name='test_config_http_client.yaml',
            test_script='tf_hello_world.py',
            script_args=['arg0'],
            expected_output='[ 2.  6.]',
        )

    def test_get_ondemand_prices(self):
        wm = self.get_worker_manager()
        prices = wm._get_ondemand_prices(['c4.large', 'p2.xlarge'])

        expected_prices = {'c4.large': 0.1, 'p2.xlarge': 0.9}
        self.assertEquals(prices, expected_prices)

    @timeout(600, use_signals=False)
    def test_worker_spot_container(self):
        experiment_name = 'test_gcloud_spot_simg_' + str(uuid.uuid4())
        with stubtest_worker(
            self,
            experiment_name=experiment_name,
            runner_args=['--cloud=ec2spot',
                         '--force-git',
                         '--cloud-timeout=120',
                         '--ssh-keypair=peterz-k1',
                         '--container=shub://vsoch/hello-world'],

            config_name='test_config_http_client.yaml',
            test_script='',
            script_args=[],
            expected_output='RaawwWWWWWRRRR!!',
            test_workspace=False
        ):
            pass

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>
DEBUG = True

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'dev.db',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

STUDLAN_FROM_MAIL = 'studlan@online.ntnu.no'
<commit_msg>Added email backend to local settings example file.<commit_after>
DEBUG = True

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'dev.db',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

STUDLAN_FROM_MAIL = 'studlan@online.ntnu.no'

#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  # real
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'  # prints
<|endoftext|>


<commit_before>from _external import *

opencv = LibWithHeaderChecker(['cv', 'cxcore',  'cvaux', 'highgui','ml'],
                              'opencv/cv.h', 'c', name='opencv')
<commit_msg>opencv 2.2<commit_after>from _external import *

opencv = LibWithHeaderChecker(['opencv_core', 'opencv_video', 'opencv_calib3d', 'opencv_highgui', 'opencv_imgproc', 'opencv_ml'],
                              'opencv/cv.h', 'c', name='opencv')
<|endoftext|>


<commit_before>from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.db import ProgrammingError
from django.forms.models import model_to_dict
from django.shortcuts import redirect
from django.shortcuts import render, HttpResponseRedirect

from gollahalli_com.utils import format_date_time
from .forms import ContentFormModel
from .models import ContentModel

# ============================================================================================
#                                       Form Main
# ============================================================================================

def portal_home(request):
    """
    Portal Home page.

    Parameters
    ----------
    request: WSGIRequest
        WSGI request.

    Returns
    -------
    render: HttpResponse
        Returns renderer's.
    """
    template = 'portal/portal_index.html'

    context = {}

    return render(request, template, context)

@login_required
def editor_home(request):
    template = "portal/editor/editor_index.html"

    try:
        content = ContentModel.objects.get(ref_id='1')
    except ContentModel.DoesNotExist:
        content = False

    context = {'content': content}
    return render(request, template, context)

<commit_msg>docs updated<commit_after>from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.db import ProgrammingError
from django.forms.models import model_to_dict
from django.shortcuts import redirect
from django.shortcuts import render, HttpResponseRedirect

from gollahalli_com.utils import format_date_time
from .forms import ContentFormModel
from .models import ContentModel

# ============================================================================================
#                                       Form Main
# ============================================================================================

def portal_home(request):
    """
    Portal Home page.

    Parameters
    ----------
    request: WSGIRequest
        WSGI request.

    Returns
    -------
    render: HttpResponse
        Returns renderer's.
    """
    template = 'portal/portal_index.html'

    context = {}

    return render(request, template, context)

@login_required
def editor_home(request):
    """
    Editor home page.

    Parameters
    ----------
    request: WSGIRequest
        WSGI request.

    Returns
    -------
    render: HttpResponse
        Returns renderer's.
    """
    template = "portal/editor/editor_index.html"

    try:
        content = ContentModel.objects.get(ref_id='1')
    except ContentModel.DoesNotExist:
        content = False

    context = {'content': content}
    return render(request, template, context)

<|endoftext|>


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

# Autheur: Matthieu Riou <matthieu.riou@etu.univ-nantes.fr>
# Version: v0.1
# Versions de python supportées: 3.3+ (à cause d'icalendar)
# Dépendances: icalendar, requests (pip install ; utiliser virtualenvwrapper)
# Notes: Pour choisir les groupes, aller remplir la fonction à la toute
# fin du programme.
# ToDo: Développer une interface graphique.

try:
        import codecs # support des encodages
        from datetime import datetime # time manipulation functions
        from datetime import time
        from icalendar import Calendar # support des .ics
        import locale # support of local locale (oh really ?), and internationalization
        import pytz # accurate timezone calculations
        from pytz import utc
        import requests # permet de réaliser simplement (plus qu'avec urllib2) des
        # requêtes HTTP
        import getpass # permet d'utilier getpass.getpass([prompt[, stream]]) pour
        # demander un mot de passe
except ImportError:
        raise ImportError("Modules are required to run this program. Try `pip install icalendar requests`.")
        exit

# VARIABLE GLOBALES
correspondance_group_tab = {"L3_Info" : "g11529", "M1_Atal" : "g78030", "L2_401" : "g93283", "L2_402" : "g115774", "L2_419" : "g7127","M1_Alma" : "g6935","M1_Oro" : "g9238", "L1_245" : "g51728", "L1_247" : "g94501", "L1_248" : "g115113", "L1_243K" : "g7057"}
horaire_to_heure = ["8h00", "9h30", "11h00", "12h30", "14h00", "15h30", "17h00", "18h30"]

# VARIABLES GLOBALES à décommenter pour accélérer les tests (default: "")
# login = ""
# mdp = ""

class GestionDatetime:

	def __init__(self):
		self.paris = pytz.timezone('Europe/Paris')
		self.format = "%Y%m%dT%H%M%SZ"
        #datefind = datetime(2014, 4, 16, 11) # careful: 04 is invalid. 4
        # is. (octal numbers not allowed in python!)
        #find = datefind.strftime("%d/%m/%Y/%Hh%M")
        #ffind = utc.localize(datefind)
        #fffind = ffind.astimezone(paris)

	def getDatetime(self, my_date):
		date = my_date.to_ical()
		dtutcdate = utc.localize(datetime.strptime(date.decode(), self.format))
		dtdate = dtutcdate.astimezone(self.paris)

		return dtdate

class Connexion:

	def __init__(self):
		self.login = input("Login : ")
		self.mdp = getpass.getpass("Mot de passe : ")

		self.correspondance_group_tab = {"L3_Info" : "g11529", "M1_Atal" : "g78030", "L2_401" : "g93283", "L2_402" : "g115774", "L2_419" : "g7127","M1_Alma" : "g6935","M1_Oro" : "g9238", "L1_245" : "g51728", "L1_247" : "g94501", "L1_248" : "g115113", "L1_243K" : "g7057"}

	def connect(self, group):
		code_group = self.correspondance_group_tab[group]

		request = requests.get(
						'https://edt.univ-nantes.fr/sciences/' + code_group + '.ics',
						auth=(self.login, self.mdp),
						timeout=2)
		if not 200 <= request.status_code < 300:
			print("Error status while retrieving the ics file for group " + group + ".")
			exit

		return request

class Edt:

	def __init__(self):
		self.start = 2 #Semaine de départ
		self.end = 20 #Semaine de fin
		self.nbWeek = self.end - self.start + 1
		self.nbDayInWeek = 6 #Nombre de jour par semaine
		self.nbSlotInDay = 8 #Nombre de créneaux par jour

		self.connexion = Connexion()
		self.edt = {}

		self.nbSlot = self.nbWeek * self.nbDayInWeek * self.nbSlotInDay

		self.gestionDate = GestionDatetime()

	def addEdt(self, group):
		if group not in self.edt:
			e = self.connexion.connect(group)
			self.edt[group] = self.analyseEdt(e)

	def analyseEdt(self, edt):

		slots = [1]*self.nbSlot #At the beggining, all the slots are free

		for component in Calendar.from_ical(edt.text).walk():
			if component.name == 'VEVENT':
				start = self.gestionDate.getDatetime(component.get('DTSTART'))
				end = self.gestionDate.getDatetime(component.get('DTEND'))

				getCrenaux(slots, start, end)

		return slots

	def compare(self, list_groups):
		if not all(group in self.edt for group in list_groups) : #try except ?
			print("Erreur, groupe non présent")
			exit(1)

		res = []

		for group in list_groups:
			#Hou ! Le vilain test à chaque tour de boucle pour un seul cas qui se retrouve ici maintenant !
			#Mais j'ai pas trop trouvé comment faire autrement. Iterateur ?
			if len(res) == 0:
				res = self.edt[group]
			else:
				res = map(etbit, res, self.edt[group]) #No need to convert it in list here, because we'll just iterate over it (with an other map)

		return list(res) #Must be convert here, because we want to return a list, and not an iterators (map object)

	def compareAll(self):
		if len(self.edt) == 0: #try except ?
			print("Erreur, il faut des groupes à comparer")
			exit(1)

		return self.compare(self.edt)

def getCrenaux(crenaux, start, end): #Pour le semestre 2 de 2014

	isodate = start.isocalendar() #tuple (annee, semaine, jour de 1 a 7)

	index = (isodate[1]-2) * 48
	index = index + (isodate[2]-1) * 8

	if intersect(time(8), time(9, 20), start.time(), end.time()):
		crenaux[index + 0] = 0

	if intersect(time(9, 30), time(10, 50), start.time(), end.time()):
		crenaux[index + 1] = 0

	if intersect(time(11), time(12, 20), start.time(), end.time()):
		crenaux[index + 2] = 0

	if intersect(time(12, 30), time(13, 50), start.time(), end.time()):
		crenaux[index + 3] = 0

	if intersect(time(14), time(15, 20), start.time(), end.time()):
		crenaux[index + 4] = 0

	if intersect(time(15, 30), time(16, 50), start.time(), end.time()):
		crenaux[index + 5] = 0

	if intersect(time(17), time(18, 20), start.time(), end.time()):
		crenaux[index + 6] = 0

def intersect(start1, end1, start2, end2):
        return (start1 <= start2 <= end1) or (start2 <= start1 <= end2)

def analyseEdtForGroups(liste_group):
	connexion = Connexion()

	liste_result = []
	for group in liste_group:
		edt = connexion.connect(group) 			#getEdt
		liste_result.append(analyseEdt(edt))	#analyseEdt

	return list(liste_result)

def etbit(x, y): # comparaison logique d'indices de deux horaires
        # identique de deux groupes différents
        return x & y

def compare_local(crenaux1, crenaux2):
        result = map(etbit, crenaux1, crenaux2)
        return result

def compare(liste_crenaux):
	if len(liste_crenaux) == 1:
		return list(liste_crenaux[0])
	else:
		crenaux1 = liste_crenaux.pop()
		crenaux2 = liste_crenaux.pop()
		liste_crenaux.append(compare_local(crenaux1, crenaux2))
		return compare(liste_crenaux)

def affiche_result(liste):
	for i, item in enumerate(liste):
		if item == 1:
			affiche_creneau(i)

def affiche_creneau(x): # indice x. en fonction de l'indice qui varie de 1
        # à 912, on affiche les semaine, jour et horaire de l'indice.
        semaine = int(x / 48)
        jour = int((x - semaine*48) / 8)
        horaire = int(x - semaine*48 - jour*8)

        heure = horaire_to_heure[horaire]

        if jour + 1 != 6 and heure != "12h30" and heure != "18h30" and semaine+2 == 18:
                print("Semaine {} jour {} horaire {}".format(semaine+2, jour+1, heure))

def correspondance_group(group):
        global correspondance_group_tab
        return correspondance_group_tab[group]

def main(tableauGroupe): # raccourci final d'utilisation
	try:
		edt = Edt()
		edt.addEdt("L1_245")
		edt.addEdt("L1_248")
		affiche_result(edt.compareAll())
	except (KeyboardInterrupt, SystemExit):
		exit # quitte sans rien dire pour les évènements Ctrl-C, Ctrl-Q

# main(["L1_245", "L1_247", "L1_248", "L1_243K", "L2_401", "L2_402",
#       "L2_419", "M1_Alma", "M1_Atal", "M1_Oro"])
main(["L1_245", "L1_248"])
<commit_msg>Remove useless functions<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Autheur: Matthieu Riou <matthieu.riou@etu.univ-nantes.fr>
# Version: v0.1
# Versions de python supportées: 3.3+ (à cause d'icalendar)
# Dépendances: icalendar, requests (pip install ; utiliser virtualenvwrapper)
# Notes: Pour choisir les groupes, aller remplir la fonction à la toute
# fin du programme.
# ToDo: Développer une interface graphique.

try:
        import codecs # support des encodages
        from datetime import datetime # time manipulation functions
        from datetime import time
        from icalendar import Calendar # support des .ics
        import locale # support of local locale (oh really ?), and internationalization
        import pytz # accurate timezone calculations
        from pytz import utc
        import requests # permet de réaliser simplement (plus qu'avec urllib2) des
        # requêtes HTTP
        import getpass # permet d'utilier getpass.getpass([prompt[, stream]]) pour
        # demander un mot de passe
except ImportError:
        raise ImportError("Modules are required to run this program. Try `pip install icalendar requests`.")
        exit

# VARIABLE GLOBALES
correspondance_group_tab = {"L3_Info" : "g11529", "M1_Atal" : "g78030", "L2_401" : "g93283", "L2_402" : "g115774", "L2_419" : "g7127","M1_Alma" : "g6935","M1_Oro" : "g9238", "L1_245" : "g51728", "L1_247" : "g94501", "L1_248" : "g115113", "L1_243K" : "g7057"}
horaire_to_heure = ["8h00", "9h30", "11h00", "12h30", "14h00", "15h30", "17h00", "18h30"]

# VARIABLES GLOBALES à décommenter pour accélérer les tests (default: "")
# login = ""
# mdp = ""

class GestionDatetime:

	def __init__(self):
		self.paris = pytz.timezone('Europe/Paris')
		self.format = "%Y%m%dT%H%M%SZ"
        #datefind = datetime(2014, 4, 16, 11) # careful: 04 is invalid. 4
        # is. (octal numbers not allowed in python!)
        #find = datefind.strftime("%d/%m/%Y/%Hh%M")
        #ffind = utc.localize(datefind)
        #fffind = ffind.astimezone(paris)

	def getDatetime(self, my_date):
		date = my_date.to_ical()
		dtutcdate = utc.localize(datetime.strptime(date.decode(), self.format))
		dtdate = dtutcdate.astimezone(self.paris)

		return dtdate

class Connexion:

	def __init__(self):
		self.login = input("Login : ")
		self.mdp = getpass.getpass("Mot de passe : ")

		self.correspondance_group_tab = {"L3_Info" : "g11529", "M1_Atal" : "g78030", "L2_401" : "g93283", "L2_402" : "g115774", "L2_419" : "g7127","M1_Alma" : "g6935","M1_Oro" : "g9238", "L1_245" : "g51728", "L1_247" : "g94501", "L1_248" : "g115113", "L1_243K" : "g7057"}

	def connect(self, group):
		code_group = self.correspondance_group_tab[group]

		request = requests.get(
						'https://edt.univ-nantes.fr/sciences/' + code_group + '.ics',
						auth=(self.login, self.mdp),
						timeout=2)
		if not 200 <= request.status_code < 300:
			print("Error status while retrieving the ics file for group " + group + ".")
			exit

		return request

class Edt:

	def __init__(self):
		self.start = 2 #Semaine de départ
		self.end = 20 #Semaine de fin
		self.nbWeek = self.end - self.start + 1
		self.nbDayInWeek = 6 #Nombre de jour par semaine
		self.nbSlotInDay = 8 #Nombre de créneaux par jour

		self.connexion = Connexion()
		self.edt = {}

		self.nbSlot = self.nbWeek * self.nbDayInWeek * self.nbSlotInDay

		self.gestionDate = GestionDatetime()

	def addEdt(self, group):
		if group not in self.edt:
			e = self.connexion.connect(group)
			self.edt[group] = self.analyseEdt(e)

	def analyseEdt(self, edt):

		slots = [1]*self.nbSlot #At the beggining, all the slots are free

		for component in Calendar.from_ical(edt.text).walk():
			if component.name == 'VEVENT':
				start = self.gestionDate.getDatetime(component.get('DTSTART'))
				end = self.gestionDate.getDatetime(component.get('DTEND'))

				getCrenaux(slots, start, end)

		return slots

	def compare(self, list_groups):
		if not all(group in self.edt for group in list_groups) : #try except ?
			print("Erreur, groupe non présent")
			exit(1)

		res = []

		for group in list_groups:
			#Hou ! Le vilain test à chaque tour de boucle pour un seul cas qui se retrouve ici maintenant !
			#Mais j'ai pas trop trouvé comment faire autrement. Iterateur ?
			if len(res) == 0:
				res = self.edt[group]
			else:
				res = map(etbit, res, self.edt[group]) #No need to convert it in list here, because we'll just iterate over it (with an other map)

		return list(res) #Must be convert here, because we want to return a list, and not an iterators (map object)

	def compareAll(self):
		if len(self.edt) == 0: #try except ?
			print("Erreur, il faut des groupes à comparer")
			exit(1)

		return self.compare(self.edt)

def getCrenaux(crenaux, start, end): #Pour le semestre 2 de 2014

	isodate = start.isocalendar() #tuple (annee, semaine, jour de 1 a 7)

	index = (isodate[1]-2) * 48
	index = index + (isodate[2]-1) * 8

	if intersect(time(8), time(9, 20), start.time(), end.time()):
		crenaux[index + 0] = 0

	if intersect(time(9, 30), time(10, 50), start.time(), end.time()):
		crenaux[index + 1] = 0

	if intersect(time(11), time(12, 20), start.time(), end.time()):
		crenaux[index + 2] = 0

	if intersect(time(12, 30), time(13, 50), start.time(), end.time()):
		crenaux[index + 3] = 0

	if intersect(time(14), time(15, 20), start.time(), end.time()):
		crenaux[index + 4] = 0

	if intersect(time(15, 30), time(16, 50), start.time(), end.time()):
		crenaux[index + 5] = 0

	if intersect(time(17), time(18, 20), start.time(), end.time()):
		crenaux[index + 6] = 0

def intersect(start1, end1, start2, end2):
        return (start1 <= start2 <= end1) or (start2 <= start1 <= end2)

def etbit(x, y): # comparaison logique d'indices de deux horaires
        # identique de deux groupes différents
        return x & y

def affiche_result(liste):
	for i, item in enumerate(liste):
		if item == 1:
			affiche_creneau(i)

def affiche_creneau(x): # indice x. en fonction de l'indice qui varie de 1
        # à 912, on affiche les semaine, jour et horaire de l'indice.
        semaine = int(x / 48)
        jour = int((x - semaine*48) / 8)
        horaire = int(x - semaine*48 - jour*8)

        heure = horaire_to_heure[horaire]

        if jour + 1 != 6 and heure != "12h30" and heure != "18h30" and semaine+2 == 18:
                print("Semaine {} jour {} horaire {}".format(semaine+2, jour+1, heure))

def main(tableauGroupe): # raccourci final d'utilisation
	try:
		edt = Edt()
		edt.addEdt("L1_245")
		edt.addEdt("L1_248")
		affiche_result(edt.compareAll())
	except (KeyboardInterrupt, SystemExit):
		exit # quitte sans rien dire pour les évènements Ctrl-C, Ctrl-Q

# main(["L1_245", "L1_247", "L1_248", "L1_243K", "L2_401", "L2_402",
#       "L2_419", "M1_Alma", "M1_Atal", "M1_Oro"])
main(["L1_245", "L1_248"])
<|endoftext|>


<commit_before>from uuid import uuid4

class TransactionManager:

    def __init__(self):
        self.transactions = []

    def __begin_transaction(self, cursor):
        cursor.execute('BEGIN;')
        return (cursor, uuid4())

    def __prepare_transaction(self, transaction):
        cursor, transaction_id = transaction
        cursor.execute('PREPARE TRANSACTION \'%s\';'%transaction_id)
        print 'Prepared transaction %s'%transaction_id
        self.transactions.append(transaction)

    def __add_queries(self, cursor, queries):
        transaction = self.__begin_transaction(cursor)
        for q in queries:
            cursor.execute(q)
        self.__prepare_transaction(transaction)

    def add_transaction(self, cursor, queries):
        try:
            self.__add_queries(cursor, queries)
        except Exception:
            self.rollback_transactions()
            return False
        return True

    def commit_transactions(self):
        for cursor, transaction_id in self.transactions:
            print 'Commiting %s'%transaction_id
            cursor.execute('COMMIT PREPARED \'%s\';'%transaction_id)

    def rollback_transactions(self):
        for cursor, transaction_id in self.transactions:
            print 'Rolling back %s'%transaction_id
            cursor.execute('ROLLBACK PREPARED \'%s\';'%transaction_id)
        self.transactions = []

<commit_msg>Updated TM: print stack trace<commit_after>from uuid import uuid4
from traceback import print_exc
from sys import stdout

class TransactionManager:

    def __init__(self):
        self.transactions = []

    def __begin_transaction(self, cursor):
        cursor.execute('BEGIN;')
        return (cursor, uuid4())

    def __prepare_transaction(self, transaction):
        cursor, transaction_id = transaction
        cursor.execute('PREPARE TRANSACTION \'%s\';'%transaction_id)
        print 'Prepared transaction %s'%transaction_id
        self.transactions.append(transaction)

    def __add_queries(self, cursor, queries):
        transaction = self.__begin_transaction(cursor)
        for q in queries:
            cursor.execute(q)
        self.__prepare_transaction(transaction)

    def add_transaction(self, cursor, queries):
        try:
            self.__add_queries(cursor, queries)
        except Exception:
            print_exc(file=stdout)
            self.rollback_transactions()
            return False
        return True

    def commit_transactions(self):
        for cursor, transaction_id in self.transactions:
            print 'Commiting %s'%transaction_id
            cursor.execute('COMMIT PREPARED \'%s\';'%transaction_id)

    def rollback_transactions(self):
        for cursor, transaction_id in self.transactions:
            print 'Rolling back %s'%transaction_id
            cursor.execute('ROLLBACK PREPARED \'%s\';'%transaction_id)
        self.transactions = []

<|endoftext|>


<commit_before>from __future__ import print_function
import numpy
import time
import traceback
import colorsys
import random

class EffectParameters(object):
    """Inputs to the individual effect layers. Includes basics like the timestamp of the frame we're
       generating, as well as parameters that may be used to control individual layers in real-time.
       """

    time = 0
    targetFrameRate = 59.0     # XXX: Want to go higher, but gl_server can't keep up!
    eeg = None

class EffectLayer(object):
    """Abstract base class for one layer of an LED light effect. Layers operate on a shared framebuffer,
       adding their own contribution to the buffer and possibly blending or overlaying with data from
       prior layers.

       The 'frame' passed to each render() function is an array of LEDs. Each LED is a 3-element list
       with the red, green, and blue components each as floating point values with a normalized
       brightness range of [0, 1]. If a component is beyond this range, it will be clamped during
       conversion to the hardware color format.
       """

    transitionFadeTime = 1.0
    maximum_errors = 5

    def render(self, params, frame):
        raise NotImplementedError("Implement render() in your EffectLayer subclass")

    def safely_render(self, params, frame):
        if not hasattr(self, 'error_count'):
            self.error_count = 0
        try:
            if self.error_count < EffectLayer.maximum_errors:
                self.render(params, frame)
        except Exception as err:
            error_log = open('error.log','a')
            error_log.write(time.asctime(time.gmtime()) + " UTC" + " : ")
            traceback.print_exc(file=error_log)
            print("ERROR:", err, "in", self)
            self.error_count += 1
            if self.error_count >= EffectLayer.maximum_errors:
                print("Disabling", self, "for throwing too many errors")

class HeadsetResponsiveEffectLayer(EffectLayer):
    """A layer effect that responds to the MindWave headset in some way.

    Two major differences from EffectLayer:
    1) Constructor expects four paramters:
       -- respond_to: the name of a field in EEGInfo (threads.HeadsetThread.EEGInfo).
          Currently this means either 'attention' or 'meditation'
       -- smooth_response_over_n_secs: to avoid rapid fluctuations from headset
          noise, averages the response metric over this many seconds
       -- minimum_response_level: if the response level is below this, the layer isn't rendered
       -- inverse: If this is true, the layer will respond to (1-response_level)
          instead of response_level
    2) Subclasses now only implement the render_responsive() function, which
       is the same as EffectLayer's render() function but has one extra
       parameter, response_level, which is the current EEG value of the indicated
       field (assumed to be on a 0-1 scale, or None if no value has been read yet).
    """
    def __init__(self, respond_to, smooth_response_over_n_secs=0, minimum_response_level=None, inverse=False):
        # Name of the eeg field to influence this effect
        if respond_to not in ('attention', 'meditation'):
            raise Exception('respond_to was "%s" -- should be "attention" or "meditation"'
                            % respond_to)
        self.respond_to = respond_to
        self.smooth_response_over_n_secs = smooth_response_over_n_secs
        self.measurements = []
        self.timestamps = []
        self.last_eeg = None
        self.last_response_level = None
        self.minimum_response_level = minimum_response_level
        # We want to smoothly transition between values instead of jumping
        # (as the headset typically gives one reading per second)
        self.fading_to = None
        self.inverse = inverse

    def start_fade(self, new_level):
        if not self.last_response_level:
            self.last_response_level = new_level
        else:
            self.fading_to = new_level

    def end_fade(self):
        self.last_response_level = self.fading_to
        self.fading_to = None

    def render(self, params, frame):
        now = time.time()
        response_level = None
        # Update our measurements, if we have a new one
        if params.eeg and params.eeg != self.last_eeg and params.eeg.on:
            if self.fading_to:
                self.end_fade()
            # Prepend newest measurement and timestamp
            self.measurements[:0] = [getattr(params.eeg, self.respond_to)]
            self.timestamps[:0] = [now]
            self.last_eeg = params.eeg
            # Compute the parameter to send to our rendering function
            N = len(self.measurements)
            idx = 0
            while idx < N:
                dt = self.timestamps[0] - self.timestamps[idx]
                if dt >= self.smooth_response_over_n_secs:
                    self.measurements = self.measurements[:(idx + 1)]
                    self.timestamps = self.timestamps[:(idx + 1)]
                    break
                idx += 1
            self.start_fade(sum(self.measurements) * 1.0 / len(self.measurements))
            response_level = self.last_response_level
        elif self.fading_to:
            # We assume one reading per second, so a one-second fade
            fade_progress = now - self.timestamps[0]
            if fade_progress >= 1:
                self.end_fade()
                response_level = self.last_response_level
            else:
                response_level = (
                    fade_progress * self.fading_to +
                    (1 - fade_progress) * self.last_response_level)

        if response_level and self.inverse:
            response_level = 1 - response_level

        if self.minimum_response_level == None or response_level >= self.minimum_response_level:
            self.render_responsive(params, frame, response_level)

    def render_responsive(self, params, frame, response_level):
        raise NotImplementedError(
            "Implement render_responsive() in your HeadsetResponsiveEffectLayer subclass")

########################################################
# Simple EffectLayer implementations and examples
########################################################

class RGBLayer(EffectLayer):
    """Simplest layer, draws a static RGB color cube."""

    def render(self, params, frame):
        length = len(frame)
        step_size = 1.0 / length

        hue = 0.0
        for pixel in xrange(0, length):
            frame[pixel] = colorsys.hsv_to_rgb(hue, 1, 1)
            hue += step_size

class MultiplierLayer(EffectLayer):
    """ Renders two layers in temporary frames, then adds the product of those frames
    to the frame passed into its render method
    """
    def __init__(self, layer1, layer2):
        self.layer1 = layer1
        self.layer2 = layer2

    def render(self, params, frame):
        temp1 = numpy.zeros(frame.shape)
        temp2 = numpy.zeros(frame.shape)
        self.layer1.render(params, temp1)
        self.layer2.render(params, temp2)
        numpy.multiply(temp1, temp2, temp1)
        numpy.add(frame, temp1, frame)

class BlinkyLayer(EffectLayer):
    """Test our timing accuracy: Just blink everything on and off every other frame."""

    on = False

    def render(self, params, frame):
        self.on = not self.on
        frame[:] += self.on

class ColorBlinkyLayer(EffectLayer):
    on = False
    def render(self, params, frame):
        self.on = not self.on
        color = numpy.array(colorsys.hsv_to_rgb(random.random(),1,1))
        if self.on:
            frame[:] += color

class SnowstormLayer(EffectLayer):
    transitionFadeTime = 1.0
    def render(self, params, frame):
        numpy.add(frame, numpy.random.rand(params.num_pixels, 1), frame)

class TechnicolorSnowstormLayer(EffectLayer):
    transitionFadeTime = 1.5
    def render(self, params, frame):
        numpy.add(frame, numpy.random.rand(params.num_pixels, 3), frame)

class WhiteOutLayer(EffectLayer):
    """ Sets everything to white """

    transitionFadeTime = 0.5
    def render(self, params, frame):
        frame += numpy.ones(frame.shape)

class GammaLayer(EffectLayer):
    """Apply a gamma correction to the brightness, to adjust for the eye's nonlinear sensitivity."""

    def __init__(self, gamma):
        # Build a lookup table
        self.lutX = numpy.arange(0, 1, 0.01)
        self.lutY = numpy.power(self.lutX, gamma)

    def render(self, params, frame):
        frame[:] = numpy.interp(frame.reshape(-1), self.lutX, self.lutY).reshape(frame.shape)

######################################################################
# Simple HeadsetResponsiveEffectLayer implementations and examples
######################################################################

class ResponsiveGreenHighRedLow(HeadsetResponsiveEffectLayer):
    """Colors everything green if the response metric is high, red if low.

    Interpolates in between.
    """
    def __init__(self, respond_to='attention', smooth_response_over_n_secs=3):
        super(ResponsiveGreenHighRedLow,self).__init__(
            respond_to, smooth_response_over_n_secs=smooth_response_over_n_secs)

    def render_responsive(self, params, frame, response_level):
        if response_level is None:
            # No signal (blue)
            frame[:,2] += 1
        else:
            frame[:,0] += 1 - response_level
            frame[:,1] += response_level

class BrainStaticLayer(HeadsetResponsiveEffectLayer):
    def __init__(self, minFactor = 0.3, respond_to='meditation', smooth_response_over_n_secs=0):
        super(BrainStaticLayer,self).__init__(respond_to, smooth_response_over_n_secs)
        self.minFactor = minFactor

    def render_responsive(self, params, frame, response_level):
        r = 1-response_level if response_level else 1
        numpy.multiply(frame, 1-numpy.random.rand(params.num_pixels, 1)*r*self.minFactor, frame)
<commit_msg>Updated to reference eeg1 instead of eeg from params<commit_after>from __future__ import print_function
import numpy
import time
import traceback
import colorsys
import random

class EffectParameters(object):
    """Inputs to the individual effect layers. Includes basics like the timestamp of the frame we're
       generating, as well as parameters that may be used to control individual layers in real-time.
       """

    time = 0
    targetFrameRate = 59.0     # XXX: Want to go higher, but gl_server can't keep up!
    eeg = None

class EffectLayer(object):
    """Abstract base class for one layer of an LED light effect. Layers operate on a shared framebuffer,
       adding their own contribution to the buffer and possibly blending or overlaying with data from
       prior layers.

       The 'frame' passed to each render() function is an array of LEDs. Each LED is a 3-element list
       with the red, green, and blue components each as floating point values with a normalized
       brightness range of [0, 1]. If a component is beyond this range, it will be clamped during
       conversion to the hardware color format.
       """

    transitionFadeTime = 1.0
    maximum_errors = 5

    def render(self, params, frame):
        raise NotImplementedError("Implement render() in your EffectLayer subclass")

    def safely_render(self, params, frame):
        if not hasattr(self, 'error_count'):
            self.error_count = 0
        try:
            if self.error_count < EffectLayer.maximum_errors:
                self.render(params, frame)
        except Exception as err:
            error_log = open('error.log','a')
            error_log.write(time.asctime(time.gmtime()) + " UTC" + " : ")
            traceback.print_exc(file=error_log)
            print("ERROR:", err, "in", self)
            self.error_count += 1
            if self.error_count >= EffectLayer.maximum_errors:
                print("Disabling", self, "for throwing too many errors")

class HeadsetResponsiveEffectLayer(EffectLayer):
    """A layer effect that responds to the MindWave headset in some way.

    Two major differences from EffectLayer:
    1) Constructor expects four paramters:
       -- respond_to: the name of a field in EEGInfo (threads.HeadsetThread.EEGInfo).
          Currently this means either 'attention' or 'meditation'
       -- smooth_response_over_n_secs: to avoid rapid fluctuations from headset
          noise, averages the response metric over this many seconds
       -- minimum_response_level: if the response level is below this, the layer isn't rendered
       -- inverse: If this is true, the layer will respond to (1-response_level)
          instead of response_level
    2) Subclasses now only implement the render_responsive() function, which
       is the same as EffectLayer's render() function but has one extra
       parameter, response_level, which is the current EEG value of the indicated
       field (assumed to be on a 0-1 scale, or None if no value has been read yet).
    """
    def __init__(self, respond_to, smooth_response_over_n_secs=0, minimum_response_level=None, inverse=False):
        # Name of the eeg field to influence this effect
        if respond_to not in ('attention', 'meditation'):
            raise Exception('respond_to was "%s" -- should be "attention" or "meditation"'
                            % respond_to)
        self.respond_to = respond_to
        self.smooth_response_over_n_secs = smooth_response_over_n_secs
        self.measurements = []
        self.timestamps = []
        self.last_eeg = None
        self.last_response_level = None
        self.minimum_response_level = minimum_response_level
        # We want to smoothly transition between values instead of jumping
        # (as the headset typically gives one reading per second)
        self.fading_to = None
        self.inverse = inverse

    def start_fade(self, new_level):
        if not self.last_response_level:
            self.last_response_level = new_level
        else:
            self.fading_to = new_level

    def end_fade(self):
        self.last_response_level = self.fading_to
        self.fading_to = None

    def render(self, params, frame):
        now = time.time()
        response_level = None
        # Update our measurements, if we have a new one
        eeg = params.eeg1
        if eeg and eeg != self.last_eeg and eeg.on:
            if self.fading_to:
                self.end_fade()
            # Prepend newest measurement and timestamp
            self.measurements[:0] = [getattr(eeg, self.respond_to)]
            self.timestamps[:0] = [now]
            self.last_eeg = eeg
            # Compute the parameter to send to our rendering function
            N = len(self.measurements)
            idx = 0
            while idx < N:
                dt = self.timestamps[0] - self.timestamps[idx]
                if dt >= self.smooth_response_over_n_secs:
                    self.measurements = self.measurements[:(idx + 1)]
                    self.timestamps = self.timestamps[:(idx + 1)]
                    break
                idx += 1
            self.start_fade(sum(self.measurements) * 1.0 / len(self.measurements))
            response_level = self.last_response_level
        elif self.fading_to:
            # We assume one reading per second, so a one-second fade
            fade_progress = now - self.timestamps[0]
            if fade_progress >= 1:
                self.end_fade()
                response_level = self.last_response_level
            else:
                response_level = (
                    fade_progress * self.fading_to +
                    (1 - fade_progress) * self.last_response_level)

        if response_level and self.inverse:
            response_level = 1 - response_level

        if self.minimum_response_level == None or response_level >= self.minimum_response_level:
            self.render_responsive(params, frame, response_level)

    def render_responsive(self, params, frame, response_level):
        raise NotImplementedError(
            "Implement render_responsive() in your HeadsetResponsiveEffectLayer subclass")

########################################################
# Simple EffectLayer implementations and examples
########################################################

class RGBLayer(EffectLayer):
    """Simplest layer, draws a static RGB color cube."""

    def render(self, params, frame):
        length = len(frame)
        step_size = 1.0 / length

        hue = 0.0
        for pixel in xrange(0, length):
            frame[pixel] = colorsys.hsv_to_rgb(hue, 1, 1)
            hue += step_size

class MultiplierLayer(EffectLayer):
    """ Renders two layers in temporary frames, then adds the product of those frames
    to the frame passed into its render method
    """
    def __init__(self, layer1, layer2):
        self.layer1 = layer1
        self.layer2 = layer2

    def render(self, params, frame):
        temp1 = numpy.zeros(frame.shape)
        temp2 = numpy.zeros(frame.shape)
        self.layer1.render(params, temp1)
        self.layer2.render(params, temp2)
        numpy.multiply(temp1, temp2, temp1)
        numpy.add(frame, temp1, frame)

class BlinkyLayer(EffectLayer):
    """Test our timing accuracy: Just blink everything on and off every other frame."""

    on = False

    def render(self, params, frame):
        self.on = not self.on
        frame[:] += self.on

class ColorBlinkyLayer(EffectLayer):
    on = False
    def render(self, params, frame):
        self.on = not self.on
        color = numpy.array(colorsys.hsv_to_rgb(random.random(),1,1))
        if self.on:
            frame[:] += color

class SnowstormLayer(EffectLayer):
    transitionFadeTime = 1.0
    def render(self, params, frame):
        numpy.add(frame, numpy.random.rand(params.num_pixels, 1), frame)

class TechnicolorSnowstormLayer(EffectLayer):
    transitionFadeTime = 1.5
    def render(self, params, frame):
        numpy.add(frame, numpy.random.rand(params.num_pixels, 3), frame)

class WhiteOutLayer(EffectLayer):
    """ Sets everything to white """

    transitionFadeTime = 0.5
    def render(self, params, frame):
        frame += numpy.ones(frame.shape)

class GammaLayer(EffectLayer):
    """Apply a gamma correction to the brightness, to adjust for the eye's nonlinear sensitivity."""

    def __init__(self, gamma):
        # Build a lookup table
        self.lutX = numpy.arange(0, 1, 0.01)
        self.lutY = numpy.power(self.lutX, gamma)

    def render(self, params, frame):
        frame[:] = numpy.interp(frame.reshape(-1), self.lutX, self.lutY).reshape(frame.shape)

######################################################################
# Simple HeadsetResponsiveEffectLayer implementations and examples
######################################################################

class ResponsiveGreenHighRedLow(HeadsetResponsiveEffectLayer):
    """Colors everything green if the response metric is high, red if low.

    Interpolates in between.
    """
    def __init__(self, respond_to='attention', smooth_response_over_n_secs=3):
        super(ResponsiveGreenHighRedLow,self).__init__(
            respond_to, smooth_response_over_n_secs=smooth_response_over_n_secs)

    def render_responsive(self, params, frame, response_level):
        if response_level is None:
            # No signal (blue)
            frame[:,2] += 1
        else:
            frame[:,0] += 1 - response_level
            frame[:,1] += response_level

class BrainStaticLayer(HeadsetResponsiveEffectLayer):
    def __init__(self, minFactor = 0.3, respond_to='meditation', smooth_response_over_n_secs=0):
        super(BrainStaticLayer,self).__init__(respond_to, smooth_response_over_n_secs)
        self.minFactor = minFactor

    def render_responsive(self, params, frame, response_level):
        r = 1-response_level if response_level else 1
        numpy.multiply(frame, 1-numpy.random.rand(params.num_pixels, 1)*r*self.minFactor, frame)
<|endoftext|>


<commit_before># Author: Ilan Schnell <ischnell@enthought.com>
"""\
egginst is a simple tool for installing eggs into a Python environment.
By default the eggs (provided as arguments) are installed.
"""

import os
import sys
import re
import shutil
import string
import zipfile
import ConfigParser
from os.path import abspath, basename, dirname, join, isdir, isfile, islink

from utils import (on_win, site_packages, rel_prefix, rmdir_er, rm_rf,
                   human_bytes)
import scripts

# This is the directory which contains the EGG-INFO directories of all
# installed packages
EGG_INFO_DIR = join(sys.prefix, 'EGG-INFO')

DEACTIVE_DIR = join(sys.prefix, 'DEACTIVE')

def projname(fn):
    return fn.split('-')[0]

class EggInst(object):

    def __init__(self, fpath, verbose=False):
        self.fpath = fpath
        self.name = projname(basename(fpath))
        self.meta_dir = join(EGG_INFO_DIR, self.name)
        self.meta_txt = join(self.meta_dir, '__egginst__.txt')
        self.files = []
        self.verbose = verbose

    def install(self):
        if not isdir(self.meta_dir):
            os.makedirs(self.meta_dir)

        self.z = zipfile.ZipFile(self.fpath)
        self.arcnames = self.z.namelist()

        self.extract()

        if on_win:
            scripts.create_proxies(self)

        else:
            import links
            import object_code

            if self.verbose:
                links.verbose = object_code.verbose = True

            links.create(self)
            object_code.fix_files(self)

        self.entry_points()
        self.z.close()
        scripts.fix_scripts(self)
        self.install_app()
        self.write_meta()

        self.run('post_install.py')

    def entry_points(self):
        lines = list(self.lines_from_arcname('EGG-INFO/entry_points.txt',
                                             ignore_empty=False))
        if lines == []:
            return

        path = join(self.meta_dir, '__entry_points__.txt')
        fo = open(path, 'w')
        fo.write('\n'.join(lines) + '\n')
        fo.close()

        conf = ConfigParser.ConfigParser()
        conf.read(path)
        if 'console_scripts' in conf.sections():
            if self.verbose:
                print 'creating console scripts'
                scripts.verbose = True
            scripts.create(self, conf)

    def write_meta(self):
        fo = open(self.meta_txt, 'w')
        fo.write('# egginst metadata\n')
        fo.write('egg_name = %r\n' % basename(self.fpath))
        fo.write('prefix = %r\n' % sys.prefix)
        fo.write('rel_files = [\n')
        fo.write('  %r,\n' % rel_prefix(self.meta_txt))
        for f in self.files:
            fo.write('  %r,\n' % rel_prefix(f))
        fo.write(']\n')
        fo.close()

    def read_meta(self):
        d = {}
        execfile(self.meta_txt, d)
        for name in ['egg_name', 'prefix', 'rel_files']:
            setattr(self, name, d[name])
        self.files = [join(self.prefix, f) for f in d['rel_files']]

    def lines_from_arcname(self, arcname,
                           ignore_empty=True,
                           ignore_comments=True):
        if not arcname in self.arcnames:
            return
        for line in self.z.read(arcname).splitlines():
            line = line.strip()
            if ignore_empty and line == '':
                continue
            if ignore_comments and line.startswith('#'):
                continue
            yield line

    def extract(self):
        cur = 0
        n = 0
        size = sum(self.z.getinfo(name).file_size
                   for name in self.arcnames)
        sys.stdout.write('%9s [' % human_bytes(size))
        for name in self.arcnames:
            n += self.z.getinfo(name).file_size
            rat = float(n) / size
            if rat * 64 >= cur:
                sys.stdout.write('.')
                sys.stdout.flush()
                cur += 1
            self.write_arcname(name)

        sys.stdout.write('.' * (65-cur) + ']\n')
        sys.stdout.flush()

    def get_dst(self, arcname):
        dispatch = [
            ('EGG-INFO/prefix/',  True,       sys.prefix),
            ('EGG-INFO/usr/',     not on_win, sys.prefix),
            ('EGG-INFO/scripts/', True,       scripts.bin_dir),
            ('EGG-INFO/',         True,       self.meta_dir),
            ('',                  True,       site_packages),
        ]
        for start, cond, dst_dir in dispatch:
            if arcname.startswith(start) and cond:
                return abspath(join(dst_dir, arcname[len(start):]))
        raise Exception("Didn't expect to get here")

    py_pat = re.compile(r'^(.+)\.py(c|o)?$')
    so_pat = re.compile(r'^lib.+\.so')
    py_obj = '.pyd' if on_win else '.so'
    def write_arcname(self, arcname):
        if arcname.endswith('/') or arcname.startswith('.unused'):
            return
        m = self.py_pat.match(arcname)
        if m and (m.group(1) + self.py_obj) in self.arcnames:
            # .py, .pyc, .pyo next to .so are not written
            return
        path = self.get_dst(arcname)
        dn, fn = os.path.split(path)
        self.files.append(path)
        if not isdir(dn):
            os.makedirs(dn)
        rm_rf(path, self.verbose)
        fo = open(path, 'wb')
        fo.write(self.z.read(arcname))
        fo.close()
        if (arcname.startswith(('EGG-INFO/usr/bin/', 'EGG-INFO/scripts/')) or
                fn.endswith(('.dylib', '.pyd', '.so')) or
                (arcname.startswith('EGG-INFO/usr/lib/') and
                 self.so_pat.match(fn))):
            os.chmod(path, 0755)

    def install_app(self, remove=False):
        path = join(self.meta_dir, 'EGG-INFO', 'inst', 'appinst.dat')
        if not isfile(path):
            return

        try:
            import appinst
        except ImportError:
            print("Error: importing appinst failed.  Can't %sinstall "
                  "application (skipping)" % 'un' if remove else '')
            return

        if remove:
            appinst.uninstall_from_dat(path)
        else:
            appinst.install_from_dat(path)

    def run(self, fn):
        path = join(self.meta_dir, 'inst', fn)
        if not isfile(path):
            return
        from subprocess import call
        call([sys.executable, path], cwd=dirname(path))

    def rmdirs(self):
        """
        Remove empty directories for the files in self.files recursively
        """
        for path in set(dirname(p) for p in self.files):
            if isdir(path):
                rmdir_er(path)

    def remove(self):
        if not isdir(self.meta_dir):
            print "Error: Can't find meta data for:", self.name
            return

        self.read_meta()
        self.run('pre_uninstall.py')
        self.install_app(remove=True)

        for p in self.files:
            if islink(p) or isfile(p):
                os.unlink(p)
        self.rmdirs()
        rm_rf(self.meta_dir)

    def deactivate(self):
        """
        Deactivate a package, i.e. move the files belonging to the package
        into the special folder.
        """
        if not isdir(self.meta_dir):
            print "Error: Can't find meta data for:", self.name
            return
        self.read_meta()
        dn = self.egg_name[:-4]
        deact_dir = join(DEACTIVE_DIR, dn)
        if isdir(deact_dir):
            print "Error: Deactive data already exists for:", dn
            return
        os.makedirs(deact_dir)

        for rel_src in self.rel_files:
            src = join(self.prefix, rel_src)
            if islink(src) or isfile(src):
                dst = join(deact_dir, rel_src)
                dst_dir = dirname(dst)
                if not isdir(dst_dir):
                    os.makedirs(dst_dir)
                os.rename(src, dst)
        self.rmdirs()
        rm_rf(self.meta_dir)

def activate(dn):
    """
    Activate a package which was previously deactivated.  'dn' is the
    directory name inside the deactive folder, which is simply the egg
    name, without the .egg extension, of the egg which was used to install
    the package in the first place.
    """
    deact_dir = join(DEACTIVE_DIR, dn)
    if not isdir(deact_dir):
        print "Error: Can't find stored data for:", dn
        return
    for root, dirs, files in os.walk(deact_dir):
        for fn in files:
            src = join(root, fn)
            rel_src = src[len(deact_dir) + 1:]
            dst = join(sys.prefix, rel_src)
            dst_dir = dirname(dst)
            if not isdir(dst_dir):
                os.makedirs(dst_dir)
            rm_rf(dst)
            os.rename(src, dst)
    shutil.rmtree(deact_dir)

def get_active():
    """
    return a sroted list of all installed (active) packages
    """
    if not isdir(EGG_INFO_DIR):
        return []
    res = []
    for fn in os.listdir(EGG_INFO_DIR):
        meta_txt = join(EGG_INFO_DIR, fn, '__egginst__.txt')
        if isfile(meta_txt):
            d = {}
            execfile(meta_txt, d)
            res.append(d['egg_name'][:-4])
    res.sort(key=string.lower)
    return res

def get_deactive():
    """
    returns the set of all deactivated projects
    """
    if not isdir(DEACTIVE_DIR):
        return []
    res = [fn for fn in os.listdir(DEACTIVE_DIR)
           if isdir(join(DEACTIVE_DIR, fn))]
    res.sort(key=string.lower)
    return res

def print_list():
    fmt = '%-20s %-20s %s'
    print fmt % ('Project name', 'Version', 'Active')
    print 50 * '='

    active = get_active()
    deactive = get_deactive()
    names = set(projname(fn) for fn in active + deactive)
    output = []
    for name in sorted(names, key=string.lower):
        for lst, act in [(active, 'Yes'), (deactive, '')]:
            for fn in lst:
                if projname(fn) != name:
                    continue
                name, vers = fn.split('-', 1)
                output.append([name, vers, act])

    names = set()
    for row in output:
        if row[0] in names:
            row[0] = ''
        print fmt % tuple(row)
        names.add(row[0])

def main():
    from optparse import OptionParser

    usage = "usage: %prog [options] [ARGS ...]"

    description = __doc__

    p = OptionParser(usage = usage,
                     description = description,
                     prog = basename(sys.argv[0]))

    p.add_option('-a', "--activate",
                 action="store_true",
                 help="activate deactivated package(s)")

    p.add_option('-d', "--deactivate",
                 action="store_true",
                 help="deactives installed package(s)")

    p.add_option('-l', "--list",
                 action="store_true",
                 help="list packages, both active and deactive")

    p.add_option('-r', "--remove",
                 action="store_true",
                 help="remove package(s), requires the egg or project name(s)")

    p.add_option('-v', "--verbose", action="store_true")

    opts, args = p.parse_args()

    if opts.activate:
        for name in args:
            activate(name)
        return

    if opts.list:
        if args:
            p.error("--list takes no arguments")
        print_list()
        return

    for name in args:
        ei = EggInst(name, opts.verbose)
        if opts.remove:
            print "Removing:", name
            ei.remove()

        elif opts.deactivate:
            print "Deactivating:", name
            ei.deactivate()

        else: # default is always install
            print "Installing:", name
            ei.install()

if __name__ == '__main__':
    main()
<commit_msg>fixed locatin of possible egginst install scripts, note that these are purposely different from the ones our patched setuptools uses<commit_after># Author: Ilan Schnell <ischnell@enthought.com>
"""\
egginst is a simple tool for installing eggs into a Python environment.
By default the eggs (provided as arguments) are installed.
"""

import os
import sys
import re
import shutil
import string
import zipfile
import ConfigParser
from os.path import abspath, basename, dirname, join, isdir, isfile, islink

from utils import (on_win, site_packages, rel_prefix, rmdir_er, rm_rf,
                   human_bytes)
import scripts

# This is the directory which contains the EGG-INFO directories of all
# installed packages
EGG_INFO_DIR = join(sys.prefix, 'EGG-INFO')

DEACTIVE_DIR = join(sys.prefix, 'DEACTIVE')

def projname(fn):
    return fn.split('-')[0]

class EggInst(object):

    def __init__(self, fpath, verbose=False):
        self.fpath = fpath
        self.name = projname(basename(fpath))
        self.meta_dir = join(EGG_INFO_DIR, self.name)
        self.meta_txt = join(self.meta_dir, '__egginst__.txt')
        self.files = []
        self.verbose = verbose

    def install(self):
        if not isdir(self.meta_dir):
            os.makedirs(self.meta_dir)

        self.z = zipfile.ZipFile(self.fpath)
        self.arcnames = self.z.namelist()

        self.extract()

        if on_win:
            scripts.create_proxies(self)

        else:
            import links
            import object_code

            if self.verbose:
                links.verbose = object_code.verbose = True

            links.create(self)
            object_code.fix_files(self)

        self.entry_points()
        self.z.close()
        scripts.fix_scripts(self)
        self.install_app()
        self.write_meta()

        self.run('post_egginst.py')

    def entry_points(self):
        lines = list(self.lines_from_arcname('EGG-INFO/entry_points.txt',
                                             ignore_empty=False))
        if lines == []:
            return

        path = join(self.meta_dir, '__entry_points__.txt')
        fo = open(path, 'w')
        fo.write('\n'.join(lines) + '\n')
        fo.close()

        conf = ConfigParser.ConfigParser()
        conf.read(path)
        if 'console_scripts' in conf.sections():
            if self.verbose:
                print 'creating console scripts'
                scripts.verbose = True
            scripts.create(self, conf)

    def write_meta(self):
        fo = open(self.meta_txt, 'w')
        fo.write('# egginst metadata\n')
        fo.write('egg_name = %r\n' % basename(self.fpath))
        fo.write('prefix = %r\n' % sys.prefix)
        fo.write('rel_files = [\n')
        fo.write('  %r,\n' % rel_prefix(self.meta_txt))
        for f in self.files:
            fo.write('  %r,\n' % rel_prefix(f))
        fo.write(']\n')
        fo.close()

    def read_meta(self):
        d = {}
        execfile(self.meta_txt, d)
        for name in ['egg_name', 'prefix', 'rel_files']:
            setattr(self, name, d[name])
        self.files = [join(self.prefix, f) for f in d['rel_files']]

    def lines_from_arcname(self, arcname,
                           ignore_empty=True,
                           ignore_comments=True):
        if not arcname in self.arcnames:
            return
        for line in self.z.read(arcname).splitlines():
            line = line.strip()
            if ignore_empty and line == '':
                continue
            if ignore_comments and line.startswith('#'):
                continue
            yield line

    def extract(self):
        cur = 0
        n = 0
        size = sum(self.z.getinfo(name).file_size
                   for name in self.arcnames)
        sys.stdout.write('%9s [' % human_bytes(size))
        for name in self.arcnames:
            n += self.z.getinfo(name).file_size
            rat = float(n) / size
            if rat * 64 >= cur:
                sys.stdout.write('.')
                sys.stdout.flush()
                cur += 1
            self.write_arcname(name)

        sys.stdout.write('.' * (65-cur) + ']\n')
        sys.stdout.flush()

    def get_dst(self, arcname):
        dispatch = [
            ('EGG-INFO/prefix/',  True,       sys.prefix),
            ('EGG-INFO/usr/',     not on_win, sys.prefix),
            ('EGG-INFO/scripts/', True,       scripts.bin_dir),
            ('EGG-INFO/',         True,       self.meta_dir),
            ('',                  True,       site_packages),
        ]
        for start, cond, dst_dir in dispatch:
            if arcname.startswith(start) and cond:
                return abspath(join(dst_dir, arcname[len(start):]))
        raise Exception("Didn't expect to get here")

    py_pat = re.compile(r'^(.+)\.py(c|o)?$')
    so_pat = re.compile(r'^lib.+\.so')
    py_obj = '.pyd' if on_win else '.so'
    def write_arcname(self, arcname):
        if arcname.endswith('/') or arcname.startswith('.unused'):
            return
        m = self.py_pat.match(arcname)
        if m and (m.group(1) + self.py_obj) in self.arcnames:
            # .py, .pyc, .pyo next to .so are not written
            return
        path = self.get_dst(arcname)
        dn, fn = os.path.split(path)
        self.files.append(path)
        if not isdir(dn):
            os.makedirs(dn)
        rm_rf(path, self.verbose)
        fo = open(path, 'wb')
        fo.write(self.z.read(arcname))
        fo.close()
        if (arcname.startswith(('EGG-INFO/usr/bin/', 'EGG-INFO/scripts/')) or
                fn.endswith(('.dylib', '.pyd', '.so')) or
                (arcname.startswith('EGG-INFO/usr/lib/') and
                 self.so_pat.match(fn))):
            os.chmod(path, 0755)

    def install_app(self, remove=False):
        path = join(self.meta_dir, 'EGG-INFO', 'inst', 'appinst.dat')
        if not isfile(path):
            return

        try:
            import appinst
        except ImportError:
            print("Error: importing appinst failed.  Can't %sinstall "
                  "application (skipping)" % 'un' if remove else '')
            return

        if remove:
            appinst.uninstall_from_dat(path)
        else:
            appinst.install_from_dat(path)

    def run(self, fn):
        path = join(self.meta_dir, fn)
        if not isfile(path):
            return
        from subprocess import call
        call([sys.executable, path], cwd=dirname(path))

    def rmdirs(self):
        """
        Remove empty directories for the files in self.files recursively
        """
        for path in set(dirname(p) for p in self.files):
            if isdir(path):
                rmdir_er(path)

    def remove(self):
        if not isdir(self.meta_dir):
            print "Error: Can't find meta data for:", self.name
            return

        self.read_meta()
        self.run('pre_egguninst.py')
        self.install_app(remove=True)

        for p in self.files:
            if islink(p) or isfile(p):
                os.unlink(p)
        self.rmdirs()
        rm_rf(self.meta_dir)

    def deactivate(self):
        """
        Deactivate a package, i.e. move the files belonging to the package
        into the special folder.
        """
        if not isdir(self.meta_dir):
            print "Error: Can't find meta data for:", self.name
            return
        self.read_meta()
        dn = self.egg_name[:-4]
        deact_dir = join(DEACTIVE_DIR, dn)
        if isdir(deact_dir):
            print "Error: Deactive data already exists for:", dn
            return
        os.makedirs(deact_dir)

        for rel_src in self.rel_files:
            src = join(self.prefix, rel_src)
            if islink(src) or isfile(src):
                dst = join(deact_dir, rel_src)
                dst_dir = dirname(dst)
                if not isdir(dst_dir):
                    os.makedirs(dst_dir)
                os.rename(src, dst)
        self.rmdirs()
        rm_rf(self.meta_dir)

def activate(dn):
    """
    Activate a package which was previously deactivated.  'dn' is the
    directory name inside the deactive folder, which is simply the egg
    name, without the .egg extension, of the egg which was used to install
    the package in the first place.
    """
    deact_dir = join(DEACTIVE_DIR, dn)
    if not isdir(deact_dir):
        print "Error: Can't find stored data for:", dn
        return
    for root, dirs, files in os.walk(deact_dir):
        for fn in files:
            src = join(root, fn)
            rel_src = src[len(deact_dir) + 1:]
            dst = join(sys.prefix, rel_src)
            dst_dir = dirname(dst)
            if not isdir(dst_dir):
                os.makedirs(dst_dir)
            rm_rf(dst)
            os.rename(src, dst)
    shutil.rmtree(deact_dir)

def get_active():
    """
    return a sroted list of all installed (active) packages
    """
    if not isdir(EGG_INFO_DIR):
        return []
    res = []
    for fn in os.listdir(EGG_INFO_DIR):
        meta_txt = join(EGG_INFO_DIR, fn, '__egginst__.txt')
        if isfile(meta_txt):
            d = {}
            execfile(meta_txt, d)
            res.append(d['egg_name'][:-4])
    res.sort(key=string.lower)
    return res

def get_deactive():
    """
    returns the set of all deactivated projects
    """
    if not isdir(DEACTIVE_DIR):
        return []
    res = [fn for fn in os.listdir(DEACTIVE_DIR)
           if isdir(join(DEACTIVE_DIR, fn))]
    res.sort(key=string.lower)
    return res

def print_list():
    fmt = '%-20s %-20s %s'
    print fmt % ('Project name', 'Version', 'Active')
    print 50 * '='

    active = get_active()
    deactive = get_deactive()
    names = set(projname(fn) for fn in active + deactive)
    output = []
    for name in sorted(names, key=string.lower):
        for lst, act in [(active, 'Yes'), (deactive, '')]:
            for fn in lst:
                if projname(fn) != name:
                    continue
                name, vers = fn.split('-', 1)
                output.append([name, vers, act])

    names = set()
    for row in output:
        if row[0] in names:
            row[0] = ''
        print fmt % tuple(row)
        names.add(row[0])

def main():
    from optparse import OptionParser

    usage = "usage: %prog [options] [ARGS ...]"

    description = __doc__

    p = OptionParser(usage = usage,
                     description = description,
                     prog = basename(sys.argv[0]))

    p.add_option('-a', "--activate",
                 action="store_true",
                 help="activate deactivated package(s)")

    p.add_option('-d', "--deactivate",
                 action="store_true",
                 help="deactives installed package(s)")

    p.add_option('-l', "--list",
                 action="store_true",
                 help="list packages, both active and deactive")

    p.add_option('-r', "--remove",
                 action="store_true",
                 help="remove package(s), requires the egg or project name(s)")

    p.add_option('-v', "--verbose", action="store_true")

    opts, args = p.parse_args()

    if opts.activate:
        for name in args:
            activate(name)
        return

    if opts.list:
        if args:
            p.error("--list takes no arguments")
        print_list()
        return

    for name in args:
        ei = EggInst(name, opts.verbose)
        if opts.remove:
            print "Removing:", name
            ei.remove()

        elif opts.deactivate:
            print "Deactivating:", name
            ei.deactivate()

        else: # default is always install
            print "Installing:", name
            ei.install()

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