<commit_before>##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/spack/spack
# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class ParallelNetcdf(AutotoolsPackage):
    """Parallel netCDF (PnetCDF) is a library providing high-performance
    parallel I/O while still maintaining file-format compatibility with
    Unidata's NetCDF."""

    homepage = "https://trac.mcs.anl.gov/projects/parallel-netcdf"
    url      = "http://cucis.ece.northwestern.edu/projects/PnetCDF/Release/parallel-netcdf-1.6.1.tar.gz"
    list_url = "http://cucis.ece.northwestern.edu/projects/PnetCDF/download.html"

    version('1.8.0', '825825481aa629eb82f21ca37afff1609b8eeb07')
    version('1.7.0', '267eab7b6f9dc78c4d0e6def2def3aea4bc7c9f0')
    version('1.6.1', '62a094eb952f9d1e15f07d56e535052604f1ac34')

    variant('cxx', default=True, description='Build the C++ Interface')
    variant('fortran', default=True, description='Build the Fortran Interface')
    variant('pic', default=True,
            description='Produce position-independent code (for shared libs)')

    depends_on('mpi')

    depends_on('m4', type='build')

    # See:
    # https://trac.mcs.anl.gov/projects/parallel-netcdf/browser/trunk/INSTALL
    def configure_args(self):
        spec = self.spec

        args = ['--with-mpi={0}'.format(spec['mpi'].prefix)]
        args.append('SEQ_CC={0}'.format(spack_cc))

        if '+pic' in spec:
            args.extend([
                'CFLAGS={0}'.format(self.compiler.pic_flag),
                'CXXFLAGS={0}'.format(self.compiler.pic_flag),
                'FFLAGS={0}'.format(self.compiler.pic_flag)
            ])

        if '~cxx' in spec:
            args.append('--disable-cxx')

        if '~fortran' in spec:
            args.append('--disable-fortran')

        return args
<commit_msg>Using MPI environment compiler variables for pnetcdf. (#6424)<commit_after>##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/spack/spack
# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class ParallelNetcdf(AutotoolsPackage):
    """Parallel netCDF (PnetCDF) is a library providing high-performance
    parallel I/O while still maintaining file-format compatibility with
    Unidata's NetCDF."""

    homepage = "https://trac.mcs.anl.gov/projects/parallel-netcdf"
    url      = "http://cucis.ece.northwestern.edu/projects/PnetCDF/Release/parallel-netcdf-1.6.1.tar.gz"
    list_url = "http://cucis.ece.northwestern.edu/projects/PnetCDF/download.html"

    version('1.8.0', '825825481aa629eb82f21ca37afff1609b8eeb07')
    version('1.7.0', '267eab7b6f9dc78c4d0e6def2def3aea4bc7c9f0')
    version('1.6.1', '62a094eb952f9d1e15f07d56e535052604f1ac34')

    variant('cxx', default=True, description='Build the C++ Interface')
    variant('fortran', default=True, description='Build the Fortran Interface')
    variant('pic', default=True,
            description='Produce position-independent code (for shared libs)')

    depends_on('mpi')

    depends_on('m4', type='build')

    # See:
    # https://trac.mcs.anl.gov/projects/parallel-netcdf/browser/trunk/INSTALL
    def configure_args(self):
        spec = self.spec

        args = ['--with-mpi={0}'.format(spec['mpi'].prefix)]
        args.append('MPICC={0}'.format(spec['mpi'].mpicc))
        args.append('MPICXX={0}'.format(spec['mpi'].mpicxx))
        args.append('MPIF77={0}'.format(spec['mpi'].mpifc))
        args.append('MPIF90={0}'.format(spec['mpi'].mpifc))
        args.append('SEQ_CC={0}'.format(spack_cc))

        if '+pic' in spec:
            args.extend([
                'CFLAGS={0}'.format(self.compiler.pic_flag),
                'CXXFLAGS={0}'.format(self.compiler.pic_flag),
                'FFLAGS={0}'.format(self.compiler.pic_flag)
            ])

        if '~cxx' in spec:
            args.append('--disable-cxx')

        if '~fortran' in spec:
            args.append('--disable-fortran')

        return args
<|endoftext|>


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

import numpy as np

class NeuralNet():
    def __init__(self,train_in,train_out,hl_size,iterations=10000):
        """The init method.
        Arguments:
        train_in -- Training set inputs (array)
        train_out -- Training set outputs (array)
        hl_size -- Hidden layer size, e.g., (4,1) (tuple)
        iterations -- How many iterations run in training (int)
        """
        self.train_in = train_in
        self.train_out = train_out
        self.iterations = iterations
        # Init weights between -1 and 1
        # Weights between input and hidden layer
        weights_1 = 2*np.random.random(train_in.shape)-1
        # Weights between hidden and output layer
        weights_2 = 2*np.random.random(hl_size)-1
        # Train the network
        self.train(self.train_in,self.train_out,self.iterations)

    def _sigmoid(self,x):
        """The sigmoid function (or it's derivative).
        Arguments:
        x -- The weighted sum of an input
        Returns:
        The sigmoid function value.
        """
        return 1/(1+np.exp(-x))

    def _sigmoid_deriv(self,y):
        """The sigmoid derivative function.
        Arguments:
        y -- The neural network outputs. Notice that
        these values have already been calculated using
        the sigmoid function. An actual sigmoid derivative
        should be sigmoid(x)*(1-sigmoid(x)).
        Return:
        The sigmoid derivative.
        """
        return y*(1-y)

    def train(self,inputs,outputs,iterations):
        """Train the neural network using a training set.
        Arguments:
        inputs -- The input data from a training set (array)
        outputs -- The correct outputs from the training set (array)
        iterations -- How many iterations to train the network (int, default=10000)
        """
        pass

    def classify(self):
        pass

def main():
    train_in = np.array([[1,0,0],[0,0,1],[1,1,1],[1,1,0]])
    train_out = np.array([[1],[0],[1],[1]])
    nn = NeuralNet(train_in,train_out,(4,1))

if __name__=='__main__':
    main()
<commit_msg>Train method now uses classify, also removed unnecessary parameters inside class<commit_after>#!/usr/bin/env python

import numpy as np

class NeuralNet():
    def __init__(self,train_in,train_out,hl_size,iterations=10000):
        """The init method.
        Arguments:
        train_in -- Training set inputs (array)
        train_out -- Training set outputs (array)
        hl_size -- Hidden layer size, e.g., (4,1) (tuple)
        iterations -- How many iterations run in training (int)
        """
        self.train_in = train_in
        self.train_out = train_out
        self.iterations = iterations
        # Init weights between -1 and 1
        # Weights between input and hidden layer
        self.weights_1 = 2*np.random.random(train_in.shape)-1
        # Weights between hidden and output layer
        self.weights_2 = 2*np.random.random(hl_size)-1
        # Train the network
        self.train()

    def _sigmoid(self,x):
        """The sigmoid function (or it's derivative).
        Arguments:
        x -- The weighted sum of an input
        Returns:
        The sigmoid function value.
        """
        return 1/(1+np.exp(-x))

    def _sigmoid_deriv(self,y):
        """The sigmoid derivative function.
        Arguments:
        y -- The neural network outputs. Notice that
        these values have already been calculated using
        the sigmoid function. An actual sigmoid derivative
        should be sigmoid(x)*(1-sigmoid(x)).
        Return:
        The sigmoid derivative.
        """
        return y*(1-y)

    def train(self):
        """Train the neural network using a training set."""
        # First, classify the training data using the network
        hidden_layer,output_layer = self.classify(self.train_in)

    def classify(self,inputs):
        hidden_layer = self._sigmoid(np.dot(inputs,self.weights_1))
        output_layer = self._sigmoid(np.dot(hidden_layer,self.weights_2))
        return hidden_layer,output_layer

def main():
    train_in = np.array([[1,0,0],[0,0,1],[1,1,1],[1,1,0]])
    train_out = np.array([[1],[0],[1],[1]])
    nn = NeuralNet(train_in,train_out,(4,1))

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


<commit_before># This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Set of common functions for all handlers."""

import types

from bson import tz_util
from datetime import (
    date,
    datetime,
    time,
    timedelta,
)
from pymongo import (
    ASCENDING,
    DESCENDING,
)

from models import (
    AGGREGATE_KEY,
    CREATED_KEY,
    DATE_RANGE_KEY,
    FIELD_KEY,
    LIMIT_KEY,
    NOT_FIELD_KEY,
    SKIP_KEY,
    SORT_KEY,
    SORT_ORDER_KEY,
)
from utils import get_log

# Default value to calculate a date range in case the provided value is
# out of range.
DEFAULT_DATE_RANGE = 15

LOG = get_log()

def get_all_query_values(query_args_func, valid_keys):
    """Handy function to get all query args in a batch.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :param valid_keys: A list containing the valid keys that should be
    retrieved.
    :type valid_keys: list
    """
    spec = get_query_spec(query_args_func, valid_keys)
    sort = get_query_sort(query_args_func)
    fields = get_query_fields(query_args_func)
    skip, limit = get_skip_and_limit(query_args_func)
    unique = get_aggregate_value(query_args_func)

    return (spec, sort, fields, skip, limit, unique)

def get_aggregate_value(query_args_func):
    """Get teh value of the aggregate key.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :return The aggregate value as string.
    """
    aggregate = query_args_func(AGGREGATE_KEY)
    if all([aggregate and isinstance(aggregate, types.ListType)]):
        aggregate = aggregate[-1]
    else:
        aggregate = None
    return aggregate

def get_query_spec(query_args_func, valid_keys):
    """Get values from the query string to build a `spec` data structure.

    A `spec` data structure is a dictionary whose keys are the keys
    accepted by this handler method.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :param valid_keys: A list containing the valid keys that should be
    retrieved.
    :type valid_keys: list
    :return A `spec` data structure (dictionary).
    """
    spec = {}
    if all([valid_keys and isinstance(valid_keys, types.ListType)]):
        spec = {
            k: v for k, v in [
                (key, val)
                for key in valid_keys
                for val in (query_args_func(key) or [])
                if val is not None
            ]
        }

    return spec

def get_and_add_date_range(spec, query_args_func):
    """Retrieve the `date_range` query from the request.

    Add the retrieved `date_range` value into the provided `spec` data
    structure.

    :param spec: The dictionary where to store the key-value.
    :type spec: dictionary
    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return The passed `spec` updated.
    """
    date_range = query_args_func(DATE_RANGE_KEY)
    if date_range:
        if isinstance(date_range, types.ListType):
            date_range = date_range[-1]
        # Today needs to be set at the end of the day!
        today = datetime.combine(
            date.today(), time(23, 59, 59, tzinfo=tz_util.utc)
        )
        previous = calculate_date_range(date_range)

        spec[CREATED_KEY] = {'$gte': previous, '$lt': today}
    return spec

def calculate_date_range(date_range):
    """Calculate the new date subtracting the passed number of days.

    It removes the passed days from today date, calculated at midnight
    UTC.

    :param date_range: The number of days to remove from today.
    :type date_range int, long, str
    :return A new `datetime.date` object that is the result of the
    subtraction of `datetime.date.today()` and
    `datetime.timedelta(days=date_range)`.
    """
    if isinstance(date_range, types.StringTypes):
        date_range = int(date_range)

    date_range = abs(date_range)
    if date_range > timedelta.max.days:
        date_range = DEFAULT_DATE_RANGE

    # Calcuate with midnight in mind though, so we get the starting of
    # the day for the previous date.
    today = datetime.combine(
        date.today(), time(tzinfo=tz_util.utc)
    )
    delta = timedelta(days=date_range)

    return today - delta

def get_query_fields(query_args_func):
    """Get values from the query string to build a `fields` data structure.

    A `field` data structure can be either a list or a dictionary.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A `fields` data structure (list or dictionary).
    """
    fields = None
    y_fields, n_fields = map(query_args_func, [FIELD_KEY, NOT_FIELD_KEY])

    if y_fields and not n_fields:
        fields = list(set(y_fields))
    elif n_fields:
        fields = dict.fromkeys(list(set(y_fields)), True)
        fields.update(dict.fromkeys(list(set(n_fields)), False))

    return fields

def get_query_sort(query_args_func):
    """Get values from the query string to build a `sort` data structure.

    A `sort` data structure is a list of tuples in a `key-value` fashion.
    The keys are the values passed as the `sort` argument on the query,
    they values are based on the `sort_order` argument and defaults to the
    descending order.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A `sort` data structure, or None.
    """
    sort = None
    sort_fields, sort_order = map(query_args_func, [SORT_KEY, SORT_ORDER_KEY])

    if sort_fields:
        if all([sort_order, isinstance(sort_order, types.ListType)]):
            sort_order = int(sort_order[-1])
        else:
            sort_order = DESCENDING

        # Wrong number for sort order? Force descending.
        if all([sort_order != ASCENDING, sort_order != DESCENDING]):
            LOG.warn(
                "Wrong sort order used (%d), default to %d",
                sort_order, DESCENDING
            )
            sort_order = DESCENDING

        sort = [
            (field, sort_order)
            for field in sort_fields
        ]

    return sort

def get_skip_and_limit(query_args_func):
    """Retrieve the `skip` and `limit` query arguments.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A tuple with the `skip` and `limit` arguments.
    """
    skip, limit = map(query_args_func, [SKIP_KEY, LIMIT_KEY])

    if all([skip, isinstance(skip, types.ListType)]):
        skip = int(skip[-1])
    else:
        skip = 0

    if all([limit, isinstance(limit, types.ListType)]):
        limit = int(limit[-1])
    else:
        limit = 0

    return skip, limit
<commit_msg>common: Move where list type is checked.<commit_after># This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Set of common functions for all handlers."""

import types

from bson import tz_util
from datetime import (
    date,
    datetime,
    time,
    timedelta,
)
from pymongo import (
    ASCENDING,
    DESCENDING,
)

from models import (
    AGGREGATE_KEY,
    CREATED_KEY,
    DATE_RANGE_KEY,
    FIELD_KEY,
    LIMIT_KEY,
    NOT_FIELD_KEY,
    SKIP_KEY,
    SORT_KEY,
    SORT_ORDER_KEY,
)
from utils import get_log

# Default value to calculate a date range in case the provided value is
# out of range.
DEFAULT_DATE_RANGE = 15

LOG = get_log()

def get_all_query_values(query_args_func, valid_keys):
    """Handy function to get all query args in a batch.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :param valid_keys: A list containing the valid keys that should be
    retrieved.
    :type valid_keys: list
    """
    spec = get_query_spec(query_args_func, valid_keys)
    sort = get_query_sort(query_args_func)
    fields = get_query_fields(query_args_func)
    skip, limit = get_skip_and_limit(query_args_func)
    unique = get_aggregate_value(query_args_func)

    return (spec, sort, fields, skip, limit, unique)

def get_aggregate_value(query_args_func):
    """Get teh value of the aggregate key.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :return The aggregate value as string.
    """
    aggregate = query_args_func(AGGREGATE_KEY)
    if all([aggregate and isinstance(aggregate, types.ListType)]):
        aggregate = aggregate[-1]
    else:
        aggregate = None
    return aggregate

def get_query_spec(query_args_func, valid_keys):
    """Get values from the query string to build a `spec` data structure.

    A `spec` data structure is a dictionary whose keys are the keys
    accepted by this handler method.

    :param query_args_func: A function used to return a list of the query
    arguments.
    :type query_args_func: function
    :param valid_keys: A list containing the valid keys that should be
    retrieved.
    :type valid_keys: list
    :return A `spec` data structure (dictionary).
    """
    spec = {}
    if all([valid_keys and isinstance(valid_keys, types.ListType)]):
        spec = {
            k: v for k, v in [
                (key, val)
                for key in valid_keys
                for val in (query_args_func(key) or [])
                if val is not None
            ]
        }

    return spec

def get_and_add_date_range(spec, query_args_func):
    """Retrieve the `date_range` query from the request.

    Add the retrieved `date_range` value into the provided `spec` data
    structure.

    :param spec: The dictionary where to store the key-value.
    :type spec: dictionary
    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return The passed `spec` updated.
    """
    date_range = query_args_func(DATE_RANGE_KEY)
    if date_range:
        # Today needs to be set at the end of the day!
        today = datetime.combine(
            date.today(), time(23, 59, 59, tzinfo=tz_util.utc)
        )
        previous = calculate_date_range(date_range)

        spec[CREATED_KEY] = {'$gte': previous, '$lt': today}
    return spec

def calculate_date_range(date_range):
    """Calculate the new date subtracting the passed number of days.

    It removes the passed days from today date, calculated at midnight
    UTC.

    :param date_range: The number of days to remove from today.
    :type date_range int, long, str
    :return A new `datetime.date` object that is the result of the
    subtraction of `datetime.date.today()` and
    `datetime.timedelta(days=date_range)`.
    """
    if isinstance(date_range, types.ListType):
        date_range = date_range[-1]

    if isinstance(date_range, types.StringTypes):
        date_range = int(date_range)

    date_range = abs(date_range)
    if date_range > timedelta.max.days:
        date_range = DEFAULT_DATE_RANGE

    # Calcuate with midnight in mind though, so we get the starting of
    # the day for the previous date.
    today = datetime.combine(
        date.today(), time(tzinfo=tz_util.utc)
    )
    delta = timedelta(days=date_range)

    return today - delta

def get_query_fields(query_args_func):
    """Get values from the query string to build a `fields` data structure.

    A `field` data structure can be either a list or a dictionary.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A `fields` data structure (list or dictionary).
    """
    fields = None
    y_fields, n_fields = map(query_args_func, [FIELD_KEY, NOT_FIELD_KEY])

    if y_fields and not n_fields:
        fields = list(set(y_fields))
    elif n_fields:
        fields = dict.fromkeys(list(set(y_fields)), True)
        fields.update(dict.fromkeys(list(set(n_fields)), False))

    return fields

def get_query_sort(query_args_func):
    """Get values from the query string to build a `sort` data structure.

    A `sort` data structure is a list of tuples in a `key-value` fashion.
    The keys are the values passed as the `sort` argument on the query,
    they values are based on the `sort_order` argument and defaults to the
    descending order.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A `sort` data structure, or None.
    """
    sort = None
    sort_fields, sort_order = map(query_args_func, [SORT_KEY, SORT_ORDER_KEY])

    if sort_fields:
        if all([sort_order, isinstance(sort_order, types.ListType)]):
            sort_order = int(sort_order[-1])
        else:
            sort_order = DESCENDING

        # Wrong number for sort order? Force descending.
        if all([sort_order != ASCENDING, sort_order != DESCENDING]):
            LOG.warn(
                "Wrong sort order used (%d), default to %d",
                sort_order, DESCENDING
            )
            sort_order = DESCENDING

        sort = [
            (field, sort_order)
            for field in sort_fields
        ]

    return sort

def get_skip_and_limit(query_args_func):
    """Retrieve the `skip` and `limit` query arguments.

    :param query_args_func: A function used to return a list of query
    arguments.
    :type query_args_func: function
    :return A tuple with the `skip` and `limit` arguments.
    """
    skip, limit = map(query_args_func, [SKIP_KEY, LIMIT_KEY])

    if all([skip, isinstance(skip, types.ListType)]):
        skip = int(skip[-1])
    else:
        skip = 0

    if all([limit, isinstance(limit, types.ListType)]):
        limit = int(limit[-1])
    else:
        limit = 0

    return skip, limit
<|endoftext|>


<commit_before>#####
#
# Name:    nextmetro.py
#
# Purpose: Determine when next DC Metro leaves Wiehle-Reston East station.
#          May need modification to work with non terminal station.
#
# Author:  Simon Prickett
#
#####

import os
import requests
import schedule
import time
#import unicornhat as UH

STATION_ID = "N06"
DESTINATION_STATION_ID = "G05"
DESTINATION_STATION_LINE = "SV"

#####
# Get train departure JSON data from WMATA API
#####
def getTrainData():
	apiUrl = "https://api.wmata.com/StationPrediction.svc/json/GetPrediction/" + STATION_ID + "?api_key=" + os.environ.get("WMATA_API_KEY")
	try:
		r = requests.get(apiUrl)
		return r.json()
	except:
		# TODO Indicate a network error on the display
		return { "Error": "" }

#####
# Get the time of the next train arrival, could be:
#
# -99 Network error
# -1  Unknown
# ARR Arriving
# BRD Boarding
# >0  Minutes until it arrives
#####
def getNextTrainTime(trainJSON):
	nextTrainTime = -1
	if ("Trains" in trainJSON):
		for train in trainJSON["Trains"]:
			if (train["DestinationCode"] == DESTINATION_STATION_ID and train["Line"] == DESTINATION_STATION_LINE):
				try:
					nextTrainTime = int(train["Min"])
				except:
					# Train is arriving or boarding
					nextTrainTime = 0

				return nextTrainTime
	elif ("Error" in trainJSON):
		nextTrainTime = -99

	return int(nextTrainTime)

#####
# TODO description
#####
def updateDisplay():
	nextTime = getNextTrainTime(getTrainData())
	r = 0
	g = 0
	b = 0

	if (nextTime == -1):
		# API does not know
		b = 255
		print "Unknown"
	elif (nextTime == -99):
		# Network error
		r = 128
		b = 128
		print "Network error"
	elif (nextTime >= 10):
		# Plenty of time
		g = 255
		print "Lots of time - " + str(nextTime) + " mins"
	elif (nextTime < 10 and nextTime > 5):
		# Pushing it
		r = 255
		g = 255
		print "Not much time - " + str(nextTime) + " mins"
	elif (nextTime >= 0 and nextTime <= 5):
		# No chance
		r = 255
		print "Not enough time - " + str(nextTime) + " mins"

#	for y in range(8):
#		for x in range(8):
#			UH.set_pixel(x, y, r, g, b)
#
#	UH.show()

#####
# Entry Point
#####
if (not "WMATA_API_KEY" in os.environ):
	print "Please set environment variable WMATA_API_KEY with your API key."
	exit(1)
else:
	updateDisplay()
	schedule.every(30).seconds.do(updateDisplay)
	while True:
		schedule.run_pending()
		time.sleep(1)
<commit_msg>Removed comments around the Unicorn Hat code.<commit_after>#####
#
# Name:    nextmetro.py
#
# Purpose: Determine when next DC Metro leaves Wiehle-Reston East station.
#          May need modification to work with non terminal station.
#
# Author:  Simon Prickett
#
#####

import os
import requests
import schedule
import time
import unicornhat as UH

STATION_ID = "N06"
DESTINATION_STATION_ID = "G05"
DESTINATION_STATION_LINE = "SV"

#####
# Get train departure JSON data from WMATA API
#####
def getTrainData():
	apiUrl = "https://api.wmata.com/StationPrediction.svc/json/GetPrediction/" + STATION_ID + "?api_key=" + os.environ.get("WMATA_API_KEY")
	try:
		r = requests.get(apiUrl)
		return r.json()
	except:
		# TODO Indicate a network error on the display
		return { "Error": "" }

#####
# Get the time of the next train arrival, could be:
#
# -99 Network error
# -1  Unknown
# ARR Arriving
# BRD Boarding
# >0  Minutes until it arrives
#####
def getNextTrainTime(trainJSON):
	nextTrainTime = -1
	if ("Trains" in trainJSON):
		for train in trainJSON["Trains"]:
			if (train["DestinationCode"] == DESTINATION_STATION_ID and train["Line"] == DESTINATION_STATION_LINE):
				try:
					nextTrainTime = int(train["Min"])
				except:
					# Train is arriving or boarding
					nextTrainTime = 0

				return nextTrainTime
	elif ("Error" in trainJSON):
		nextTrainTime = -99

	return int(nextTrainTime)

#####
# TODO description
#####
def updateDisplay():
	nextTime = getNextTrainTime(getTrainData())
	r = 0
	g = 0
	b = 0

	if (nextTime == -1):
		# API does not know
		b = 255
		print "Unknown"
	elif (nextTime == -99):
		# Network error
		r = 128
		b = 128
		print "Network error"
	elif (nextTime >= 10):
		# Plenty of time
		g = 255
		print "Lots of time - " + str(nextTime) + " mins"
	elif (nextTime < 10 and nextTime > 5):
		# Pushing it
		r = 255
		g = 255
		print "Not much time - " + str(nextTime) + " mins"
	elif (nextTime >= 0 and nextTime <= 5):
		# No chance
		r = 255
		print "Not enough time - " + str(nextTime) + " mins"

	for y in range(8):
		for x in range(8):
			UH.set_pixel(x, y, r, g, b)

	UH.show()

#####
# Entry Point
#####
if (not "WMATA_API_KEY" in os.environ):
	print "Please set environment variable WMATA_API_KEY with your API key."
	exit(1)
else:
	updateDisplay()
	schedule.every(30).seconds.do(updateDisplay)
	while True:
		schedule.run_pending()
		time.sleep(1)
<|endoftext|>


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

import os
import sys
import json
import textwrap
import optparse
import logging.config
from datetime import datetime
import unicodedata
import re

from pyramid.settings import aslist
from xylose.scielodocument import Article

from citedby import utils
from citedby.controller import controller, articlemeta

logger = logging.getLogger(__name__)

config = utils.Configuration.from_env()
settings = dict(config.items())

# set logger
logger = logging.getLogger('pcitations')

TAG_RE = re.compile(r'<[^>]+>')

def remove_tags(text):
    return TAG_RE.sub('', text)

def cleanup_string(text):

    nfd_form = unicodedata.normalize('NFD', text.strip().lower())

    cleaned_str = u''.join(x for x in nfd_form if unicodedata.category(x)[0] == 'L' or x == ' ')

    return remove_tags(cleaned_str)

def citation_meta(document):
    """
    This function receives a article meta JSON, transform it in an citation
    dicitionary, look the response example.

    :param document: ArticleMeta Xylose Document

    This function only create keys that has content, ignore otherwise.

    :returns:
        {
          "url": "<DOAMIN>scielo.php?script=sci_arttext&pid=S0101-31222002000100038",
          "source": "Revista Brasileira de Sementes",
          "issn": "0101-3122",
          "code": "S0101-31222002000100038",
          "collection": "scl",
          "titles": ["Adequação do...", "Seconde title..."]
          "first_author": {role: "ND",
                           xref: ["A01"],
                           surname: "Moreira",
                           given_names: "Jessica Pronestino de Lima"},
          "publication_year": "2013",
          "citations":
          [{
              "source": "Anais da Academia Brasileira de Ciências",
              "first_author": "Moreira JK",
              "title": "Germination of Croton...",
              "publication_year": "2004"
           }]
        }
    """

    if document.citations:

        c_dict = {}

        c_dict['titles'] = []
        c_dict['url'] = document.html_url()
        c_dict['issn'] = document.journal.scielo_issn
        c_dict['pid'] = document.publisher_id
        c_dict['code'] = document.publisher_id
        c_dict['collection'] = document.collection_acronym
        c_dict['document_type'] = document.document_type

        if document.doi:
            c_dict['doi'] = document.doi

        if document.journal.title:
            c_dict['source'] = document.journal.title

        if document.translated_titles():
            c_dict['titles'] = [t for l, t in document.translated_titles().items() if t != None]
            c_dict['titles_cleaned'] = [cleanup_string(t) for l, t in document.translated_titles().items() if t != None]

        if document.original_title():
            c_dict['titles'].append(cleanup_string(document.original_title()))
            c_dict['titles_cleaned'].append(cleanup_string(document.original_title()))

        if document.authors:
            c_dict['authors'] = document.authors

        if document.subject_areas:
            c_dict['subject_areas'] = document.subject_areas

        if document.first_author:
            c_dict['first_author'] = document.first_author

        if document.start_page:
            c_dict['start_page'] = document.start_page

        if document.end_page:
            c_dict['end_page'] = document.end_page

        if document.publication_date:
            c_dict['publication_year'] = document.publication_date[:4]

        for cit in document.citations:

            if cit.source:
                c_dict['reference_source'] = cit.source
                try:
                    c_dict['reference_source_cleaned'] = cleanup_string(cit.source)
                except:
                    c_dict['reference_source_cleaned'] = cit.source
            if cit.title():
                c_dict['reference_title'] = cit.title()
            elif cit.chapter_title:
                c_dict['reference_title'] = cit.chapter_title

            if cit.date:
                c_dict['reference_publication_year'] = cit.date[:4]

            if cit.authors:
                c_dict['reference_authors'] = cit.authors

            if cit.first_author:
                c_dict['reference_first_author'] = ' '.join([
                    cit.first_author.get('given_names', ''),
                    cit.first_author.get('surname', '')
                ])

            if cit.start_page:
                c_dict['reference_start_page'] = cit.start_page

            if cit.end_page:
                c_dict['reference_end_page'] = cit.end_page

            if cit.end_page:
                c_dict['reference_index_number'] = str(cit.index_number)

            c_dict['_id'] = '-'.join([
                document.collection_acronym,
                document.publisher_id,
                str(cit.index_number)
            ])

            yield c_dict

class PCitation(object):
    """
    Process citation getting articles from Article Meta
    """

    usage = """\
    %prog -f (full) index all citations OR -d (distinct) only difference
    between endpoints.

    This process collects all articles in the Article meta
    http://articlemeta.scielo.org and index in ES (elasticsearch).

    With this process it is possible to process all the citations or only difference
    between elasticsearch and Article Meta, use pcitations -h to verify the options list.

    Edit logging.ini to change logging definitions.
    """

    parser = optparse.OptionParser(
        textwrap.dedent(usage), version="prog 0.9 - beta")

    parser.add_option('-f', '--full', action='store_true',
                      help='update all documents and insert the difference')

    parser.add_option('-r', '--rebuild_index', action='store_true',
                      help='this will remove all data in ES and\
                             index all documents')

    parser.add_option('-o', '--offset', action='store', default=5000,
                      help='Bulk offset, default= 5000')

    def __init__(self, argv):
        self.started = None
        self.finished = None
        self.options, self.args = self.parser.parse_args(argv)

        hosts = aslist(settings['app:main'].get('elasticsearch_host', '127.0.0.1:9200'))
        index = settings['app:main'].get('elasticsearch_index', 'citations')

        self.controller = controller(
            hosts=hosts,
            timeout=60,
            sniff_on_start=True,
            sniff_on_connection_fail=True
        )

        self.articlemeta = articlemeta()

    def _duration(self):
        """
        Return datetime process duration
        """
        return self.finished - self.started

    def _string_json(self, data):
        """
        Method convert string to json handler some errors.

        :param data: string

        :returns: json
        """

        try:
            jdata = json.loads(data)
        except ValueError as e:
            logger.error(e)
        else:
            return jdata

    def _bulk(self, documents):

        for document in documents:
            for reference in citation_meta(document):
                self.controller.index_citation(reference, reference['_id'])

    def run(self):
        """
        Run the Loaddata switching between full and incremental indexation
        """

        self.started = datetime.now()

        logger.info('Load Data Script (index citation)')

        logger.info('Get all ids from articlemeta')

        self.controller.load_mapping()

        documents = self.articlemeta.documents()

        if self.options.full:
            logger.info('You have selected full processing... this will take a while')

            if self.options.rebuild_index:
                logger.info('This will remove EVERYTHING from your search index')

                self.controller.index_reset()

            self._bulk(documents)

        else:
            logger.info('You have selected incremental processing...')
            self._bulk(documents)

        self.finished = datetime.now()

        logger.info("Total processing time: %s sec." % self._duration())

def main(argv=sys.argv[1:]):

    command = PCitation(argv)

    return command.run()<commit_msg>Fix undeclared key titles_cleaned to append elements<commit_after>#!/usr/bin/python
# !coding: utf-8

import os
import sys
import json
import textwrap
import optparse
import logging.config
from datetime import datetime
import unicodedata
import re

from pyramid.settings import aslist
from xylose.scielodocument import Article

from citedby import utils
from citedby.controller import controller, articlemeta

logger = logging.getLogger(__name__)

config = utils.Configuration.from_env()
settings = dict(config.items())

# set logger
logger = logging.getLogger('pcitations')

TAG_RE = re.compile(r'<[^>]+>')

def remove_tags(text):
    return TAG_RE.sub('', text)

def cleanup_string(text):

    nfd_form = unicodedata.normalize('NFD', text.strip().lower())

    cleaned_str = u''.join(x for x in nfd_form if unicodedata.category(x)[0] == 'L' or x == ' ')

    return remove_tags(cleaned_str)

def citation_meta(document):
    """
    This function receives a article meta JSON, transform it in an citation
    dicitionary, look the response example.

    :param document: ArticleMeta Xylose Document

    This function only create keys that has content, ignore otherwise.

    :returns:
        {
          "url": "<DOAMIN>scielo.php?script=sci_arttext&pid=S0101-31222002000100038",
          "source": "Revista Brasileira de Sementes",
          "issn": "0101-3122",
          "code": "S0101-31222002000100038",
          "collection": "scl",
          "titles": ["Adequação do...", "Seconde title..."]
          "first_author": {role: "ND",
                           xref: ["A01"],
                           surname: "Moreira",
                           given_names: "Jessica Pronestino de Lima"},
          "publication_year": "2013",
          "citations":
          [{
              "source": "Anais da Academia Brasileira de Ciências",
              "first_author": "Moreira JK",
              "title": "Germination of Croton...",
              "publication_year": "2004"
           }]
        }
    """

    if document.citations:

        c_dict = {}

        c_dict['titles'] = []
        c_dict['titles_cleaned'] = []
        c_dict['url'] = document.html_url()
        c_dict['issn'] = document.journal.scielo_issn
        c_dict['pid'] = document.publisher_id
        c_dict['code'] = document.publisher_id
        c_dict['collection'] = document.collection_acronym
        c_dict['document_type'] = document.document_type

        if document.doi:
            c_dict['doi'] = document.doi

        if document.journal.title:
            c_dict['source'] = document.journal.title

        if document.translated_titles():
            c_dict['titles'] = [t for l, t in document.translated_titles().items() if t != None]
            c_dict['titles_cleaned'] = [cleanup_string(t) for l, t in document.translated_titles().items() if t != None]

        if document.original_title():
            c_dict['titles'].append(cleanup_string(document.original_title()))
            c_dict['titles_cleaned'].append(cleanup_string(document.original_title()))

        if document.authors:
            c_dict['authors'] = document.authors

        if document.subject_areas:
            c_dict['subject_areas'] = document.subject_areas

        if document.first_author:
            c_dict['first_author'] = document.first_author

        if document.start_page:
            c_dict['start_page'] = document.start_page

        if document.end_page:
            c_dict['end_page'] = document.end_page

        if document.publication_date:
            c_dict['publication_year'] = document.publication_date[:4]

        for cit in document.citations:

            if cit.source:
                c_dict['reference_source'] = cit.source
                try:
                    c_dict['reference_source_cleaned'] = cleanup_string(cit.source)
                except:
                    c_dict['reference_source_cleaned'] = cit.source
            if cit.title():
                c_dict['reference_title'] = cit.title()
            elif cit.chapter_title:
                c_dict['reference_title'] = cit.chapter_title

            if cit.date:
                c_dict['reference_publication_year'] = cit.date[:4]

            if cit.authors:
                c_dict['reference_authors'] = cit.authors

            if cit.first_author:
                c_dict['reference_first_author'] = ' '.join([
                    cit.first_author.get('given_names', ''),
                    cit.first_author.get('surname', '')
                ])

            if cit.start_page:
                c_dict['reference_start_page'] = cit.start_page

            if cit.end_page:
                c_dict['reference_end_page'] = cit.end_page

            if cit.end_page:
                c_dict['reference_index_number'] = str(cit.index_number)

            c_dict['_id'] = '-'.join([
                document.collection_acronym,
                document.publisher_id,
                str(cit.index_number)
            ])

            yield c_dict

class PCitation(object):
    """
    Process citation getting articles from Article Meta
    """

    usage = """\
    %prog -f (full) index all citations OR -d (distinct) only difference
    between endpoints.

    This process collects all articles in the Article meta
    http://articlemeta.scielo.org and index in ES (elasticsearch).

    With this process it is possible to process all the citations or only difference
    between elasticsearch and Article Meta, use pcitations -h to verify the options list.

    Edit logging.ini to change logging definitions.
    """

    parser = optparse.OptionParser(
        textwrap.dedent(usage), version="prog 0.9 - beta")

    parser.add_option('-f', '--full', action='store_true',
                      help='update all documents and insert the difference')

    parser.add_option('-r', '--rebuild_index', action='store_true',
                      help='this will remove all data in ES and\
                             index all documents')

    parser.add_option('-o', '--offset', action='store', default=5000,
                      help='Bulk offset, default= 5000')

    def __init__(self, argv):
        self.started = None
        self.finished = None
        self.options, self.args = self.parser.parse_args(argv)

        hosts = aslist(settings['app:main'].get('elasticsearch_host', '127.0.0.1:9200'))
        index = settings['app:main'].get('elasticsearch_index', 'citations')

        self.controller = controller(
            hosts=hosts,
            timeout=60,
            sniff_on_start=True,
            sniff_on_connection_fail=True
        )

        self.articlemeta = articlemeta()

    def _duration(self):
        """
        Return datetime process duration
        """
        return self.finished - self.started

    def _string_json(self, data):
        """
        Method convert string to json handler some errors.

        :param data: string

        :returns: json
        """

        try:
            jdata = json.loads(data)
        except ValueError as e:
            logger.error(e)
        else:
            return jdata

    def _bulk(self, documents):

        for document in documents:
            for reference in citation_meta(document):
                self.controller.index_citation(reference, reference['_id'])

    def run(self):
        """
        Run the Loaddata switching between full and incremental indexation
        """

        self.started = datetime.now()

        logger.info('Load Data Script (index citation)')

        logger.info('Get all ids from articlemeta')

        self.controller.load_mapping()

        documents = self.articlemeta.documents()

        if self.options.full:
            logger.info('You have selected full processing... this will take a while')

            if self.options.rebuild_index:
                logger.info('This will remove EVERYTHING from your search index')

                self.controller.index_reset()

            self._bulk(documents)

        else:
            logger.info('You have selected incremental processing...')
            self._bulk(documents)

        self.finished = datetime.now()

        logger.info("Total processing time: %s sec." % self._duration())

def main(argv=sys.argv[1:]):

    command = PCitation(argv)

    return command.run()
<|endoftext|>


<commit_before>#####

# Name:    nextmetro.py
#
# Purpose: Determine when next DC Metro leaves Wiehle-Reston East station.
#          May need modification to work with non terminal station.
#
# Author:  Simon Prickett
#
#####

import os
import requests
import schedule
import time
import unicornhat as UH

API_POLL_INTERVAL = 30
MAX_CONSECUTIVE_NETWORK_ERRORS = 5
STATION_ID = "N06"
DESTINATION_STATION_ID = "G05"
DESTINATION_STATION_LINE = "SV"

consecutiveNetworkErrors = 0

#####
# Log something with a timestamp
#####
def log(logMessage):
	print logMessage

#####
# Get train departure JSON data from WMATA API
#####
def getTrainData():
	apiUrl = "https://api.wmata.com/StationPrediction.svc/json/GetPrediction/" + STATION_ID + "?api_key=" + os.environ.get("WMATA_API_KEY")
	try:
		r = requests.get(apiUrl)
		return r.json()
	except:
		# TODO Indicate a network error on the display
		return { "Error": "" }

#####
# Get the time of the next train arrival, could be:
#
# -99 Network error
# -1  Unknown
# ARR Arriving
# BRD Boarding
# >0  Minutes until it arrives
#####
def getNextTrainTime(trainJSON):
	nextTrainTime = -1
	if ("Trains" in trainJSON):
		for train in trainJSON["Trains"]:
			if (train["DestinationCode"] == DESTINATION_STATION_ID and train["Line"] == DESTINATION_STATION_LINE):
				try:
					nextTrainTime = int(train["Min"])
				except:
					# Train is arriving or boarding
					nextTrainTime = 0

				return nextTrainTime
	elif ("Error" in trainJSON):
		nextTrainTime = -99

	return int(nextTrainTime)

#####
# Reboot the device as the network is down
# Displays a red X during reboot
#####
def reboot():
	log("Rebooting as network is not working...")

	ledMatrix = [[1, 0, 0, 0, 0, 0, 0, 1],
		     	 [0, 1, 0, 0, 0, 0, 1, 0],
	      	     [0, 0, 1, 0, 0, 1, 0, 0],
	             [0, 0, 0, 1, 1, 0, 0, 0],
 		     	 [0, 0, 0, 1, 1, 0, 0, 0],
		     	 [0, 0, 1, 0, 0, 1, 0, 0],
		     	 [0, 1, 0, 0, 0, 0, 1, 0],
		     	 [1, 0, 0, 0, 0, 0, 0, 1]
		    	]

	for y in range(8):
		for x in range(8):
			UH.set_pixel(x, y, 255 * ledMatrix[y][x], 0, 0)

	UH.show()

	os.system("reboot")

#####
# TODO description
#####
def updateDisplay():
	global consecutiveNetworkErrors
	nextTime = getNextTrainTime(getTrainData())
	r = 0
	g = 0
	b = 0

	ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
		     	 [0, 0, 0, 0, 0, 0, 0, 0],
	      	     [0, 0, 0, 0, 0, 0, 0, 0],
	             [0, 0, 0, 0, 0, 0, 0, 0],
 		     	 [0, 0, 0, 0, 0, 0, 0, 0],
		     	 [0, 0, 0, 0, 0, 0, 0, 0],
		     	 [0, 0, 0, 0, 0, 0, 0, 0],
		     	 [0, 0, 0, 0, 0, 0, 0, 0]
		    	]

	if (nextTime == -1):
		# API does not know
		b = 255
		ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
			     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		     [0, 0, 0, 0, 0, 0, 1, 0],
	       		     [0, 0, 0, 1, 1, 1, 1, 0],
 		     	     [0, 0, 0, 1, 0, 0, 0, 0],
		             [0, 0, 0, 0, 0, 0, 0, 0],
		             [0, 0, 0, 1, 0, 0, 0, 0],
		             [0, 0, 0, 0, 0, 0, 0, 0]
		            ]
		log("Unknown")
	elif (nextTime == -99):
		# Network error
		r = 128
		b = 128
		log("Network error")
		consecutiveNetworkErrors += 1

		if (consecutiveNetworkErrors == MAX_CONSECUTIVE_NETWORK_ERRORS):
			reboot()
	elif (nextTime >= 10):
		# Plenty of time
		g = 255
		log("Lots of time - " + str(nextTime) + " mins")
	elif (nextTime < 10 and nextTime > 5):
		# Pushing it
		r = 255
		g = 140

		# Show the time remaining
		if (nextTime == 9):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 1, 0, 0, 0, 0, 1, 0],
	       		         [0, 1, 1, 1, 1, 1, 1, 0],
 		     	     	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 8):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 1, 0, 0, 0, 0, 1, 0],
	       		         [0, 1, 1, 1, 1, 1, 1, 0],
 		     	     	 [0, 1, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 7):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 0, 0, 0, 0, 0, 1, 0],
	       		         [0, 0, 0, 0, 0, 1, 0, 0],
 		     	     	 [0, 0, 0, 0, 1, 0, 0, 0],
		             	 [0, 0, 0, 0, 1, 0, 0, 0],
		             	 [0, 0, 0, 0, 1, 0, 0, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 6):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 1, 0, 0, 0, 0, 0, 0],
	       		         [0, 1, 0, 0, 0, 0, 0, 0],
 		     	     	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 1, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]

		log("Not much time - " + str(nextTime) + " mins")
	elif (nextTime >= 0 and nextTime <= 5):
		# No chance
		r = 255
		log("Not enough time - " + str(nextTime) + " mins")

		if (nextTime == 5):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 1, 0, 0, 0, 0, 0, 0],
	       		         [0, 1, 0, 0, 0, 0, 0, 0],
 		     	     	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 4):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 0, 0, 0, 0, 1, 0],
	      		         [0, 1, 0, 0, 0, 0, 1, 0],
	       		         [0, 1, 1, 1, 1, 1, 1, 0],
 		     	     	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 3):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 0, 0, 0, 0, 0, 1, 0],
	       		         [0, 0, 0, 0, 0, 0, 1, 0],
 		     	     	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 2):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 1, 1, 1, 1, 1, 1, 0],
	      		         [0, 0, 0, 0, 0, 0, 1, 0],
	       		         [0, 0, 0, 0, 0, 0, 1, 0],
 		     	     	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 1, 0, 0, 0, 0, 0, 0],
		             	 [0, 1, 1, 1, 1, 1, 1, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 1):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 0, 0, 0, 1, 0, 0, 0],
	      		         [0, 0, 0, 1, 1, 0, 0, 0],
	       		         [0, 0, 0, 0, 1, 0, 0, 0],
 		     	     	 [0, 0, 0, 0, 1, 0, 0, 0],
		             	 [0, 0, 0, 0, 1, 0, 0, 0],
		             	 [0, 0, 0, 1, 1, 1, 0, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
		elif (nextTime == 0):
			ledMatrix = [[0, 0, 0, 0, 0, 0, 0, 0],
				     	 [0, 0, 1, 1, 1, 1, 0, 0],
	      		         [0, 1, 0, 0, 0, 0, 1, 0],
	       		         [0, 1, 0, 0, 0, 0, 1, 0],
 		     	     	 [0, 1, 0, 0, 0, 0, 1, 0],
		             	 [0, 1, 0, 0, 0, 0, 1, 0],
		             	 [0, 0, 1, 1, 1, 1, 0, 0],
		             	 [0, 0, 0, 0, 0, 0, 0, 0]
		            	]
	if (nextTime != -99):
		consecutiveNetworkErrors = 0

	for y in range(8):
		for x in range(8):
			if (ledMatrix[y][x] == 1):
				UH.set_pixel(x, y, 255, 255, 255)
			else:
				UH.set_pixel(x, y, r, g, b)

	UH.show()

#####
# Entry Point
#####

if (not "WMATA_API_KEY" in os.environ):
	log("Please set environment variable WMATA_API_KEY with your API key.")
	exit(1)
else:
	updateDisplay()
	schedule.every(API_POLL_INTERVAL).seconds.do(updateDisplay)
	while True:
		schedule.run_pending()
		time.sleep(1)
<commit_msg>Went back to solid colours, added brightness<commit_after>#####

# Name:    nextmetro.py
#
# Purpose: Determine when next DC Metro leaves Wiehle-Reston East station.
#          May need modification to work with non terminal station.
#
# Author:  Simon Prickett
#
#####

import os
import requests
import schedule
import time
import unicornhat as UH

API_POLL_INTERVAL = 30
MAX_CONSECUTIVE_NETWORK_ERRORS = 5
STATION_ID = "N06"
DESTINATION_STATION_ID = "G05"
DESTINATION_STATION_LINE = "SV"

consecutiveNetworkErrors = 0

#####
# Log something with a timestamp
#####
def log(logMessage):
	print time.strftime("%c") + ": " + logMessage

#####
# Get train departure JSON data from WMATA API
#####
def getTrainData():
	apiUrl = "https://api.wmata.com/StationPrediction.svc/json/GetPrediction/" + STATION_ID + "?api_key=" + os.environ.get("WMATA_API_KEY")
	try:
		r = requests.get(apiUrl)
		return r.json()
	except:
		# TODO Indicate a network error on the display
		return { "Error": "" }

#####
# Get the time of the next train arrival, could be:
#
# -99 Network error
# -1  Unknown
# ARR Arriving
# BRD Boarding
# >0  Minutes until it arrives
#####
def getNextTrainTime(trainJSON):
	nextTrainTime = -1
	if ("Trains" in trainJSON):
		for train in trainJSON["Trains"]:
			if (train["DestinationCode"] == DESTINATION_STATION_ID and train["Line"] == DESTINATION_STATION_LINE):
				try:
					nextTrainTime = int(train["Min"])
				except:
					# Train is arriving or boarding
					nextTrainTime = 0

				return nextTrainTime
	elif ("Error" in trainJSON):
		nextTrainTime = -99

	return int(nextTrainTime)

#####
# Reboot the device as the network is down
# Displays a red X during reboot
#####
def reboot():
	log("Rebooting as network is not working...")

	ledMatrix = [[1, 0, 0, 0, 0, 0, 0, 1],
		     	 [0, 1, 0, 0, 0, 0, 1, 0],
	      	     [0, 0, 1, 0, 0, 1, 0, 0],
	             [0, 0, 0, 1, 1, 0, 0, 0],
 		     	 [0, 0, 0, 1, 1, 0, 0, 0],
		     	 [0, 0, 1, 0, 0, 1, 0, 0],
		     	 [0, 1, 0, 0, 0, 0, 1, 0],
		     	 [1, 0, 0, 0, 0, 0, 0, 1]
		    	]

	for y in range(8):
		for x in range(8):
			UH.set_pixel(x, y, 255 * ledMatrix[y][x], 0, 0)

	UH.show()

	os.system("reboot")

#####
# Clear the display
#####
def clearDisplay():
	for x in range(8):
		for y in range(8):
			UH.set_pixel(x, y, 0, 0, 0)

		UH.show()
		time.sleep(0.2)

#####
# TODO description
#####
def updateDisplay():
	global consecutiveNetworkErrors
	nextTime = getNextTrainTime(getTrainData())
	r = 0
	g = 0
	b = 0

	if (nextTime == -1):
		# API does not know
		b = 255
		log("Unknown")
	elif (nextTime == -99):
		# Network error
		r = 128
		b = 128
		log("Network error")
		consecutiveNetworkErrors += 1

		if (consecutiveNetworkErrors == MAX_CONSECUTIVE_NETWORK_ERRORS):
			reboot()
	elif (nextTime >= 10):
		# Plenty of time
		g = 255
		log("Lots of time - " + str(nextTime) + " mins")
	elif (nextTime < 10 and nextTime > 5):
		# Pushing it
		r = 238
		g = 238
		log("Not much time - " + str(nextTime) + " mins")
	elif (nextTime >= 0 and nextTime <= 5):
		# No chance
		r = 255
		log("Not enough time - " + str(nextTime) + " mins")
	if (nextTime != -99):
		consecutiveNetworkErrors = 0

	clearDisplay()
	for y in range(8):
		for x in range(8):
			UH.set_pixel(x, y, r, g, b)
		 	time.sleep(0.05)
			UH.show()

#####
# Entry Point
#####

if (not "WMATA_API_KEY" in os.environ):
	log("Please set environment variable WMATA_API_KEY with your API key.")
	exit(1)
else:
	UH.brightness(0.3)
	updateDisplay()
	schedule.every(API_POLL_INTERVAL).seconds.do(updateDisplay)
	while True:
		schedule.run_pending()
		time.sleep(1)
<|endoftext|>


<commit_before>from django.http import HttpResponseRedirect
from django.views.generic import DetailView, ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, ModelFormMixin
from django.urls import reverse_lazy
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from product.models import ProductCategory, ProductType, UnitOfMeasurement, Product, PurchaseUnitOfMeasurement, SaleUnitOfMeasurement
from django.forms import modelformset_factory
from .forms import ProductEditForm

# Create your views here.

@login_required
def manage_product_categories(request):
    ProductCategoryFormSet = modelformset_factory(ProductCategory,
            can_delete=True, fields=['name',])
    if request.method == 'POST':
        formset = ProductCategoryFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = ProductCategoryFormSet()
    return render(request, 'product/productcategory_manage.html',
            {'formset': formset})

@login_required
def manage_product_types(request):
    ProductTypeFormSet = modelformset_factory(ProductType,
            can_delete=True, fields=['name',])
    if request.method == 'POST':
        formset = ProductTypeFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = ProductTypeFormSet()
    return render(request, 'product/producttype_manage.html',
            {'formset': formset})

@login_required
def manage_units_of_measurement(request):
    UnitOfMeasurementFormSet = modelformset_factory(UnitOfMeasurement,
            can_delete=True, fields=['unit',])
    if request.method == 'POST':
        formset = UnitOfMeasurementFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = UnitOfMeasurementFormSet()
    return render(request, 'product/unitofmeasurement_manage.html',
            {'formset': formset})

class ProductList(ListView):
    model = Product
    context_object_name = 'products'

class ProductDetail(DetailView):
    model = Product
    context_object_name = 'product'

class ProductCreate(PermissionRequiredMixin, SuccessMessageMixin, CreateView):
    model = Product
    form_class = ProductEditForm
    permission_required = "product.add_product"
    raise_exception = True
    permsission_denied_message = "You do not have the permission to add products."
    success_message = "Product %(name)s created"

class ProductUpdate(PermissionRequiredMixin, SuccessMessageMixin, UpdateView):
    model = Product
    form_class = ProductEditForm
    permission_required = "product.change_product"
    raise_exception = True
    permission_denied_message = "You do not have the permission to update products."
    success_message = "Product %(name)s updated"

class ProductDelete(PermissionRequiredMixin, DeleteView):
    model = Product
    context_object_name = 'product'
    permission_required = "product.delete_product"
    raise_exception = True
    permission_denied_message = "You do not have the permission to delete products."
    success_url = reverse_lazy('product-list')
    success_message = "Product deleted"
    cancel_message = "Delete cancelled"

    def post(self, request, *args, **kwargs):
        if 'cancel' in request.POST:
            url = self.success_url
            messages.success(self.request, self.cancel_message)
            return HttpResponseRedirect(url)
        else:
            messages.success(self.request, self.success_message)
            return super(ProductDelete, self).delete(request, *args, **kwargs)
<commit_msg>Also add LoginRequiredMixin to product class-based views.<commit_after>from django.http import HttpResponseRedirect
from django.views.generic import DetailView, ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, ModelFormMixin
from django.urls import reverse_lazy
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from product.models import ProductCategory, ProductType, UnitOfMeasurement, Product, PurchaseUnitOfMeasurement, SaleUnitOfMeasurement
from django.forms import modelformset_factory
from .forms import ProductEditForm

# Create your views here.

@login_required
def manage_product_categories(request):
    ProductCategoryFormSet = modelformset_factory(ProductCategory,
            can_delete=True, fields=['name',])
    if request.method == 'POST':
        formset = ProductCategoryFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = ProductCategoryFormSet()
    return render(request, 'product/productcategory_manage.html',
            {'formset': formset})

@login_required
def manage_product_types(request):
    ProductTypeFormSet = modelformset_factory(ProductType,
            can_delete=True, fields=['name',])
    if request.method == 'POST':
        formset = ProductTypeFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = ProductTypeFormSet()
    return render(request, 'product/producttype_manage.html',
            {'formset': formset})

@login_required
def manage_units_of_measurement(request):
    UnitOfMeasurementFormSet = modelformset_factory(UnitOfMeasurement,
            can_delete=True, fields=['unit',])
    if request.method == 'POST':
        formset = UnitOfMeasurementFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse_lazy('product-list'))
    else:
        formset = UnitOfMeasurementFormSet()
    return render(request, 'product/unitofmeasurement_manage.html',
            {'formset': formset})

class ProductList(LoginRequiredMixin, ListView):
    model = Product
    context_object_name = 'products'

class ProductDetail(LoginRequiredMixin, DetailView):
    model = Product
    context_object_name = 'product'

class ProductCreate(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, CreateView):
    model = Product
    form_class = ProductEditForm
    permission_required = "product.add_product"
    raise_exception = True
    permsission_denied_message = "You do not have the permission to add products."
    success_message = "Product %(name)s created"

class ProductUpdate(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView):
    model = Product
    form_class = ProductEditForm
    permission_required = "product.change_product"
    raise_exception = True
    permission_denied_message = "You do not have the permission to update products."
    success_message = "Product %(name)s updated"

class ProductDelete(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    model = Product
    context_object_name = 'product'
    permission_required = "product.delete_product"
    raise_exception = True
    permission_denied_message = "You do not have the permission to delete products."
    success_url = reverse_lazy('product-list')
    success_message = "Product deleted"
    cancel_message = "Delete cancelled"

    def post(self, request, *args, **kwargs):
        if 'cancel' in request.POST:
            url = self.success_url
            messages.success(self.request, self.cancel_message)
            return HttpResponseRedirect(url)
        else:
            messages.success(self.request, self.success_message)
            return super(ProductDelete, self).delete(request, *args, **kwargs)
<|endoftext|>


<commit_before># Allison Schubauer and Daisy Hernandez
# Created: 5/28/2013
# Last Updated: 5/28/2013
# For JCAP

from PyQt4 import QtCore, QtGui
from graph import *

class ProfileWindow(QtGui.QMainWindow):

    def __init__(self, name = "None", varsList = []):
        super(ProfileWindow, self).__init__()
        self.name = name
        self.varsList = varsList
        self.graphs = []

        self.initUI()

    def initUI(self):
        self.setGeometry(300, 200, 200*(len(self.varsList)+1)+100, 650)
        self.setWindowTitle(self.name)

        self.main_widget = QtGui.QWidget(self)
        self.setCentralWidget(self.main_widget)
        grid = QtGui.QGridLayout(self.main_widget)

        num_graphs = len(self.varsList)
        midpoint = (num_graphs+1)/2
        first_row = self.varsList[:midpoint]
        second_row = self.varsList[midpoint:]
        for index in range(len(first_row)):
            newGraph = Graph(parent=None, xvarname="Time",
                             yvarname=first_row[index])
            self.graphs += [newGraph]
            grid.addWidget(newGraph, 0, index)
        for index in range(len(second_row)):
            newGraph = Graph(parent=None, xvarname="Time",
                             yvarname=second_row[index])
            self.graphs += [newGraph]
            grid.addWidget(newGraph, 1, index)

    def updateWindow(self):
        for graph in self.graphs:
            graph.updatePlot()

class LoadMenu(QtGui.QDialog):

    profileChosen = QtCore.pyqtSignal(str)

    def __init__(self, menuList = []):
        super(LoadMenu, self).__init__()

        self.setWindowTitle('Load Profile')

        self.layout = QtGui.QVBoxLayout(self)
        self.list = QtGui.QListWidget(self)
        self.list.addItems(menuList)
        self.layout.addWidget(self.list)

        buttons = QtGui.QDialogButtonBox()
        buttons.setStandardButtons(QtGui.QDialogButtonBox.Ok
                                         | QtGui.QDialogButtonBox.Cancel)
        buttons.accepted.connect(self.sendName)
        buttons.rejected.connect(self.close)
        self.layout.addWidget(buttons)

    def sendName(self):
        name = str(self.list.currentItem().text())
        self.profileChosen.emit(name)
        self.close()

    def updateWindow(self):
        pass
<commit_msg>added comments to profilewindow<commit_after># Allison Schubauer and Daisy Hernandez
# Created: 5/28/2013
# Last Updated: 5/30/2013
# For JCAP

from PyQt4 import QtCore, QtGui
from graph import *

""" window that displays profile after loading """
class ProfileWindow(QtGui.QMainWindow):

    """ takes in name that profile was saved under and list of
        variables to be graphed """
    def __init__(self, name = "None", varsList = []):
        super(ProfileWindow, self).__init__()
        self.name = name
        self.varsList = varsList
        self.graphs = []

        self.initUI()

    """ creates graphics in window """
    def initUI(self):
        # window width is based on number of graphs in profile
        self.setGeometry(100, 50, 200*(len(self.varsList)+1)+50, 1000)
        self.setWindowTitle(self.name)

        # displays graphs in a grid format
        self.main_widget = QtGui.QWidget(self)
        self.setCentralWidget(self.main_widget)
        grid = QtGui.QGridLayout(self.main_widget)

        # divides graphs between two rows in display
        num_graphs = len(self.varsList)
        midpoint = (num_graphs+1)/2
        first_row = self.varsList[:midpoint]
        second_row = self.varsList[midpoint:]

        # creates and adds graphs to appropriate row
        for index in range(len(first_row)):
            newGraph = Graph(parent=None, xvarname="Time",
                             yvarname=first_row[index])
            self.graphs += [newGraph]
            grid.addWidget(newGraph, 0, index)
        for index in range(len(second_row)):
            newGraph = Graph(parent=None, xvarname="Time",
                             yvarname=second_row[index])
            self.graphs += [newGraph]
            grid.addWidget(newGraph, 1, index)

    """ called by MainMenu every second """
    def updateWindow(self):
        for graph in self.graphs:
            graph.updatePlot()

""" menu that shows avaiable profiles and loads user's selection """
class LoadMenu(QtGui.QDialog):

    # this signal will be sent to MainMenu
    profileChosen = QtCore.pyqtSignal(str)

    """ takes in a list of profiles saved for the current data file """
    def __init__(self, menuList = []):
        super(LoadMenu, self).__init__()

        self.setWindowTitle('Load Profile')

        # create the main layout and add the list of profiles
        self.layout = QtGui.QVBoxLayout(self)
        self.list = QtGui.QListWidget(self)
        self.list.addItems(menuList)
        self.layout.addWidget(self.list)

        # create and activate OK and Cancel buttons
        buttons = QtGui.QDialogButtonBox()
        buttons.setStandardButtons(QtGui.QDialogButtonBox.Ok
                                         | QtGui.QDialogButtonBox.Cancel)
        buttons.accepted.connect(self.sendName)
        buttons.rejected.connect(self.close)
        self.layout.addWidget(buttons)

    """ sends name of selected profile to MainMenu,
        which will then load the profile in a new window """
    def sendName(self):
        name = str(self.list.currentItem().text())
        self.profileChosen.emit(name)
        self.close()

    """ called by MainMenu every second; nothing for this widget to do """
    def updateWindow(self):
        pass
<|endoftext|>


<commit_before>from project.models import *
from django import forms
from django.forms import ModelForm
from django.core.exceptions import ValidationError
from filemanager.models import fileobject
from project.models import Project
from django.conf import settings

###        This function validates the form for submitting projects. Excluding the title, thats only done in the createForm.
def cleanify(self, formName):

    print("project.form says pk is "+str(self.project.pk))
    cleaned_data = super(formName, self).clean()

   ###	make certain the selected thumbnail is valid	##
    try:
        thumb = cleaned_data["thumbnail"]
    except:
        thumb = ""

    files=fileobject.objects.filter(project=self.project)###	This gets a list of files from the project

    if thumb:
        noThumb = True
        for fl in files:
            if "uploads/"+str(self.project.pk)+thumb == str(fl.filename) and fl.filetype != "norender" and fl.filetype != "text":
                noThumb = False
                self.project.thumbnail = fl
                print("project.form settng "+self.project.title+"'s thumbnail to "+str(fl))
                break
        if noThumb:
            self._errors['thumbnail'] = [u"The thumbnail you selected is not a valid uploaded image."]
    else:
        noThumb = True
        for fl in files:
            if fl.filetype != 'norender' and fl.filetype != "text":### Look for thumbnailable pic.
                noThumb = False
                self.project.thumbnail = fl
                print("project.form settng "+self.project.title+"'s thumbnail to "+str(fl))
                break
        if noThumb:
            self._errors['thumbnail'] = [u"None of your uploaded file makes a thumbnail!"]##	and an error if they all are.

   ###   make sure user wrote something about thier project.
    if not cleaned_data['body']:
        self._errors['body'] = [u"Write something about your project! Jeezers."]

    return cleaned_data

class ProjectForm(ModelForm):

    def __init__(self, request, project):
        self.project = project
        super(ProjectForm, self).__init__(request)

    class Meta:
        model = Project
        fields = ["body","tags",]

    thumbnail = forms.CharField(required=False)

    def clean(self):
        return cleanify(self, ProjectForm)

class createForm(ModelForm):

    def __init__(self, request, project):
        self.project = project
        if request:
            super(createForm, self).__init__(request)
        else:
            super(createForm, self).__init__()

    class Meta:
        model = Project
        fields = ["title", "body", "tags",]

    def clean_title(self):
       data=self.cleaned_data["title"]
       if not data:
           raise forms.ValidationError("There is no title! You gotta have a title.")
       return data

    thumbnail = forms.CharField(required=False)

    def clean(self):
        return cleanify(self, createForm)

class defaulttag(forms.Form):
    OPTIONS = (
    ("learning", "learning"),
    ("household", "househole"),
    ("abstract", "abstract"),
    ("game", "game")
    )
    categories = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                         choices=OPTIONS)
<commit_msg>Now the project.form prints are fixed.... also, this bug wasn't worth fixing... oh well<commit_after>from project.models import *
from django import forms
from django.forms import ModelForm
from django.core.exceptions import ValidationError
from filemanager.models import fileobject
from project.models import Project
from django.conf import settings

###        This function validates the form for submitting projects. Excluding the title, thats only done in the createForm.
def cleanify(self, formName):

    print("project.form says pk is "+str(self.project.pk))
    cleaned_data = super(formName, self).clean()

   ###	make certain the selected thumbnail is valid	##
    try:
        thumb = cleaned_data["thumbnail"]
    except:
        thumb = ""

    files=fileobject.objects.filter(project=self.project)###	This gets a list of files from the project

    if thumb:
        noThumb = True
        for fl in files:
            if "uploads/"+str(self.project.pk)+thumb == str(fl.filename) and fl.filetype != "norender" and fl.filetype != "text":
                noThumb = False
                self.project.thumbnail = fl
                print("project.form settng "+cleaned_data["title"]+"'s thumbnail to "+str(fl.filename))
                break
        if noThumb:
            self._errors['thumbnail'] = [u"The thumbnail you selected is not a valid uploaded image."]
    else:
        noThumb = True
        for fl in files:
            if fl.filetype != 'norender' and fl.filetype != "text":### Look for thumbnailable pic.
                noThumb = False
                self.project.thumbnail = fl
                print("project.form settng "+cleaned_data["title"]+"'s thumbnail to "+str(fl.filename))
                break
        if noThumb:
            self._errors['thumbnail'] = [u"None of your uploaded file makes a thumbnail!"]##	and an error if they all are.

   ###   make sure user wrote something about thier project.
    if not cleaned_data['body']:
        self._errors['body'] = [u"Write something about your project! Jeezers."]

    return cleaned_data

class ProjectForm(ModelForm):

    def __init__(self, request, project):
        self.project = project
        super(ProjectForm, self).__init__(request)

    class Meta:
        model = Project
        fields = ["body","tags",]

    thumbnail = forms.CharField(required=False)

    def clean(self):
        return cleanify(self, ProjectForm)

class createForm(ModelForm):

    def __init__(self, request, project):
        self.project = project
        if request:
            super(createForm, self).__init__(request)
        else:
            super(createForm, self).__init__()

    class Meta:
        model = Project
        fields = ["title", "body", "tags",]

    def clean_title(self):
       data=self.cleaned_data["title"]
       if not data:
           raise forms.ValidationError("There is no title! You gotta have a title.")
       return data

    thumbnail = forms.CharField(required=False)

    def clean(self):
        return cleanify(self, createForm)

class defaulttag(forms.Form):
    OPTIONS = (
    ("learning", "learning"),
    ("household", "househole"),
    ("abstract", "abstract"),
    ("game", "game")
    )
    categories = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                         choices=OPTIONS)
<|endoftext|>


<commit_before>import datetime

from django import forms
from promgen import models, plugins

class ImportForm(forms.Form):
    config = forms.CharField(widget=forms.Textarea, required=False)
    url = forms.CharField(required=False)
    file_field = forms.FileField(required=False)

class MuteForm(forms.Form):
    def validate_datetime(value):
        try:
            datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
        except:
            raise forms.ValidationError('Invalid timestamp')

    next = forms.CharField(required=False)
    duration = forms.CharField(required=False)
    start = forms.CharField(required=False, validators=[validate_datetime])
    stop = forms.CharField(required=False, validators=[validate_datetime])

    def clean(self):
        duration = self.data.get('duration')
        start = self.data.get('start')
        stop = self.data.get('stop')

        if duration:
            # No further validation is required if only duration is set
            return

        if not all([start, stop]):
            raise forms.ValidationError('Both start and end are required')
        elif datetime.datetime.strptime(start, '%Y-%m-%d %H:%M') > datetime.datetime.strptime(stop, '%Y-%m-%d %H:%M'):
            raise forms.ValidationError('Start time and end time is mismatch')

class ExporterForm(forms.ModelForm):
    class Meta:
        model = models.Exporter
        exclude = ['project']

class ServiceForm(forms.ModelForm):
    class Meta:
        model = models.Service
        exclude = []

class ProjectForm(forms.ModelForm):
    class Meta:
        model = models.Project
        exclude = ['service', 'farm']

class ProjectMove(forms.ModelForm):
    class Meta:
        model = models.Project
        exclude = ['farm']

class URLForm(forms.ModelForm):
    class Meta:
        model = models.URL
        exclude = ['project']

class RuleForm(forms.ModelForm):
    class Meta:
        model = models.Rule
        exclude = ['service']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'clause': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
            'labels': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
            'annotations': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
        }

class RuleCopyForm(forms.Form):
    rule_id = forms.TypedChoiceField(coerce=int, choices=[
        (rule.pk, rule.name) for rule in models.Rule.objects.all()
    ])

class FarmForm(forms.ModelForm):
    class Meta:
        model = models.Farm
        exclude = ['source']

class SenderForm(forms.ModelForm):
    sender = forms.ChoiceField(choices=[
        (entry.module_name, entry.module_name) for entry in plugins.senders()
    ])

    class Meta:
        model = models.Sender
        exclude = ['content_type', 'object_id']

class HostForm(forms.Form):
    hosts = forms.CharField(widget=forms.Textarea)
<commit_msg>Show and sort by service name when showing rules to copy from<commit_after>import datetime

from django import forms
from promgen import models, plugins

class ImportForm(forms.Form):
    config = forms.CharField(widget=forms.Textarea, required=False)
    url = forms.CharField(required=False)
    file_field = forms.FileField(required=False)

class MuteForm(forms.Form):
    def validate_datetime(value):
        try:
            datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
        except:
            raise forms.ValidationError('Invalid timestamp')

    next = forms.CharField(required=False)
    duration = forms.CharField(required=False)
    start = forms.CharField(required=False, validators=[validate_datetime])
    stop = forms.CharField(required=False, validators=[validate_datetime])

    def clean(self):
        duration = self.data.get('duration')
        start = self.data.get('start')
        stop = self.data.get('stop')

        if duration:
            # No further validation is required if only duration is set
            return

        if not all([start, stop]):
            raise forms.ValidationError('Both start and end are required')
        elif datetime.datetime.strptime(start, '%Y-%m-%d %H:%M') > datetime.datetime.strptime(stop, '%Y-%m-%d %H:%M'):
            raise forms.ValidationError('Start time and end time is mismatch')

class ExporterForm(forms.ModelForm):
    class Meta:
        model = models.Exporter
        exclude = ['project']

class ServiceForm(forms.ModelForm):
    class Meta:
        model = models.Service
        exclude = []

class ProjectForm(forms.ModelForm):
    class Meta:
        model = models.Project
        exclude = ['service', 'farm']

class ProjectMove(forms.ModelForm):
    class Meta:
        model = models.Project
        exclude = ['farm']

class URLForm(forms.ModelForm):
    class Meta:
        model = models.URL
        exclude = ['project']

class RuleForm(forms.ModelForm):
    class Meta:
        model = models.Rule
        exclude = ['service']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'clause': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
            'labels': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
            'annotations': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
        }

class RuleCopyForm(forms.Form):
    rule_id = forms.TypedChoiceField(coerce=int, choices=sorted([
        (rule.pk, '<{}> {}'.format(rule.service.name, rule.name)) for rule in models.Rule.objects.all()
    ], key=lambda student: student[1]))

class FarmForm(forms.ModelForm):
    class Meta:
        model = models.Farm
        exclude = ['source']

class SenderForm(forms.ModelForm):
    sender = forms.ChoiceField(choices=[
        (entry.module_name, entry.module_name) for entry in plugins.senders()
    ])

    class Meta:
        model = models.Sender
        exclude = ['content_type', 'object_id']

class HostForm(forms.Form):
    hosts = forms.CharField(widget=forms.Textarea)
<|endoftext|>


<commit_before>"""
Read NMEA from UDP or serial and send position and orientation to Water Linked Underwater GPS
"""
from __future__ import print_function
import requests
import argparse
import time
import logging
import sys
import serial
import pynmea2
import socket

log = logging.getLogger()
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)

class SetupException(Exception):
    pass

class SerialReader(object):
    def __init__(self, port, baud):
        try:
            self.ser = serial.Serial(port, baud, timeout=5.0)
        except serial.SerialException as err:
            print("Serial connection error: {}".format(err))
            raise SetupException()

    def iter(self):
        while True:
            yield self.ser.read()

class UDPReader(object):
    def __init__(self, host, port):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            self.sock.bind((host, port))
        except socket.error as err:
            print("UDP setup: Could not bind to {}:{}. Error: {}".format(host, port, err))
            raise SetupException()

    def iter(self):
        while True:
            data, addr = self.sock.recvfrom(1024)
            print("Got {} bytes from {}: {}".format(len(data), addr, data))
            if not data:
                break
            # Add newline if not present
            if data[-1] != "\n":
                data = data + "\n"
            yield data
        self.sock.close()

def set_position_master(url, latitude, longitude, orientation):
    payload = dict(lat=latitude, lon=longitude, orientation=orientation)
    r = requests.put(url, json=payload, timeout=10)
    if r.status_code != 200:
        log.error("Error setting position and orientation: {} {}".format(r.status_code, r.text))

def run(base_url, conn):
    lat = 0
    lon = 0
    orientation = 0
    gotUpdate = False

    reader = pynmea2.NMEAStreamReader()

    for data in conn.iter():
        try:
          for msg in reader.next(data):
            if type(msg) == pynmea2.types.talker.GGA:
                lat = msg.latitude
                lon = msg.longitude
                gotUpdate = True

            elif type(msg) == pynmea2.types.talker.HDT:
                orientation = msg.heading
                gotUpdate = True

        except pynmea2.ParseError as e:
            log.warning("Error while parsing NMEA string: {}".format(e))

        if gotUpdate:
            log.info('Sending position and orientation')
            set_position_master('{}/api/v1/external/master'.format(base_url), lat, lon, orientation)
            gotUpdate = False

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-u', '--url', help='IP/URL of Underwater GPS kit. Typically http://192.168.2.94', type=str, default='http://demo.waterlinked.com')
    # UDP options
    parser.add_argument('-p', '--port', help="Port to listen for UDP packets", type=int, default=10110)
    parser.add_argument('-i', '--ip', help="Enable UDP by specifying interface to listen for UDP packets. Typically 'localhost' or '0.0.0.0'. Default disabled", type=str, default='')
    # Serial options
    parser.add_argument('-s', '--serial', help="Enable Serial by specifying serial port to use. Example: '/dev/ttyUSB0' or 'COM1' Default disabled", type=str, default='')
    parser.add_argument('-b', '--baud', help="Serial port baud rate", type=int, default=9600)
    args = parser.parse_args()

    if not (args.ip or args.serial):
        parser.print_help()
        print("")
        print("ERROR: Please specify either serial port or UDP port to use")
        print("")
        sys.exit(1)

    if (args.ip and args.serial):
        parser.print_help()
        print("")
        print("ERROR: Please specify either serial port or UDP port to use")
        print("")
        sys.exit(1)

    print("Sending data to Underwater GPS on url: {}".format(args.url))
    if args.serial:
        print("Source Serial {} at {} baud".format(args.serial, args.baud))
        try:
            ser = SerialReader(args.serial, args.baud)
        except SetupException:
            print("Aborting")
            sys.exit(1)

        run(args.url, ser)
        return

    if args.ip:
        print("Source UDP port {} on interface {}".format(args.port, args.ip))
        try:
            reader = UDPReader(args.ip, args.port)
        except SetupException:
            print("Aborting")
            sys.exit(1)

        run(args.url, reader)
        return

if __name__ == "__main__":
    main()
<commit_msg>Fixed two little details/bugs<commit_after>"""
Read NMEA from UDP or serial and send position and orientation to Water Linked Underwater GPS
"""
from __future__ import print_function
import requests
import argparse
import time
import logging
import sys
import serial
import pynmea2
import socket

log = logging.getLogger()
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)

class SetupException(Exception):
    pass

class SerialReader(object):
    def __init__(self, port, baud):
        try:
            self.ser = serial.Serial(port, baud, timeout=5.0)
        except serial.SerialException as err:
            print("Serial connection error: {}".format(err))
            raise SetupException()

    def iter(self):
        while True:
            yield self.ser.read()

class UDPReader(object):
    def __init__(self, host, port):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            self.sock.bind((host, port))
        except socket.error as err:
            print("UDP setup: Could not bind to {}:{}. Error: {}".format(host, port, err))
            raise SetupException()

    def iter(self):
        while True:
            data, addr = self.sock.recvfrom(1024)
            print("Got {} bytes from {}: {}".format(len(data), addr, data))
            if not data:
                break
            # Add newline if not present
            if data[-1] != "\n":
                data = data + "\n"
            yield data
        self.sock.close()

def set_position_master(url, latitude, longitude, orientation):
    payload = dict(lat=latitude, lon=longitude, orientation=orientation)
    #Keep loop running even if for some reason there is no connection.
    try:
        requests.put(url, json=payload, timeout=1)
    except  requests.exceptions.RequestException as err:
        print("Serial connection error: {}".format(err))

def run(base_url, conn):
    lat = 0
    lon = 0
    orientation = 0
    gotUpdate = False

    reader = pynmea2.NMEAStreamReader()

    for data in conn.iter():
        #In case the format is given in bytes
        try:
            data = data.decode('UTF-8')
        except AttributeError:
            pass
        try:
          for msg in reader.next(data):
            if type(msg) == pynmea2.types.talker.GGA:
                lat = msg.latitude
                lon = msg.longitude
                gotUpdate = True

            elif type(msg) == pynmea2.types.talker.HDT:
                orientation = msg.heading
                gotUpdate = True

        except pynmea2.ParseError as e:
            log.warning("Error while parsing NMEA string: {}".format(e))

        if gotUpdate:
            log.info('Sending position and orientation')
            set_position_master('{}/api/v1/external/master'.format(base_url), lat, lon, orientation)
            gotUpdate = False

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-u', '--url', help='IP/URL of Underwater GPS kit. Typically http://192.168.2.94', type=str, default='http://demo.waterlinked.com')
    # UDP options
    parser.add_argument('-p', '--port', help="Port to listen for UDP packets", type=int, default=10110)
    parser.add_argument('-i', '--ip', help="Enable UDP by specifying interface to listen for UDP packets. Typically 'localhost' or '0.0.0.0'. Default disabled", type=str, default='')
    # Serial options
    parser.add_argument('-s', '--serial', help="Enable Serial by specifying serial port to use. Example: '/dev/ttyUSB0' or 'COM1' Default disabled", type=str, default='')
    parser.add_argument('-b', '--baud', help="Serial port baud rate", type=int, default=9600)
    args = parser.parse_args()

    if not (args.ip or args.serial):
        parser.print_help()
        print("")
        print("ERROR: Please specify either serial port or UDP port to use")
        print("")
        sys.exit(1)

    if (args.ip and args.serial):
        parser.print_help()
        print("")
        print("ERROR: Please specify either serial port or UDP port to use")
        print("")
        sys.exit(1)

    print("Sending data to Underwater GPS on url: {}".format(args.url))
    if args.serial:
        print("Source Serial {} at {} baud".format(args.serial, args.baud))
        try:
            ser = SerialReader(args.serial, args.baud)
        except SetupException:
            print("Aborting")
            sys.exit(1)

        run(args.url, ser)
        return

    if args.ip:
        print("Source UDP port {} on interface {}".format(args.port, args.ip))
        try:
            reader = UDPReader(args.ip, args.port)
        except SetupException:
            print("Aborting")
            sys.exit(1)

        run(args.url, reader)
        return

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