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

from __future__ import print_function
from future.standard_library import install_aliases
install_aliases()

from urllib.parse import urlparse, urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError

import json
import os

from flask import Flask
from flask import request
from flask import make_response

# Flask app should start in global layout
app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    req = request.get_json(silent=True, force=True)

    print("Request:")
    print(json.dumps(req, indent=4))

    res = processRequest(req)

    res = json.dumps(res, indent=4)
    # print(res)
    r = make_response(res)
    r.headers['Content-Type'] = 'application/json'
    return r

def processRequest(req):
    if req.get("result").get("action") != "yahooWeatherForecast":
        return {}
    baseurl = "https://query.yahooapis.com/v1/public/yql?"
    yql_query = makeYqlQuery(req)
    if yql_query is None:
        return {}
    yql_url = baseurl + urlencode({'q': yql_query}) + "&format=json"
    result = urlopen(yql_url).read()
    data = json.loads(result)
    res = makeWebhookResult(data)
    return res

def makeYqlQuery(req):
    result = req.get("result")
    parameters = result.get("parameters")
    city = parameters.get("geo-city")
    if city is None:
        return None

    return "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='" + city + "')"

def makeWebhookResult(data):
    buscasitur = "tunja"
    buscasitur_sin_espacio = buscasitur.replace(" ", "%20")
    leer = json.loads(urlopen('http://situr.boyaca.gov.co/wp-json/wp/v2/atractivo_turistico?search=' + buscasitur_sin_espacio).read())
    test = leer[0].get('link')
    query = data.get('query')
    if query is None:
        return {}

    result = query.get('results')
    if result is None:
        return {}

    channel = result.get('channel')
    if channel is None:
        return {}

    item = channel.get('item')
    location = channel.get('location')
    units = channel.get('units')
    if (location is None) or (item is None) or (units is None):
        return {}

    condition = item.get('condition')
    if condition is None:
        return {}

    mahoobox = " hola mundo dato ingresado: "
    datoapi = (json.dumps(item, indent=4))

    # print(json.dumps(item, indent=4))

#    speech = "Hoy Mauricio in " + location.get('city') + ": " + condition.get('text') + ", SI ENTENDIO LA TEMPERATURA " + condition.get('temp') + " " + units.get('temperature')
    speech = "Hoy Mauricio in here " + location.get('city') + mahoobox + condition.get('temp') + test

    print("Response:")
    print(speech)

    return {
        "speech": speech,
        "displayText": speech,
        # "data": data,
        # "contextOut": [],
        "source": "apiai-weather-webhook-sample"
    }

if __name__ == '__main__':
    port = int(os.getenv('PORT', 5000))

    print("Starting app on port %d" % port)

    app.run(debug=False, port=port, host='0.0.0.0')
<commit_msg>uncommentssdf<commit_after>#!/usr/bin/env python

from __future__ import print_function
from future.standard_library import install_aliases
install_aliases()

from urllib.parse import urlparse, urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError

import json
import os

from flask import Flask
from flask import request
from flask import make_response

# Flask app should start in global layout
app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    req = request.get_json(silent=True, force=True)

    print("Request:")
    print(json.dumps(req, indent=4))

    res = processRequest(req)

    res = json.dumps(res, indent=4)
    # print(res)
    r = make_response(res)
    r.headers['Content-Type'] = 'application/json'
    return r

def processRequest(req):
    if req.get("result").get("action") != "yahooWeatherForecast":
        return {}
    baseurl = "https://query.yahooapis.com/v1/public/yql?"
    yql_query = makeYqlQuery(req)
    if yql_query is None:
        return {}
    yql_url = baseurl + urlencode({'q': yql_query}) + "&format=json"
    result = urlopen(yql_url).read()
    data = json.loads(result)
    res = makeWebhookResult(data)
    return res

def makeYqlQuery(req):
    result = req.get("result")
    parameters = result.get("parameters")
    city = parameters.get("geo-city")
    if city is None:
        return None

    return "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='" + city + "')"

def makeWebhookResult(data):
    buscasitur = "tunja"
    buscasitur_sin_espacio = buscasitur.replace(" ", "%20")
    leer = json.loads(urlopen('http://situr.boyaca.gov.co/wp-json/wp/v2/atractivo_turistico?search=' + buscasitur_sin_espacio).read())
    test = leer[0].get('link')
    query = data.get('query')
    if query is None:
        return {}

    result = query.get('results')
    if result is None:
        return {}

    channel = result.get('channel')
    if channel is None:
        return {}

    item = channel.get('item')
    location = channel.get('location')
    units = channel.get('units')
    if (location is None) or (item is None) or (units is None):
        return {}

    condition = item.get('condition')
    if condition is None:
        return {}

    mahoobox = " hola mundo dato ingresado: "
    datoapi = (json.dumps(item, indent=4))

    # print(json.dumps(item, indent=4))

#    speech = "Hoy Mauricio in " + location.get('city') + ": " + condition.get('text') + ", SI ENTENDIO LA TEMPERATURA " + condition.get('temp') + " " + units.get('temperature')
    speech = "Hoy Mauricio in here " + location.get('city') + mahoobox + condition.get('temp') + test

    print("Response:")
    print(speech)

    return {
        "speech": speech,
        "displayText": speech,
         "data": data,
         "contextOut": [],
        "source": "apiai-weather-webhook-sample"
    }

if __name__ == '__main__':
    port = int(os.getenv('PORT', 5000))

    print("Starting app on port %d" % port)

    app.run(debug=False, port=port, host='0.0.0.0')
<|endoftext|>


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

import datetime
import json
import psycopg2
import requests
from bs4 import BeautifulSoup
from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
from urllib.parse import quote, unquote, urlencode

app = Flask(__name__)
CORS(app)

with open('./config.json', 'r') as f:
    config = json.load(f)
    db = config['db']
    user = config['user']

@app.route('/api/repos', methods=['GET'])
def repos():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            sql = "SELECT data FROM repos"
            ids = []
            if 'ids' in request.args:
                ids = [i.strip() for i in request.args.get('ids').split(',')]
                sql += " WHERE id IN (%s)" % ','.join(['%s']*len(ids))
                sql += " ORDER BY data->>'updated_at' DESC;"
            cur.execute(sql, ids)
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/issues', methods=['GET'])
def issues():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            sql = "SELECT a.data from "
            if 'labels' in request.args:
                labels = [l.strip() for l in request.args.get('labels').split(',')]
                sql += "(SELECT * FROM issues, jsonb_array_elements(data->'labels') l WHERE l->>'name' = Any ('{%s}')) AS a" % ','.join(labels)
            else:
                sql += "(SELECT * FROM issues) AS a"
            if 'language' in request.args:
                language = request.args.get('language').lower()
                sql += " INNER JOIN (SELECT r.id FROM repos r WHERE lower(r.data->>'language') = '%s') AS b ON a.repo_id = b.id" % language
            sql += " ORDER BY a.data->>'updated_at' DESC;"
            cur.execute(sql)
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/labels', methods=['GET'])
def labels():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            cur.execute('SELECT name FROM labels ORDER BY name DESC;')
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/gas', methods=['GET'])
def gas():
    gdn = 'https://www.github.com'

    if 'prev_page' in request.args:
        query = unquote(request.args.get('prev_page'))
    elif 'next_page' in request.args:
        query = unquote(request.args.get('next_page'))
    else:
        q = 'state:open updated:<%s' % datetime.datetime.utcnow().isoformat()

        with open('./data/url_list.json', 'r') as f:
            urls = json.load(f)
            q += ''.join([u.replace('https://github.com/', ' repo:') for u in urls])

        if 'language' in request.args:
            q += ' language:%s' % request.args.get('language')

        if 'labels' in request.args:
            labels = [l.strip() for l in request.args.get('labels').split(',')]
            q += ''.join([' label:%s' % l for l in labels])

        params = {'q': q, 'l': '', 'o': 'desc', 'ref': 'advsearch', 's': 'updated', 'type': 'Issues', 'utf8': '✓'}
        query = '/search?%s' % urlencode(params)

    j = {}
    issues = []
    r = requests.get(gdn + query)

    # html parsing
    soup = BeautifulSoup(r.text, 'html.parser')
    items = soup.find_all('div', class_='issue-list-item public')
    for item in items:
        issue = {}
        issue['sn'] = item.span.contents[0].replace('#', '')

        all_p = item.find_all('p')
        issue['html_url'] = gdn + all_p[0].a['href']
        issue['title'] = all_p[0].a['title']
        issue['body'] = all_p[1].contents[0] if all_p[1].contents else ''

        all_li = item.ul.find_all('li')
        issue['issues_html_url'] = gdn + all_li[0].a['href']
        issue['user_html_url'] = gdn + all_li[1].a['href']
        issue['updated_at'] = all_li[1].find('relative-time')['datetime']
        issue['comments'] = int(all_li[2].strong.contents[0]) if len(all_li) >= 3 else 0

        issues.append(issue)

    prev_page = soup.find('a', class_='prev_page')
    if prev_page:
        j['prev_page'] = quote(unquote(prev_page['href']))

    next_page = soup.find('a', class_='next_page')
    if next_page:
        j['next_page'] = quote(unquote(next_page['href']))

    j['result'] = issues

    return jsonify(**j)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

<commit_msg>Add limit and offset<commit_after>#!/usr/bin/env python3

import datetime
import json
import psycopg2
import requests
from bs4 import BeautifulSoup
from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
from urllib.parse import quote, unquote, urlencode

app = Flask(__name__)
CORS(app)

with open('./config.json', 'r') as f:
    config = json.load(f)
    db = config['db']
    user = config['user']

def append_limit_offset_sql(request, sql):
    try:
        limit = int(request.args.get('limit'))
    except Exception as e:
        limit = 30
    sql += " LIMIT %d" % limit

    try:
        offset = int(request.args.get('offset'))
    except Exception as e:
        offset = 0
    sql += " OFFSET %d" % offset

    return sql

@app.route('/api/repos', methods=['GET'])
def repos():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            sql = "SELECT data FROM repos"
            ids = []
            if 'ids' in request.args:
                ids = [i.strip() for i in request.args.get('ids').split(',')]
                sql += " WHERE id IN (%s)" % ','.join(['%s']*len(ids))
                sql += " ORDER BY data->>'updated_at' DESC"
            sql = append_limit_offset_sql(request, sql) + ";"
            cur.execute(sql, ids)
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/issues', methods=['GET'])
def issues():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            sql = "SELECT a.data from "
            if 'labels' in request.args:
                labels = [l.strip() for l in request.args.get('labels').split(',')]
                sql += "(SELECT * FROM issues, jsonb_array_elements(data->'labels') l WHERE l->>'name' = Any ('{%s}')) AS a" % ','.join(labels)
            else:
                sql += "(SELECT * FROM issues) AS a"
            if 'language' in request.args:
                language = request.args.get('language').lower()
                sql += " INNER JOIN (SELECT r.id FROM repos r WHERE lower(r.data->>'language') = '%s') AS b ON a.repo_id = b.id" % language
            sql += " ORDER BY a.data->>'updated_at' DESC"
            sql = append_limit_offset_sql(request, sql) + ";"
            cur.execute(sql)
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/labels', methods=['GET'])
def labels():
    with psycopg2.connect(database=db, user=user) as conn:
        with conn.cursor() as cur:
            sql = 'SELECT name FROM labels ORDER BY name DESC'
            sql = append_limit_offset_sql(request, sql) + ";"
            cur.execute(sql)
            rs = cur.fetchall()
            j = {'result': [r[0] for r in rs]}
            return jsonify(**j)
    abort(500)

@app.route('/api/gas', methods=['GET'])
def gas():
    gdn = 'https://www.github.com'

    if 'prev_page' in request.args:
        query = unquote(request.args.get('prev_page'))
    elif 'next_page' in request.args:
        query = unquote(request.args.get('next_page'))
    else:
        q = 'state:open updated:<%s' % datetime.datetime.utcnow().isoformat()

        with open('./data/url_list.json', 'r') as f:
            urls = json.load(f)
            q += ''.join([u.replace('https://github.com/', ' repo:') for u in urls])

        if 'language' in request.args:
            q += ' language:%s' % request.args.get('language')

        if 'labels' in request.args:
            labels = [l.strip() for l in request.args.get('labels').split(',')]
            q += ''.join([' label:%s' % l for l in labels])

        params = {'q': q, 'l': '', 'o': 'desc', 'ref': 'advsearch', 's': 'updated', 'type': 'Issues', 'utf8': '✓'}
        query = '/search?%s' % urlencode(params)

    j = {}
    issues = []
    r = requests.get(gdn + query)

    # html parsing
    soup = BeautifulSoup(r.text, 'html.parser')
    items = soup.find_all('div', class_='issue-list-item public')
    for item in items:
        issue = {}
        issue['sn'] = item.span.contents[0].replace('#', '')

        all_p = item.find_all('p')
        issue['html_url'] = gdn + all_p[0].a['href']
        issue['title'] = all_p[0].a['title']
        issue['body'] = all_p[1].contents[0] if all_p[1].contents else ''

        all_li = item.ul.find_all('li')
        issue['issues_html_url'] = gdn + all_li[0].a['href']
        issue['user_html_url'] = gdn + all_li[1].a['href']
        issue['updated_at'] = all_li[1].find('relative-time')['datetime']
        issue['comments'] = int(all_li[2].strong.contents[0]) if len(all_li) >= 3 else 0

        issues.append(issue)

    prev_page = soup.find('a', class_='prev_page')
    if prev_page:
        j['prev_page'] = quote(unquote(prev_page['href']))

    next_page = soup.find('a', class_='next_page')
    if next_page:
        j['next_page'] = quote(unquote(next_page['href']))

    j['result'] = issues

    return jsonify(**j)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

<|endoftext|>


<commit_before>from classifier import clf
from flask import Flask, render_template, jsonify, request, json
from hand_data import get_hand_position
from lib import Leap
import pickle
import random
import redis

app = Flask(__name__)

controller = Leap.Controller()
controller.set_policy(Leap.Controller.POLICY_BACKGROUND_FRAMES)

past_symbol = 'a'
prev_prediction = None

r = redis.StrictRedis(host='localhost', port=6379, db=0)

@app.route('/translate')
def translate():
    return render_template('ui.html')

@app.route('/')
def tutorial():
    return render_template('tutorial.html')

@app.route('/score', methods=['POST'])
def add_score():
    data = request.form
    try:
        record = json.dumps({'user': data['user'], 'score': int(data['score'])})
        print record
        result = r.lpush('scoreboard', record)
        return jsonify(error=result)
    except KeyError:
        return jsonify(error=True)

@app.route('/scores', methods=['GET'])
def get_scores():
    scores = [json.loads(i) for i in r.lrange('scoreboard', 0, 100)]
    scores.sort(key=lambda s: s['score'], reverse=True)
    return json.dumps(scores)

@app.route('/current')
def current_symbol():
    global past_symbol
    global prev_prediction

    # Is there a hand?
    hand_pos = get_hand_position(controller)
    if not hand_pos:
        new = past_symbol != ' '
        past_symbol = ' '
        return jsonify(symbol=' ', new=new)
    features = [v for k, v in hand_pos.iteritems()]

    # Do we have a new symbol?
    prediction = ''.join(clf.predict(features))
    if prediction == prev_prediction:
        # We good fam
        return jsonify(new=False, symbol=prediction)
    else:
        prev_prediction = prediction
        return jsonify(new=True, symbol=prediction)

@app.route('/splash')
def splash():
    return render_template('splash.html')

@app.route('/scoreboard')
def scoreboard():
    return jsonify(user_score=100)

if __name__ == '__main__':
    app.run(debug=True)
<commit_msg>Use jsonify instead of dumps<commit_after>from classifier import clf
from flask import Flask, render_template, jsonify, request, json
from hand_data import get_hand_position
from lib import Leap
import pickle
import random
import redis

app = Flask(__name__)

controller = Leap.Controller()
controller.set_policy(Leap.Controller.POLICY_BACKGROUND_FRAMES)

past_symbol = 'a'
prev_prediction = None

r = redis.StrictRedis(host='localhost', port=6379, db=0)

@app.route('/translate')
def translate():
    return render_template('ui.html')

@app.route('/')
def tutorial():
    return render_template('tutorial.html')

@app.route('/score', methods=['POST'])
def add_score():
    data = request.form
    try:
        record = json.dumps({'user': data['user'], 'score': int(data['score'])})
        print record
        result = r.lpush('scoreboard', record)
        return jsonify(error=result)
    except KeyError:
        return jsonify(error=True)

@app.route('/scores', methods=['GET'])
def get_scores():
    scores = [json.loads(i) for i in r.lrange('scoreboard', 0, 100)]
    scores.sort(key=lambda s: s['score'], reverse=True)
    return jsonify(scores=scores)

@app.route('/current')
def current_symbol():
    global past_symbol
    global prev_prediction

    # Is there a hand?
    hand_pos = get_hand_position(controller)
    if not hand_pos:
        new = past_symbol != ' '
        past_symbol = ' '
        return jsonify(symbol=' ', new=new)
    features = [v for k, v in hand_pos.iteritems()]

    # Do we have a new symbol?
    prediction = ''.join(clf.predict(features))
    if prediction == prev_prediction:
        # We good fam
        return jsonify(new=False, symbol=prediction)
    else:
        prev_prediction = prediction
        return jsonify(new=True, symbol=prediction)

@app.route('/splash')
def splash():
    return render_template('splash.html')

@app.route('/scoreboard')
def scoreboard():
    return jsonify(user_score=100)

if __name__ == '__main__':
    app.run(debug=True)
<|endoftext|>


<commit_before># core dependencies
from flask import Flask, render_template, request, session, redirect, url_for, send_from_directory
from functools import wraps
import sys, os
import pandas
sys.path.insert(0, './utils/')

# project imports
from database import DBManager
from Constants import *
from database_setup import delete_project_table, get_excel, load_excel_file

# security imports
from werkzeug import secure_filename

################################################################################
# Python Flask based server script for graduation requirement tracker          #
#                                                                              #
# Authors                                                                      #
#  Yicheng Wang                                                                #
#  Ariel Levy                                                                  #
#  Ethan Cheng
#  Loren Maggiore                                                              #
#                                                                              #
# Description                                                                  #
#  TODO                                                                        #
#                                                                              #
################################################################################

#{{{ Preamble
app_path = os.path.realpath(__file__)
app_dir = os.path.dirname(app_path)

UPLOAD_FOLDER = app_dir + '/uploaded_files/'
DOWNLOAD_FOLDER = app_dir + '/downloadables/'
ALLOWED_EXTENSIONS = set(['xlsx', 'xls'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['DOWNLOAD_FOLDER'] = DOWNLOAD_FOLDER

print "Saving files to: ", app.config['UPLOAD_FOLDER']
print "Generating files in: ", app.config['DOWNLOAD_FOLDER']

db_m = DBManager(PROJECT_DB_NAME, COURSES_TABLE_NAME, STUDENT_TABLE_NAME)
#}}}
#{{{ Decorator Functions
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if "logged_in" not in session or not session['logged_in']:
            session.clear()
            return redirect(url_for("login"))
        return f(*args, **kwargs)
    return decorated_function

def redirect_if_logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'logged_in' in session and session['logged_in']:
            return redirect(url_for("class_view"))
        return f(*args, **kwargs)
    return decorated_function
#}}}
#{{{ Pages
@app.route("/")
def home():
    """
    home: returns the home page

    Returns:
        the home page
    """
    return render_template("master.html")

@app.route('/login', methods=["GET", "POST"])
@app.route('/login/', methods=["GET", "POST"])
@redirect_if_logged_in
def login():
    """
    login_page: returns the login page

    Returns:
        the login page
    """
    return render_template("login.html")

@app.route('/class', methods = ['GET'])
@app.route('/class/', methods = ['GET'])
# @login_required
def class_view():
    """
    class_view: returns the student data for all students

    This applies filters specified by the GET request, including:
        - grade
        - TODO: ADD MORE

    Returns:
        the page with data of the specified graduating year
    """
    grades = []
    req_statuses = [[], [], [], [], [], [], []]

    get_req_args = request.args

    if not get_req_args:
        return render_template('class.html', students = db_m.get_all_students_info())

    logic = get_req_args.get( 'logic' )
    change_db_logic(logic)
    for grade in range(9, 13):
        if get_req_args.get( 'grade-' + str( grade ) ) == 'on':
            grades.append(str( grade ))

    for req in range(0, 7):
        if get_req_args.get( str( req ) + '-fulfilled' ) == 'on':
            req_statuses[req].append(0)
        if get_req_args.get( str( req ) + '-missing' ) == 'on':
            req_statuses[req].append(1)
        if get_req_args.get( str( req ) + '-failed' ) == 'on':
            req_statuses[req].append(2)

    list_of_students = [student_info for student_info
                            in db_m.get_students_such_that(req_statuses)
                            if student_info['grade'] in grades]

    export_student_list(list_of_students)

    return render_template("class.html", students=list_of_students, boxes = dict( get_req_args ))

@app.route('/student', methods = ['GET'])
@app.route('/student/', methods = ['GET'])
def student_search():
    return redirect(url_for('student_view', OSIS = request.args.get('osis')))

@app.route('/student/<OSIS>')
@app.route('/student/<OSIS>/')
# @login_required
def student_view(OSIS=0):
    """
    student_view: returns the page for single-student data. By default, if
    failed, will return the page with fake data.

    Args:
        OSIS (string): OSIS of student

    Returns:
        the page with the specified student's data
    """

    student_info = db_m.get_student_info(OSIS)
    list_of_courses = [""] * 7
    next_term_suggestions = [""] * 7
    if not student_info:
        return render_template("student_not_found.html", osis=OSIS)
        # Default data for testing
        student_info = {
            "osis" : "123456789",
            "lastn" : "Rachmaninoff",
            "firstn" : "Sergei Vasilievich",
            "grade" : "12",
            "offcl" : "7CC"
        }
        list_of_courses = [
            "ART APPRECIATION",
            "BEGINNING BAND",
            "INTRO COMP SCI 1 OF 2",
            "TECHNICAL GRAPHIC COMMUNICATIONS",
            "BEGINNING BAND, CONCERT BAND, SYMPHONIC BAND",
            "HEALTH"
        ]
    else:
        for i in range(len(list_of_courses)):
            data = db_m.get_relevant_courses(OSIS, i)
            courses = {}
            for entry in data:
                if entry[2] == 'F' or entry[2] == 'NC' or entry[2] == 'NS' or int(entry[2]) < 65:
                    if entry[0] + " (FAILED)" in courses:
                        courses[entry[0] + " (FAILED)"] += 1
                    else:
                        courses[entry[0] + " (FAILED)"] = 1
                elif entry[0] in courses:
                    courses[entry[0]] += 1
                else:
                    courses[entry[0]] = 1

            def format_output(d):
                output = []
                for key in d:
                    output.append("%s (%d)" % (key, d[key]))
                return ", ".join(output)

            list_of_courses[i] = "None" if courses == {} else format_output(courses)

            need_to_take = db_m.get_req_course_track(OSIS, i)[1]
            for j in need_to_take:
                if j == []: # fufilled
                    next_term_suggestions[i] = "Fufilled"

            if next_term_suggestions[i] == "":
                suggestions = ""
                for j in need_to_take:
                    for k in j[0]:
                        suggestions += str( k ) + ', '

                suggestions = suggestions[:-2]

                next_term_suggestions[i] = suggestions

    return render_template("student.html", profile=student_info,
            courses=list_of_courses, suggestions = next_term_suggestions)

@app.route('/data')
@app.route('/data/')
# @login_required
def manage_data():
    """
    manage_data: returns the page for data management

    Returns:
        the page with links to manage database
    """
    return render_template("data.html")

def allowed_filename(filename):
    """
    Utility function to verify a file extension

    Returns:
        True if the filename is that of an Excel file
    """
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/upload', methods=["GET", "POST"])
@app.route('/upload/', methods=["GET", "POST"])
# @login_required
def upload():
    """
    upload: takes a .xls or .xlsx file and models the database.
    #TODO: (enhancement) allow the user to undo, or revert to previous versions
    #TODO: (enhancement) load the file into the database asynchronously and
    display a progress bar.

    Returns:
        The upload page (regardless of whether not you are uploading or not
    """
    if request.method == 'POST':
        f = request.files['file']
        if f and allowed_filename(f.filename):
            secure_name = secure_filename(f.filename)
            path_to_uploaded = os.path.join(app.config['UPLOAD_FOLDER'], secure_name)
            print "Saving file to: ", path_to_uploaded
            f.save(os.path.join(path_to_uploaded))
            print "Deleting database to clean state..."
            delete_project_table()
            print "Loading database..."
            load_excel_file(get_excel(path_to_uploaded))
            print "Removing file to save storage..."
            os.remove(path_to_uploaded)
        else:
            print "File extension not allowed!", str(f)

        return redirect(url_for("class_view"))
    else:
        return render_template("upload.html")

# @app.route('/export_filtered', methods = ['POST'])
# @app.route('/export_filtered/', methods = ['POST'])
def export_student_list(student_list):
    """
    Generates an excel file given a student_list (formated the same way as
    list_of_students from the class view route.

    Args:
        student_list: a list of dictionaries of student data
            [
                {
                    'offcl': 'nan',
                    'firstn': 'nan',
                    'grade': '9',
                    'lastn': 'nan',
                    'osis': '701111441',
                    'req_status': [1, 1, 1, 1, 1, 1, 1]
                },
                ...
            ]

    Returns:
        An Excel file for the user to download
    """
    data = []
    for student in student_list:
        row = {
                "OSIS" : student['osis'],
                "OFF. CLASS" : student['offcl'],
                "GRADE" : student['grade'],
                "LAST NAME" : student['lastn'],
                "FIRST NAME" : student['firstn']
        }
        data.append(row)
    df = pandas.DataFrame(data)
    print df

    filename = "filtered.xlsx" # TODO: Make the filename the filter options
    if allowed_filename(filename):
        secure_name = secure_filename(filename)
        path_to_filtered = os.path.join(app.config['DOWNLOAD_FOLDER'], secure_name)
        if os.path.isfile(path_to_filtered):
            os.remove(path_to_filtered)
        df.to_excel(path_to_filtered, index=False)
        # return send_from_directory(directory=app.config['DOWNLOAD_FOLDER'],
        #        filename=secure_name)
    else:
        return None

#}}}
#{{{ AJAX Calls
@app.route('/update_reqs', methods = ['GET', 'POST'])
@app.route('/update_reqs/', methods = ['GET', 'POST'])
def update_graduation_requirements():
    """
    update_graduation_requirements: AJAX call to server that updates the
    graduation requirements

    Returns:
        JSON status for success or failure
    """
    return ""

@app.route('/update_db/<int:grad_year>', methods = ['GET', 'POST'])
@app.route('/update_db/<int:grad_year>/', methods = ['GET', 'POST'])
def update_db(grad_year):
    """
    update_db: AJAX call that updates the student info of a given graduating
    year in the database

    Args:
        grad_year (int): the specified graduation year

    Returns:
        JSON status for success or failure
    """
    return ""

@app.route('/update_student/<OSIS>', methods = ['GET', 'POST'])
@app.route('/update_student/<OSIS>/', methods = ['GET', 'POST'])
def update_student(OSIS):
    """
    update_student: updates the information on a single student in the database

    Args:
        OSIS (string): the OSIS for the student

    Returns:
        JSON status for success or failure
    """
    return ""
#}}}

if __name__ == "__main__":
    app.run(host = "0.0.0.0", port = 8000, debug = True)

<commit_msg>fixed problem<commit_after># core dependencies
from flask import Flask, render_template, request, session, redirect, url_for, send_from_directory
from functools import wraps
import sys, os
import pandas
sys.path.insert(0, './utils/')

# project imports
from database import DBManager
from Constants import *
from database_setup import delete_project_table, get_excel, load_excel_file

# security imports
from werkzeug import secure_filename

################################################################################
# Python Flask based server script for graduation requirement tracker          #
#                                                                              #
# Authors                                                                      #
#  Yicheng Wang                                                                #
#  Ariel Levy                                                                  #
#  Ethan Cheng
#  Loren Maggiore                                                              #
#                                                                              #
# Description                                                                  #
#  TODO                                                                        #
#                                                                              #
################################################################################

#{{{ Preamble
app_path = os.path.realpath(__file__)
app_dir = os.path.dirname(app_path)

UPLOAD_FOLDER = app_dir + '/uploaded_files/'
DOWNLOAD_FOLDER = app_dir + '/downloadables/'
ALLOWED_EXTENSIONS = set(['xlsx', 'xls'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['DOWNLOAD_FOLDER'] = DOWNLOAD_FOLDER

print "Saving files to: ", app.config['UPLOAD_FOLDER']
print "Generating files in: ", app.config['DOWNLOAD_FOLDER']

db_m = DBManager(PROJECT_DB_NAME, COURSES_TABLE_NAME, STUDENT_TABLE_NAME)
#}}}
#{{{ Decorator Functions
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if "logged_in" not in session or not session['logged_in']:
            session.clear()
            return redirect(url_for("login"))
        return f(*args, **kwargs)
    return decorated_function

def redirect_if_logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'logged_in' in session and session['logged_in']:
            return redirect(url_for("class_view"))
        return f(*args, **kwargs)
    return decorated_function
#}}}
#{{{ Pages
@app.route("/")
def home():
    """
    home: returns the home page

    Returns:
        the home page
    """
    return render_template("master.html")

@app.route('/login', methods=["GET", "POST"])
@app.route('/login/', methods=["GET", "POST"])
@redirect_if_logged_in
def login():
    """
    login_page: returns the login page

    Returns:
        the login page
    """
    return render_template("login.html")

@app.route('/class', methods = ['GET'])
@app.route('/class/', methods = ['GET'])
# @login_required
def class_view():
    """
    class_view: returns the student data for all students

    This applies filters specified by the GET request, including:
        - grade
        - TODO: ADD MORE

    Returns:
        the page with data of the specified graduating year
    """
    grades = []
    req_statuses = [[], [], [], [], [], [], []]

    get_req_args = request.args

    if not get_req_args:
        return render_template('class.html', students = db_m.get_all_students_info())

    logic = get_req_args.get( 'logic' )
    db_m.change_db_logic(logic)
    for grade in range(9, 13):
        if get_req_args.get( 'grade-' + str( grade ) ) == 'on':
            grades.append(str( grade ))

    for req in range(0, 7):
        if get_req_args.get( str( req ) + '-fulfilled' ) == 'on':
            req_statuses[req].append(0)
        if get_req_args.get( str( req ) + '-missing' ) == 'on':
            req_statuses[req].append(1)
        if get_req_args.get( str( req ) + '-failed' ) == 'on':
            req_statuses[req].append(2)

    list_of_students = [student_info for student_info
                            in db_m.get_students_such_that(req_statuses)
                            if student_info['grade'] in grades]

    export_student_list(list_of_students)

    return render_template("class.html", students=list_of_students, boxes = dict( get_req_args ))

@app.route('/student', methods = ['GET'])
@app.route('/student/', methods = ['GET'])
def student_search():
    return redirect(url_for('student_view', OSIS = request.args.get('osis')))

@app.route('/student/<OSIS>')
@app.route('/student/<OSIS>/')
# @login_required
def student_view(OSIS=0):
    """
    student_view: returns the page for single-student data. By default, if
    failed, will return the page with fake data.

    Args:
        OSIS (string): OSIS of student

    Returns:
        the page with the specified student's data
    """

    student_info = db_m.get_student_info(OSIS)
    list_of_courses = [""] * 7
    next_term_suggestions = [""] * 7
    if not student_info:
        return render_template("student_not_found.html", osis=OSIS)
        # Default data for testing
        student_info = {
            "osis" : "123456789",
            "lastn" : "Rachmaninoff",
            "firstn" : "Sergei Vasilievich",
            "grade" : "12",
            "offcl" : "7CC"
        }
        list_of_courses = [
            "ART APPRECIATION",
            "BEGINNING BAND",
            "INTRO COMP SCI 1 OF 2",
            "TECHNICAL GRAPHIC COMMUNICATIONS",
            "BEGINNING BAND, CONCERT BAND, SYMPHONIC BAND",
            "HEALTH"
        ]
    else:
        for i in range(len(list_of_courses)):
            data = db_m.get_relevant_courses(OSIS, i)
            courses = {}
            for entry in data:
                if entry[2] == 'F' or entry[2] == 'NC' or entry[2] == 'NS' or int(entry[2]) < 65:
                    if entry[0] + " (FAILED)" in courses:
                        courses[entry[0] + " (FAILED)"] += 1
                    else:
                        courses[entry[0] + " (FAILED)"] = 1
                elif entry[0] in courses:
                    courses[entry[0]] += 1
                else:
                    courses[entry[0]] = 1

            def format_output(d):
                output = []
                for key in d:
                    output.append("%s (%d)" % (key, d[key]))
                return ", ".join(output)

            list_of_courses[i] = "None" if courses == {} else format_output(courses)

            need_to_take = db_m.get_req_course_track(OSIS, i)[1]
            for j in need_to_take:
                if j == []: # fufilled
                    next_term_suggestions[i] = "Fufilled"

            if next_term_suggestions[i] == "":
                suggestions = ""
                for j in need_to_take:
                    for k in j[0]:
                        suggestions += str( k ) + ', '

                suggestions = suggestions[:-2]

                next_term_suggestions[i] = suggestions

    return render_template("student.html", profile=student_info,
            courses=list_of_courses, suggestions = next_term_suggestions)

@app.route('/data')
@app.route('/data/')
# @login_required
def manage_data():
    """
    manage_data: returns the page for data management

    Returns:
        the page with links to manage database
    """
    return render_template("data.html")

def allowed_filename(filename):
    """
    Utility function to verify a file extension

    Returns:
        True if the filename is that of an Excel file
    """
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/upload', methods=["GET", "POST"])
@app.route('/upload/', methods=["GET", "POST"])
# @login_required
def upload():
    """
    upload: takes a .xls or .xlsx file and models the database.
    #TODO: (enhancement) allow the user to undo, or revert to previous versions
    #TODO: (enhancement) load the file into the database asynchronously and
    display a progress bar.

    Returns:
        The upload page (regardless of whether not you are uploading or not
    """
    if request.method == 'POST':
        f = request.files['file']
        if f and allowed_filename(f.filename):
            secure_name = secure_filename(f.filename)
            path_to_uploaded = os.path.join(app.config['UPLOAD_FOLDER'], secure_name)
            print "Saving file to: ", path_to_uploaded
            f.save(os.path.join(path_to_uploaded))
            print "Deleting database to clean state..."
            delete_project_table()
            print "Loading database..."
            load_excel_file(get_excel(path_to_uploaded))
            print "Removing file to save storage..."
            os.remove(path_to_uploaded)
        else:
            print "File extension not allowed!", str(f)

        return redirect(url_for("class_view"))
    else:
        return render_template("upload.html")

# @app.route('/export_filtered', methods = ['POST'])
# @app.route('/export_filtered/', methods = ['POST'])
def export_student_list(student_list):
    """
    Generates an excel file given a student_list (formated the same way as
    list_of_students from the class view route.

    Args:
        student_list: a list of dictionaries of student data
            [
                {
                    'offcl': 'nan',
                    'firstn': 'nan',
                    'grade': '9',
                    'lastn': 'nan',
                    'osis': '701111441',
                    'req_status': [1, 1, 1, 1, 1, 1, 1]
                },
                ...
            ]

    Returns:
        An Excel file for the user to download
    """
    data = []
    for student in student_list:
        row = {
                "OSIS" : student['osis'],
                "OFF. CLASS" : student['offcl'],
                "GRADE" : student['grade'],
                "LAST NAME" : student['lastn'],
                "FIRST NAME" : student['firstn']
        }
        data.append(row)
    df = pandas.DataFrame(data)
    print df

    filename = "filtered.xlsx" # TODO: Make the filename the filter options
    if allowed_filename(filename):
        secure_name = secure_filename(filename)
        path_to_filtered = os.path.join(app.config['DOWNLOAD_FOLDER'], secure_name)
        if os.path.isfile(path_to_filtered):
            os.remove(path_to_filtered)
        df.to_excel(path_to_filtered, index=False)
        # return send_from_directory(directory=app.config['DOWNLOAD_FOLDER'],
        #        filename=secure_name)
    else:
        return None

#}}}
#{{{ AJAX Calls
@app.route('/update_reqs', methods = ['GET', 'POST'])
@app.route('/update_reqs/', methods = ['GET', 'POST'])
def update_graduation_requirements():
    """
    update_graduation_requirements: AJAX call to server that updates the
    graduation requirements

    Returns:
        JSON status for success or failure
    """
    return ""

@app.route('/update_db/<int:grad_year>', methods = ['GET', 'POST'])
@app.route('/update_db/<int:grad_year>/', methods = ['GET', 'POST'])
def update_db(grad_year):
    """
    update_db: AJAX call that updates the student info of a given graduating
    year in the database

    Args:
        grad_year (int): the specified graduation year

    Returns:
        JSON status for success or failure
    """
    return ""

@app.route('/update_student/<OSIS>', methods = ['GET', 'POST'])
@app.route('/update_student/<OSIS>/', methods = ['GET', 'POST'])
def update_student(OSIS):
    """
    update_student: updates the information on a single student in the database

    Args:
        OSIS (string): the OSIS for the student

    Returns:
        JSON status for success or failure
    """
    return ""
#}}}

if __name__ == "__main__":
    app.run(host = "0.0.0.0", port = 8000, debug = True)

<|endoftext|>


<commit_before># Copyright 2010 Gregory L. Rosenblatt

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

################################################################
# types
class Type:
    def contains(self, ty, tenv=None): return self is ty
    def __repr__(self): return '<%s %s>'%(self.__class__.__name__, self)

class BasicType(Type): pass

class ScalarType(BasicType): pass
#class PyType(ScalarType): pass

class AggregateType(BasicType): pass # future: alignment
class StructType(AggregateType): pass # heterogeneous els
class ArrayType(AggregateType): pass # homogeneous els

# combine removal/addition in an update operation:
# tables/records: ({?a}//{?b})|{?c} # can also use struct-like repacking?
# arrays: reslice arr [(old-range new-subarr) (old-range new-subarr) ...]
# structs (no resizing): repack struct [(0 ?v) (2 ?v) ...]

class BoxedType(Type): pass # regions: mutability
class RefType(BoxedType): pass # strict, non-polymorphic, no ptr-arithmetic
#class DynArrayType(RefType): pass
#class DynArrayRefType(RefType): pass # ptr-like refs w/arithmetic to DA data
#class WeakRefType(RefType): pass # stores boxed element in unmanaged memory
#class ResourceType(RefType): pass # finalizable

# more general record type to support row-typing?
class TableType(BoxedType): pass # scalar/hashable keys; homogeneous els

class TaggedType(BoxedType): pass # polymorphic, regions: strictness
class AnyType(TaggedType): pass
class SumType(TaggedType): pass
class ProdType(TaggedType): pass
class ProcType(TaggedType): pass # closure and effect information?

# type variables
# lattice types: top, bottom, unions, intersections
# row types
# refinement types

class Tag: pass

################################################################
# interpreter utilities
from functools import reduce
from itertools import chain
from collections import namedtuple

def alphaGen(alphabet=[chr(o) for o in range(ord('a'), ord('z')+1)]):
    count = 0
    while True:
        countStr = str(count)
        for s in alphabet: yield s+countStr
        count += 1
class UIDGen:
    def __init__(self): self.counter = 0; self.recycled = set()
    def get(self):
        if self.recycled: uid = self.recycled.pop()
        else: uid = self.counter; self.counter += 1
        return uid
    def put(self, uid):
        assert uid < self.counter, (uid, self.counter)
        self.recycled.add(uid); prev = self.counter-1
        while prev in self.recycled: self.recycled.remove(prev); prev -= 1
        self.counter = prev+1
def Label(uidg=UIDGen()): return uidg.get()
_Name = namedtuple('Name', 'str uid')
def Name(str, uidg=UIDGen()): return _Name(str, uidg.get())
_showUID = False
def strName(self):
    global _showUID
    if _showUID: return str((self.str, self.uid))
    return str(self.str)
_Name.__str__ = strName
def strTup(tup): return '(%s)'%' '.join(str(el) for el in tup)
def strDict(dct, joiner=' '):
    return '{%s}'%joiner.join('(%s => %s)'%(key, strSet(val))
                           for key, val in dct.items())
def strSet(st):
    if isinstance(st, set): return '#{%s}'%' '.join(str(el) for el in st)
    return str(st)
def unionReduce(xs): return reduce(set.union, xs, set())
################################################################
# interpreter
class Env:
    def __init__(self, dat=None):
        if dat is None: dat = {}
        self.data = dat
    def __eq__(self, env): return self.data == env.data
    def __hash__(self): return hash(self.data)
    def __str__(self): return strDict(self.data)
    def __repr__(self): return '<Env %s>'%str(self)
    def get(self, key):
        val = self.data.get(key)
        if val is None: return set()
        return val
    def insert(self, kvs):
        dat = self.data.copy()
        dat.update((key, self.get(key)|val) for (key, val) in kvs)
        return Env(dat)
    def contains(self, env):
        return all(self.get(key).issuperset(val)
                   for (key,val) in env.data.items())
    def join(self, env): return self.insert(env.data.items())
    def only(self, keys):
        dat = dict((key, val) for key, val in self.data.items() if key in keys)
        return Env(dat)
class ConcreteTime:
    def __init__(self, count): self.count = count
    def advance(self, code): return ConcreteTime(self.count+1)
    def __eq__(self, tm): return self.count == tm.count
    def __hash__(self): return hash(self.count)
class AbstractTime:
    def __init__(self, codes, mx): self.codes = codes; self.mx = mx
    def __eq__(self, tm): return self.codes == tm.codes
    def __hash__(self): return hash(self.codes)
    def __str__(self): return strTup(self.codes)
    def __repr__(self): return '<m=%d %s>'%(self.mx, str(self))
    def advance(self, code):
        codes = (self.codes+(code,)); codes = codes[max(0,len(codes)-self.mx):]
        return AbstractTime(codes, self.mx)

def namedTup(*args): ntup = namedtuple(*args); ntup.__str__=strTup; return ntup
Closure = namedTup('Closure', 'proc time')
Binding = namedTup('Binding', 'name time')
Context = namedTup('Context', 'code time')
def advance(ctx): return ctx.time.advance(ctx.code)
def touchedClosure(clo):
    return set(Binding(name, clo.time) for name in clo.proc.frees())
def touchedBinding(cfg, bnd):
    return unionReduce(touchedClosure(clo) for clo in cfg.store.get(bnd))
def reachable(cfg, bnds):
    seen = set(bnds)
    while bnds:
        bnds = unionReduce(touchedBinding(cfg, bnd) for bnd in bnds) - seen
        seen |= bnds
    return seen
class Config:
    def __init__(self, store): self.store = store
    def __str__(self): return str(self.store)
    def __repr__(self): return '<Config %s>'%str(self)
    def contains(self, cfg): return self.store.contains(cfg.store)
    def join(self, cfg): return Config(self.store.join(cfg.store))
    def only(self, bnds): return Config(self.store.only(bnds))
class State:
    def __init__(self, ctx, cfg): self.ctx = ctx; self.cfg = cfg
    def next(self): return self.ctx.code.eval(self.ctx.time, self.cfg)
    def reachable(self):
        return reachable(self.cfg, self.ctx.code.touched(self.ctx.time))
    def garbageCollect(self):
        return State(self.ctx, self.cfg.only(self.reachable()))

class Expr:
    def __init__(self): self.lab = Label()
    def __str__(self): raise NotImplementedError
    def __repr__(self): return '<%s %s>'%(self.__class__.__name__, str(self))
    def frees(self): raise NotImplementedError
def accFrees(xs): return unionReduce(x.frees() for x in xs)

class CExpr(Expr):
    def touched(self, tm): return set(Binding(nm, tm) for nm in self.frees())
    def eval(self, tm, cfg): raise NotImplementedError
class Halt(CExpr):
    def __init__(self, resultName='halt-result'):
        super().__init__(); self.result = Name(resultName)
    def __str__(self): return '*HALT!*'
    def frees(self): return set((self.result,))
    def eval(self, tm, cfg): return ()
def makeHalt(): hlt = Halt(); return CProc((hlt.result,), hlt)
class Call(CExpr):
    def __init__(self, proc, params):
        super().__init__(); self.proc = proc; self.params = params
    def __str__(self):
        return '(call %s %s)'%(str(self.proc), strTup(self.params))
    def frees(self): return self.proc.frees()|accFrees(self.params)
    def eval(self, tm, cfg):
        clos = self.proc.eval(tm, cfg)
        paramss = tuple(pm.eval(tm, cfg) for pm in self.params)
        nexts = []
        for (proc, ptm) in clos:
            ntm = proc.advance(Context(self, tm), ptm)
            nexts.append(applyProc(proc, paramss, ptm, ntm, cfg))
        return nexts
def applyProc(proc, paramss, ptm, ntm, cfg):
    bvs = zip((Binding(bv, ntm) for bv in proc.binders), paramss)
    fvs = ((Binding(fv, ntm), cfg.store.get(Binding(fv, ptm)))
           for fv in proc.frees())
    ncfg = Config(cfg.store.insert(chain(bvs, fvs)))
    return State(Context(proc.code, ntm), ncfg)

class VExpr(Expr):
    def eval(self, tm, cfg): raise NotImplementedError
class Var(VExpr):
    def __init__(self, name): super().__init__(); self.name = name
    def __str__(self): return str(self.name)
    def frees(self): return {self.name}
    def eval(self, tm, cfg): return cfg.store.get(Binding(self.name, tm))
class Proc(VExpr):
    def __init__(self, binders, code):
        super().__init__(); self.binders = binders; self.code = code
    def __str__(self):
        return '(%s %s %s)'%(self.strTag, strTup(self.binders), str(self.code))
    def frees(self): return self.code.frees()-set(self.binders)
    def eval(self, tm, cfg): return {Closure(self, tm)}
class UProc(Proc):
    strTag = 'uproc'
    def advance(self, ctx, tm): return advance(ctx)
class CProc(Proc):
    strTag = 'cproc'
    def advance(self, ctx, tm): return tm
def progState(proc, params, tm):
    cfg = Config(Env())
    return applyProc(proc, params+(makeHalt().eval(tm, cfg),), tm, tm, cfg)

def freshCVar(alpha=alphaGen(['k'])): return Var(Name(next(alpha)))
def freshUVar(alpha=alphaGen(['u'])): return Var(Name(next(alpha)))
class DExpr(Expr):
    def toCPS(self, ce): raise NotImplementedError
class DVar(DExpr):
    def __init__(self, name): super().__init__(); self.name = name
    def __str__(self): return str(self.name)
    def toCPS(self, ce): return Call(ce, (Var(self.name),))
class DProc(DExpr):
    def __init__(self, binders, body):
        super().__init__(); self.binders = binders; self.body = body
    def __str__(self):
        return '(dproc %s %s)'%(strTup(self.binders), str(self.body))
    def toCPS(self, ce):
        cv = freshCVar()
        return Call(ce, (UProc(self.binders+(cv.name,), self.body.toCPS(cv)),))
class DApply(DExpr):
    def __init__(self, proc, params):
        super().__init__(); self.proc = proc; self.params = params
    def __str__(self): return '(%s %s)'%(str(self.proc), strTup(self.params))
    def toCPS(self, ce):
        uvp = freshUVar(); uvs = tuple(freshUVar() for _ in self.params)
        call = Call(uvp, uvs+(ce,))
        for uv, param in reversed(tuple(zip(uvs, self.params))):
            call = param.toCPS(CProc((uv.name,), call))
        return self.proc.toCPS(CProc((uvp.name,), call))
def dLetStar(bnds, body):
    for (binder, de) in reversed(bnds):
        body = DApply(DProc((binder,), body), (de,))
    return body
def dProg(dexpr):
    haltBnd = Name('halt'); return UProc((haltBnd,), dexpr.toCPS(Var(haltBnd)))

def garbageCollect(state): return state.garbageCollect()
def search(seen, unseen):
    while unseen:
        state = garbageCollect(unseen.pop()); cfg = seen.get(state.ctx)
        if cfg is not None:
            if cfg.contains(state.cfg): continue
            cfg = cfg.join(state.cfg)
            state = garbageCollect(State(state.ctx, cfg)) # context widening
        else: cfg = state.cfg
        seen[state.ctx] = cfg; unseen.extend(state.next())
    return seen
def searchProg(proc, mx=0):
    return search({}, [progState(proc, (), AbstractTime((), mx))])
def summary(seen): return reduce(Config.join, seen.values(), Config(Env()))
################################################################
# testing
#  (let* ((id (lambda (x) x))
#         (a (id (lambda (z) z)))
#         (b (id (lambda (y) y))))
#   b))
dvID, dvA, dvB, dvX, dvY, dvZ = [DVar(Name(nm)) for nm in
                                 ('id', 'a', 'b', 'x', 'y', 'z')]
testProg = dProg(dLetStar([(dvID.name, DProc((dvX.name,), dvX)),
                           (dvA.name,
                            DApply(dvID, (DProc((dvZ.name,), dvZ),))),
                           (dvB.name,
                            DApply(dvID, (DProc((dvY.name,), dvY),)))],
                          dvB))
test = searchProg(testProg, 1)
testSum = summary(test)
print(strDict(testSum.store.data, '\n'))
<commit_msg>added abstract counting<commit_after># Copyright 2010 Gregory L. Rosenblatt

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

################################################################
# types
class Type:
    def contains(self, ty, tenv=None): return self is ty
    def __repr__(self): return '<%s %s>'%(self.__class__.__name__, self)

class BasicType(Type): pass

class ScalarType(BasicType): pass
#class PyType(ScalarType): pass

class AggregateType(BasicType): pass # future: alignment
class StructType(AggregateType): pass # heterogeneous els
class ArrayType(AggregateType): pass # homogeneous els

# combine removal/addition in an update operation:
# tables/records: ({?a}//{?b})|{?c} # can also use struct-like repacking?
# arrays: reslice arr [(old-range new-subarr) (old-range new-subarr) ...]
# structs (no resizing): repack struct [(0 ?v) (2 ?v) ...]

class BoxedType(Type): pass # regions: mutability
class RefType(BoxedType): pass # strict, non-polymorphic, no ptr-arithmetic
#class DynArrayType(RefType): pass
#class DynArrayRefType(RefType): pass # ptr-like refs w/arithmetic to DA data
#class WeakRefType(RefType): pass # stores boxed element in unmanaged memory
#class ResourceType(RefType): pass # finalizable

# more general record type to support row-typing?
class TableType(BoxedType): pass # scalar/hashable keys; homogeneous els

class TaggedType(BoxedType): pass # polymorphic, regions: strictness
class AnyType(TaggedType): pass
class SumType(TaggedType): pass
class ProdType(TaggedType): pass
class ProcType(TaggedType): pass # closure and effect information?

# type variables
# lattice types: top, bottom, unions, intersections
# row types
# refinement types

class Tag: pass

################################################################
# interpreter utilities
from functools import reduce
from itertools import chain
from collections import namedtuple

def alphaGen(alphabet=[chr(o) for o in range(ord('a'), ord('z')+1)]):
    count = 0
    while True:
        countStr = str(count)
        for s in alphabet: yield s+countStr
        count += 1
class UIDGen:
    def __init__(self): self.counter = 0; self.recycled = set()
    def get(self):
        if self.recycled: uid = self.recycled.pop()
        else: uid = self.counter; self.counter += 1
        return uid
    def put(self, uid):
        assert uid < self.counter, (uid, self.counter)
        self.recycled.add(uid); prev = self.counter-1
        while prev in self.recycled: self.recycled.remove(prev); prev -= 1
        self.counter = prev+1
def Label(uidg=UIDGen()): return uidg.get()
_Name = namedtuple('Name', 'str uid')
def Name(str, uidg=UIDGen()): return _Name(str, uidg.get())
_showUID = False
def strName(self):
    global _showUID
    if _showUID: return str((self.str, self.uid))
    return str(self.str)
_Name.__str__ = strName
def strTup(tup): return '(%s)'%' '.join(str(el) for el in tup)
def strDict(dct, joiner=' '):
    return '{%s}'%joiner.join('(%s => %s)'%(key, strSet(val))
                           for key, val in dct.items())
def strSet(st):
    if isinstance(st, set): return '#{%s}'%' '.join(str(el) for el in st)
    return str(st)
def unionReduce(xs): return reduce(set.union, xs, set())
################################################################
# interpreter
class Mapping:
    def __init__(self, dat=None):
        if dat is None: dat = {}
        self.data = dat
    def __str__(self): return strDict(self.data)
    def __repr__(self): return '<%s %s>'%(self.__class__.__name__, str(self))
    def _getDefault(self): return None
    def _combineVal(self, key, val): return val
    def get(self, key):
        val = self.data.get(key)
        if val is None: return self._getDefault()
        return val
    def insert(self, kvs):
        dat = self.data.copy()
        dat.update((key, self._combineVal(key, val)) for key, val in kvs)
        return self.__class__(dat)
    def join(self, other): return self.insert(other.data.items())
    def only(self, keys):
        dat = dict((key, val) for key, val in self.data.items() if key in keys)
        return self.__class__(dat)
class Env(Mapping):
    def _getDefault(self): return set()
    def _combineVal(self, key, val): return self.get(key)|val
    def contains(self, env):
        return all(self.get(key).issuperset(val)
                   for (key,val) in env.data.items())
class ConcreteTime:
    def __init__(self, count): self.count = count
    def advance(self, code): return ConcreteTime(self.count+1)
    def __eq__(self, tm): return self.count == tm.count
    def __hash__(self): return hash(self.count)
class AbstractTime:
    def __init__(self, codes, mx): self.codes = codes; self.mx = mx
    def __eq__(self, tm): return self.codes == tm.codes
    def __hash__(self): return hash(self.codes)
    def __str__(self): return strTup(self.codes)
    def __repr__(self): return '<m=%d %s>'%(self.mx, str(self))
    def advance(self, code):
        codes = (self.codes+(code,)); codes = codes[max(0,len(codes)-self.mx):]
        return AbstractTime(codes, self.mx)

def namedTup(*args): ntup = namedtuple(*args); ntup.__str__=strTup; return ntup
Closure = namedTup('Closure', 'proc time')
Binding = namedTup('Binding', 'name time')
Context = namedTup('Context', 'code time')
def advance(ctx): return ctx.time.advance(ctx.code)
def touchedClosure(clo):
    return set(Binding(name, clo.time) for name in clo.proc.frees())
def touchedBinding(cfg, bnd):
    return unionReduce(touchedClosure(clo) for clo in cfg.store.get(bnd))
def reachable(cfg, bnds):
    seen = set(bnds)
    while bnds:
        bnds = unionReduce(touchedBinding(cfg, bnd) for bnd in bnds) - seen
        seen |= bnds
    return seen
class Config:
    def __init__(self, store, count): self.store = store; self.count = count
    def __str__(self): return '(%s %s)'%str(self.store), str(self.count)
    def __repr__(self): return '<Config %s>'%str(self)
    def contains(self, cfg): return self.store.contains(cfg.store)
    def join(self, cfg):
        return Config(self.store.join(cfg.store), self.addCounts(cfg))
    def only(self, bnds):
        return Config(self.store.only(bnds), self.count.only(bnds))
    def addCounts(self, cfg):
        newCounts = []
        for bnd, cnt in self.count.data.items():
            if cnt == 1:
                val = cfg.store.get(bnd)
                if val:
                    val0 = self.store.get(bnd)
                    if val != val0: cnt+=1; print(val, '!=', val0)
                    else: cnt = cfg.count.get(bnd)
            newCounts.append((bnd, cnt))
        return cfg.count.insert(newCounts)
def newConfig(vals=None, counts=None):
    return Config(Env(vals), Mapping(counts))
class State:
    def __init__(self, ctx, cfg): self.ctx = ctx; self.cfg = cfg
    def next(self): return self.ctx.code.eval(self.ctx.time, self.cfg)
    def reachable(self):
        return reachable(self.cfg, self.ctx.code.touched(self.ctx.time))
    def garbageCollect(self):
        return State(self.ctx, self.cfg.only(self.reachable()))

class Expr:
    def __init__(self): self.lab = Label()
    def __eq__(self, expr): return self.lab == expr.lab
    def __hash__(self): return hash(self.lab)
    def __str__(self): raise NotImplementedError
    def __repr__(self): return '<%s %s>'%(self.__class__.__name__, str(self))
    def frees(self): raise NotImplementedError
def accFrees(xs): return unionReduce(x.frees() for x in xs)

class CExpr(Expr):
    def touched(self, tm): return set(Binding(nm, tm) for nm in self.frees())
    def eval(self, tm, cfg): raise NotImplementedError
class Halt(CExpr):
    def __init__(self, resultName='halt-result'):
        super().__init__(); self.result = Name(resultName)
    def __str__(self): return '*HALT!*'
    def frees(self): return set((self.result,))
    def eval(self, tm, cfg): return ()
def makeHalt(): hlt = Halt(); return CProc((hlt.result,), hlt)
class Call(CExpr):
    def __init__(self, proc, params):
        super().__init__(); self.proc = proc; self.params = params
    def __str__(self):
        return '(call %s %s)'%(str(self.proc), strTup(self.params))
    def frees(self): return self.proc.frees()|accFrees(self.params)
    def eval(self, tm, cfg):
        clos = self.proc.eval(tm, cfg)
        paramss = tuple(pm.eval(tm, cfg) for pm in self.params)
        nexts = []
        for (proc, ptm) in clos:
            ntm = proc.advance(Context(self, tm), ptm)
            nexts.append(applyProc(proc, paramss, ptm, ntm, cfg))
        return nexts
def applyProc(proc, paramss, ptm, ntm, cfg):
    bvs = zip((Binding(bv, ntm) for bv in proc.binders), paramss)
    fvs = ((Binding(fv, ntm), cfg.store.get(Binding(fv, ptm)))
           for fv in proc.frees())
    bindings = tuple(chain(bvs, fvs))
    ncfg = newConfig(dict(bindings), dict((bnd, 1) for bnd, _ in bindings))
    return State(Context(proc.code, ntm), ncfg.join(cfg))

class VExpr(Expr):
    def eval(self, tm, cfg): raise NotImplementedError
class Var(VExpr):
    def __init__(self, name): super().__init__(); self.name = name
    def __str__(self): return str(self.name)
    def frees(self): return {self.name}
    def eval(self, tm, cfg): return cfg.store.get(Binding(self.name, tm))
class Proc(VExpr):
    def __init__(self, binders, code):
        super().__init__(); self.binders = binders; self.code = code
    def __str__(self):
        return '(%s %s %s)'%(self.strTag, strTup(self.binders), str(self.code))
    def frees(self): return self.code.frees()-set(self.binders)
    def eval(self, tm, cfg): return {Closure(self, tm)}
class UProc(Proc):
    strTag = 'uproc'
    def advance(self, ctx, tm): return advance(ctx)
class CProc(Proc):
    strTag = 'cproc'
    def advance(self, ctx, tm): return tm
def progState(proc, params, tm):
    cfg = newConfig()
    return applyProc(proc, params+(makeHalt().eval(tm, cfg),), tm, tm, cfg)

def freshCVar(alpha=alphaGen(['k'])): return Var(Name(next(alpha)))
def freshUVar(alpha=alphaGen(['u'])): return Var(Name(next(alpha)))
class DExpr(Expr):
    def toCPS(self, ce): raise NotImplementedError
class DVar(DExpr):
    def __init__(self, name): super().__init__(); self.name = name
    def __str__(self): return str(self.name)
    def toCPS(self, ce): return Call(ce, (Var(self.name),))
class DProc(DExpr):
    def __init__(self, binders, body):
        super().__init__(); self.binders = binders; self.body = body
    def __str__(self):
        return '(dproc %s %s)'%(strTup(self.binders), str(self.body))
    def toCPS(self, ce):
        cv = freshCVar()
        return Call(ce, (UProc(self.binders+(cv.name,), self.body.toCPS(cv)),))
class DApply(DExpr):
    def __init__(self, proc, params):
        super().__init__(); self.proc = proc; self.params = params
    def __str__(self): return '(%s %s)'%(str(self.proc), strTup(self.params))
    def toCPS(self, ce):
        uvp = freshUVar(); uvs = tuple(freshUVar() for _ in self.params)
        call = Call(uvp, uvs+(ce,))
        for uv, param in reversed(tuple(zip(uvs, self.params))):
            call = param.toCPS(CProc((uv.name,), call))
        return self.proc.toCPS(CProc((uvp.name,), call))
def dLetStar(bnds, body):
    for (binder, de) in reversed(bnds):
        body = DApply(DProc((binder,), body), (de,))
    return body
def dProg(dexpr):
    haltBnd = Name('halt'); return UProc((haltBnd,), dexpr.toCPS(Var(haltBnd)))

def garbageCollect(state): return state.garbageCollect()
def search(seen, unseen):
    while unseen:
        state = garbageCollect(unseen.pop()); cfg = seen.get(state.ctx)
        if cfg is not None:
            if cfg.contains(state.cfg): continue
            cfg = cfg.join(state.cfg)
            state = garbageCollect(State(state.ctx, cfg)) # context widening
        else: cfg = state.cfg
        seen[state.ctx] = cfg; unseen.extend(state.next())
    return seen
def searchProg(proc, mx=0):
    return search({}, [progState(proc, (), AbstractTime((), mx))])
def summary(seen): return reduce(Config.join, seen.values(), newConfig())
################################################################
# testing
#  (let* ((id (lambda (x) x))
#         (a (id (lambda (z) z)))
#         (b (id (lambda (y) y))))
#   b))
dvID, dvA, dvB, dvX, dvY, dvZ = [DVar(Name(nm)) for nm in
                                 ('id', 'a', 'b', 'x', 'y', 'z')]
testProg = dProg(dLetStar([(dvID.name, DProc((dvX.name,), dvX)),
                           (dvA.name,
                            DApply(dvID, (DProc((dvZ.name,), dvZ),))),
                           (dvB.name,
                            DApply(dvID, (DProc((dvY.name,), dvY),)))],
                          dvB))
test = searchProg(testProg, 1)
testSum = summary(test)
divider = '================================================================'
def printDivd(msg): print(divider+'\n= '+msg+'\n'+divider)
printDivd('store summary')
print(strDict(testSum.store.data, '\n'))
printDivd('count summary')
print(strDict(testSum.count.data, '\n'))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import datetime
import os
from random import randint
import sys

from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import requests

TOKEN = os.environ.get('TOKEN', None)
# SLACK_WEBHOOK_URL = 'https://hooks.slack.com/' + os.environ.get('SLACK_WEBHOOK_PATH')

COFFEE_GIFS = [
  'oZEBLugoTthxS',
  'DrJm6F9poo4aA',
  'GhNCif5GnFBYY',
  '687qS11pXwjCM',
  'zJ8ldRaGLnHTa',
  '3oFyDpRagf96Uz9rzO',
  '5Ztn33chuvutW'
]

app = Flask(__name__, static_folder='static/dist', template_folder='static')

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'postgresql://localhost/groselha_dev')
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    kind = db.Column(db.String(10), nullable=False)
    mac_address = db.Column(db.String(20), nullable=False, unique=True)
    last_online_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)

    def __init__(self, first_name, last_name, kind, mac_address, last_online_at):
        self.first_name = first_name
        self.last_name = last_name
        self.kind = kind
        self.mac_address = mac_address
        self.last_online_at = last_online_at

    def __repr__(self):
        return '<User %r %r >' % (self.first_name, self.last_name)

    @classmethod
    def online_users(cls):
        query = User.last_online_at > datetime.datetime.utcnow() - datetime.timedelta(minutes=2)
        users = cls \
           .query \
           .with_entities(User.first_name, User.last_name) \
           .distinct(User.first_name, User.last_name) \
           .filter(query) \
           .all()

        return(users)

@app.route('/register-macs', methods=['GET', 'POST'])
def register_macs():
    if request.method == 'GET':
        return render_template('index.html')
    elif request.method == 'POST':
        args = request.get_json()
        new_user = User(
            first_name=args['firstName'],
            last_name=args['lastName'],
            mac_address=args['macAddress'],
            kind=args['kind'],
            last_online_at=datetime.datetime.utcnow()
        )
        db.session.add(new_user)
        db.session.commit()

        return('ok', 200)

@app.route('/macs', methods=['POST'])
def save_macs():
    if request.get_json()['token'] != TOKEN: return('', 401)

    macs = request.get_json()['macs']
    users = User.query.filter(User.mac_address.in_(macs)).all()

    for user in users:
        user.last_online_at = datetime.datetime.utcnow()
        db.session.add(user)
    db.session.commit()

    return('', 200)

@app.route('/who', methods=['GET'])
def who_is_in_the_room():
    if request.args.get('token') != TOKEN: return('', 401)

    online_users = User.online_users()

    if len(online_users) == 0:
        return('Não há ninguém no laboratório :(')
    elif len(online_users) == 1:
        name = online_users[0].first_name + ' ' + online_users[0].last_name
        return("Só o " + name + " está no laboratório. Tadinho :(")
    else:
        names = "\n".join([user.first_name + ' ' + user.last_name for user in online_users])
        return("Há " + str(len(online_users)) + " pessoas no laboratório:\n\n" + names)

@app.route('/coffee_gifs', methods=['GET'])
def get_coffee_gifs():
    if request.get_json()['token'] != TOKEN: return('', 401)

    gif_id = randint(0,6)

    gif_url = 'https://media.giphy.com/media/' + COFFEE_GIFS[gif_id] + '/giphy.gif'
    gif_data = {'image_url': gif_url}

    r = requests.post(SLACK_WEBHOOK_URL,
                      json={"text": "<!here> Café quentinho na cafeteira!",
                            "link_names": 1,
                            "attachments": [gif_data]})
    return('', 200)

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 5000))
    app.run(host='0.0.0.0', port=port)
<commit_msg>Uncomment line<commit_after># -*- coding: utf-8 -*-
import datetime
import os
from random import randint
import sys

from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import requests

TOKEN = os.environ.get('TOKEN', None)
SLACK_WEBHOOK_URL = 'https://hooks.slack.com/' + os.environ.get('SLACK_WEBHOOK_PATH')

COFFEE_GIFS = [
  'oZEBLugoTthxS',
  'DrJm6F9poo4aA',
  'GhNCif5GnFBYY',
  '687qS11pXwjCM',
  'zJ8ldRaGLnHTa',
  '3oFyDpRagf96Uz9rzO',
  '5Ztn33chuvutW'
]

app = Flask(__name__, static_folder='static/dist', template_folder='static')

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'postgresql://localhost/groselha_dev')
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    kind = db.Column(db.String(10), nullable=False)
    mac_address = db.Column(db.String(20), nullable=False, unique=True)
    last_online_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)

    def __init__(self, first_name, last_name, kind, mac_address, last_online_at):
        self.first_name = first_name
        self.last_name = last_name
        self.kind = kind
        self.mac_address = mac_address
        self.last_online_at = last_online_at

    def __repr__(self):
        return '<User %r %r >' % (self.first_name, self.last_name)

    @classmethod
    def online_users(cls):
        query = User.last_online_at > datetime.datetime.utcnow() - datetime.timedelta(minutes=2)
        users = cls \
           .query \
           .with_entities(User.first_name, User.last_name) \
           .distinct(User.first_name, User.last_name) \
           .filter(query) \
           .all()

        return(users)

@app.route('/register-macs', methods=['GET', 'POST'])
def register_macs():
    if request.method == 'GET':
        return render_template('index.html')
    elif request.method == 'POST':
        args = request.get_json()
        new_user = User(
            first_name=args['firstName'],
            last_name=args['lastName'],
            mac_address=args['macAddress'],
            kind=args['kind'],
            last_online_at=datetime.datetime.utcnow()
        )
        db.session.add(new_user)
        db.session.commit()

        return('ok', 200)

@app.route('/macs', methods=['POST'])
def save_macs():
    if request.get_json()['token'] != TOKEN: return('', 401)

    macs = request.get_json()['macs']
    users = User.query.filter(User.mac_address.in_(macs)).all()

    for user in users:
        user.last_online_at = datetime.datetime.utcnow()
        db.session.add(user)
    db.session.commit()

    return('', 200)

@app.route('/who', methods=['GET'])
def who_is_in_the_room():
    if request.args.get('token') != TOKEN: return('', 401)

    online_users = User.online_users()

    if len(online_users) == 0:
        return('Não há ninguém no laboratório :(')
    elif len(online_users) == 1:
        name = online_users[0].first_name + ' ' + online_users[0].last_name
        return("Só o " + name + " está no laboratório. Tadinho :(")
    else:
        names = "\n".join([user.first_name + ' ' + user.last_name for user in online_users])
        return("Há " + str(len(online_users)) + " pessoas no laboratório:\n\n" + names)

@app.route('/coffee_gifs', methods=['GET'])
def get_coffee_gifs():
    if request.get_json()['token'] != TOKEN: return('', 401)

    gif_id = randint(0,6)

    gif_url = 'https://media.giphy.com/media/' + COFFEE_GIFS[gif_id] + '/giphy.gif'
    gif_data = {'image_url': gif_url}

    r = requests.post(SLACK_WEBHOOK_URL,
                      json={"text": "<!here> Café quentinho na cafeteira!",
                            "link_names": 1,
                            "attachments": [gif_data]})
    return('', 200)

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 5000))
    app.run(host='0.0.0.0', port=port)
<|endoftext|>


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

# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for
# full license information.

import random
import time
import sys
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue
import config as config
from BME280SensorSimulator import BME280SensorSimulator
import RPi.GPIO as GPIO
#from Adafruit_BME280 import *
import re
from telemetry import Telemetry
from readDataClass import ReadData

# HTTP options
# Because it can poll "after 9 seconds" polls will happen effectively
# at ~10 seconds.
# Note that for scalabilty, the default value of minimumPollingTime
# is 25 minutes. For more information, see:
# https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
TIMEOUT = 241000
MINIMUM_POLLING_TIME = 9

# messageTimeout - the maximum time in milliseconds until a message times out.
# The timeout period starts at IoTHubClient.send_event_async.
# By default, messages do not expire.
MESSAGE_TIMEOUT = 10000

RECEIVE_CONTEXT = 0
MESSAGE_COUNT = 0
MESSAGE_SWITCH = True
TWIN_CONTEXT = 0
SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0
TEMPERATURE_ALERT = 30.0

# global counters
RECEIVE_CALLBACKS = 0
SEND_CALLBACKS = 0
BLOB_CALLBACKS = 0
TWIN_CALLBACKS = 0
SEND_REPORTED_STATE_CALLBACKS = 0
METHOD_CALLBACKS = 0
EVENT_SUCCESS = "success"
EVENT_FAILED = "failed"

# chose HTTP, AMQP or MQTT as transport protocol
PROTOCOL = IoTHubTransportProvider.MQTT

# String containing Hostname, Device Id & Device Key in the format:
# "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
telemetry = Telemetry()

#if len(sys.argv) < 2:
#    print ( "You need to provide the device connection string as command line arguments." )
#    telemetry.send_telemetry_data(None, EVENT_FAILED, "Device connection string is not provided")
#    sys.exit(0)

def is_correct_connection_string():
    m = re.search("HostName=.*;DeviceId=.*;", CONNECTION_STRING)
    if m:
        return True
    else:
        return False

CONNECTION_STRING = config.CONNECTION_STRING #sys.argv[1]

if not is_correct_connection_string():
    print ( "Device connection string is not correct." )
    telemetry.send_telemetry_data(None, EVENT_FAILED, "Device connection string is not correct.")
    sys.exit(0)

MSG_TXT = "{\"deviceId\": \"raspPI\",\"dining temperature\": %f,\"bathroom temperature\": %f}"

GPIO.setmode(GPIO.BCM)
GPIO.setup(config.GPIO_PIN_ADDRESS, GPIO.OUT)

def receive_message_callback(message, counter):
    global RECEIVE_CALLBACKS
    message_buffer = message.get_bytearray()
    size = len(message_buffer)
    print ( "Received Message [%d]:" % counter )
    print ( "    Data: <<<%s>>> & Size=%d" % (message_buffer[:size].decode("utf-8"), size) )
    map_properties = message.properties()
    key_value_pair = map_properties.get_internals()
    print ( "    Properties: %s" % key_value_pair )
    counter += 1
    RECEIVE_CALLBACKS += 1
    print ( "    Total calls received: %d" % RECEIVE_CALLBACKS )
    return IoTHubMessageDispositionResult.ACCEPTED

def send_confirmation_callback(message, result, user_context):
    global SEND_CALLBACKS
    print ( "Confirmation[%d] received for message with result = %s" % (user_context, result) )
    map_properties = message.properties()
    print ( "    message_id: %s" % message.message_id )
    print ( "    correlation_id: %s" % message.correlation_id )
    key_value_pair = map_properties.get_internals()
    print ( "    Properties: %s" % key_value_pair )
    SEND_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_CALLBACKS )
    led_blink()

def device_twin_callback(update_state, payload, user_context):
    global TWIN_CALLBACKS
    print ( "\nTwin callback called with:\nupdateStatus = %s\npayload = %s\ncontext = %s" % (update_state, payload, user_context) )
    TWIN_CALLBACKS += 1
    print ( "Total calls confirmed: %d\n" % TWIN_CALLBACKS )

def send_reported_state_callback(status_code, user_context):
    global SEND_REPORTED_STATE_CALLBACKS
    print ( "Confirmation for reported state received with:\nstatus_code = [%d]\ncontext = %s" % (status_code, user_context) )
    SEND_REPORTED_STATE_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_REPORTED_STATE_CALLBACKS )

def device_method_callback(method_name, payload, user_context):
    global METHOD_CALLBACKS,MESSAGE_SWITCH
    print ( "\nMethod callback called with:\nmethodName = %s\npayload = %s\ncontext = %s" % (method_name, payload, user_context) )
    METHOD_CALLBACKS += 1
    print ( "Total calls confirmed: %d\n" % METHOD_CALLBACKS )
    device_method_return_value = DeviceMethodReturnValue()
    device_method_return_value.response = "{ \"Response\": \"This is the response from the device\" }"
    device_method_return_value.status = 200
    if method_name == "start":
        MESSAGE_SWITCH = True
        print ( "Start sending message\n" )
        device_method_return_value.response = "{ \"Response\": \"Successfully started\" }"
        return device_method_return_value
    if method_name == "stop":
        MESSAGE_SWITCH = False
        print ( "Stop sending message\n" )
        device_method_return_value.response = "{ \"Response\": \"Successfully stopped\" }"
        return device_method_return_value
    return device_method_return_value

def blob_upload_conf_callback(result, user_context):
    global BLOB_CALLBACKS
    print ( "Blob upload confirmation[%d] received for message with result = %s" % (user_context, result) )
    BLOB_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % BLOB_CALLBACKS )

def iothub_client_init():
    # prepare iothub client
    client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
    if client.protocol == IoTHubTransportProvider.HTTP:
        client.set_option("timeout", TIMEOUT)
        client.set_option("MinimumPollingTime", MINIMUM_POLLING_TIME)
    # set the time until a message times out
    client.set_option("messageTimeout", MESSAGE_TIMEOUT)
    # to enable MQTT logging set to 1
    if client.protocol == IoTHubTransportProvider.MQTT:
        client.set_option("logtrace", 0)
    client.set_message_callback(
        receive_message_callback, RECEIVE_CONTEXT)
    if client.protocol == IoTHubTransportProvider.MQTT or client.protocol == IoTHubTransportProvider.MQTT_WS:
        client.set_device_twin_callback(
            device_twin_callback, TWIN_CONTEXT)
        client.set_device_method_callback(
            device_method_callback, METHOD_CONTEXT)
    return client

def print_last_message_time(client):
    try:
        last_message = client.get_last_message_receive_time()
        print ( "Last Message: %s" % time.asctime(time.localtime(last_message)) )
        print ( "Actual time : %s" % time.asctime() )
    except IoTHubClientError as iothub_client_error:
        if iothub_client_error.args[0].result == IoTHubClientResult.INDEFINITE_TIME:
            print ( "No message received" )
        else:
            print ( iothub_client_error )

def iothub_client_sample_run():
    try:
        client = iothub_client_init()

        if client.protocol == IoTHubTransportProvider.MQTT:
            print ( "IoTHubClient is reporting state" )
            reported_state = "{\"newState\":\"standBy\",\"relaysState\":{\"dining\":\"off\"}}"
            client.send_reported_state(reported_state, len(reported_state), send_reported_state_callback, SEND_REPORTED_STATE_CONTEXT)

        sensor = ReadData()

        #telemetry.send_telemetry_data(parse_iot_hub_name(), EVENT_SUCCESS, "IoT hub connection is established")
        while True:
            global MESSAGE_COUNT,MESSAGE_SWITCH
            if MESSAGE_SWITCH:
                # send a few messages every minute
                print ( "IoTHubClient sending %d messages" % MESSAGE_COUNT )
                #temperature = sensor.read_temperature()
                #humidity = sensor.read_humidity()
                sensor.updVal()
                sensor.logValues()
                msg_txt_formatted = MSG_TXT % (
                    sensor.diningTemp,
                    sensor.bathTemp)
                print (msg_txt_formatted)
                message = IoTHubMessage(msg_txt_formatted)
                # optional: assign ids
                message.message_id = "message_%d" % MESSAGE_COUNT
                message.correlation_id = "correlation_%d" % MESSAGE_COUNT
                # optional: assign properties
                prop_map = message.properties()
                prop_map.add("temperatureAlert", "true" if sensor.diningTemp > TEMPERATURE_ALERT else "false")

                client.send_event_async(message, send_confirmation_callback, MESSAGE_COUNT)
                print ( "IoTHubClient.send_event_async accepted message [%d] for transmission to IoT Hub." % MESSAGE_COUNT )

                status = client.get_send_status()
                print ( "Send status: %s" % status )
                MESSAGE_COUNT += 1
            time.sleep(config.MESSAGE_TIMESPAN / 1000.0)

    except IoTHubError as iothub_error:
        print ( "Unexpected error %s from IoTHub" % iothub_error )
        telemetry.send_telemetry_data(parse_iot_hub_name(), EVENT_FAILED, "Unexpected error %s from IoTHub" % iothub_error)
        return
    except KeyboardInterrupt:
        print ( "IoTHubClient sample stopped" )

    print_last_message_time(client)

def led_blink():
    GPIO.output(config.GPIO_PIN_ADDRESS, GPIO.HIGH)
    time.sleep(config.BLINK_TIMESPAN / 1000.0)
    GPIO.output(config.GPIO_PIN_ADDRESS, GPIO.LOW)

def usage():
    print ( "Usage: iothub_client_sample.py -p <protocol> -c <connectionstring>" )
    print ( "    protocol        : <amqp, amqp_ws, http, mqtt, mqtt_ws>" )
    print ( "    connectionstring: <HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>>" )

def parse_iot_hub_name():
    m = re.search("HostName=(.*?)\.", CONNECTION_STRING)
    return m.group(1)

if __name__ == "__main__":
    print ( "\nPython %s" % sys.version )
    print ( "IoT Hub Client for Python" )

    iothub_client_sample_run()
<commit_msg>json test<commit_after>#!/usr/bin/env python

# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for
# full license information.

import random
import time
import sys
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue
import config as config
from BME280SensorSimulator import BME280SensorSimulator
import RPi.GPIO as GPIO
#from Adafruit_BME280 import *
import re
from telemetry import Telemetry
from readDataClass import ReadData
import json

# HTTP options
# Because it can poll "after 9 seconds" polls will happen effectively
# at ~10 seconds.
# Note that for scalabilty, the default value of minimumPollingTime
# is 25 minutes. For more information, see:
# https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
TIMEOUT = 241000
MINIMUM_POLLING_TIME = 9

# messageTimeout - the maximum time in milliseconds until a message times out.
# The timeout period starts at IoTHubClient.send_event_async.
# By default, messages do not expire.
MESSAGE_TIMEOUT = 10000

RECEIVE_CONTEXT = 0
MESSAGE_COUNT = 0
MESSAGE_SWITCH = True
TWIN_CONTEXT = 0
SEND_REPORTED_STATE_CONTEXT = 0
METHOD_CONTEXT = 0
TEMPERATURE_ALERT = 30.0

# global counters
RECEIVE_CALLBACKS = 0
SEND_CALLBACKS = 0
BLOB_CALLBACKS = 0
TWIN_CALLBACKS = 0
SEND_REPORTED_STATE_CALLBACKS = 0
METHOD_CALLBACKS = 0
EVENT_SUCCESS = "success"
EVENT_FAILED = "failed"

# chose HTTP, AMQP or MQTT as transport protocol
PROTOCOL = IoTHubTransportProvider.MQTT

# String containing Hostname, Device Id & Device Key in the format:
# "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
telemetry = Telemetry()

#if len(sys.argv) < 2:
#    print ( "You need to provide the device connection string as command line arguments." )
#    telemetry.send_telemetry_data(None, EVENT_FAILED, "Device connection string is not provided")
#    sys.exit(0)

def is_correct_connection_string():
    m = re.search("HostName=.*;DeviceId=.*;", CONNECTION_STRING)
    if m:
        return True
    else:
        return False

CONNECTION_STRING = config.CONNECTION_STRING #sys.argv[1]

if not is_correct_connection_string():
    print ( "Device connection string is not correct." )
    telemetry.send_telemetry_data(None, EVENT_FAILED, "Device connection string is not correct.")
    sys.exit(0)

MSG_TXT = "{\"deviceId\": \"raspPI\",\"dining temperature\": %f,\"bathroom temperature\": %f}"

GPIO.setmode(GPIO.BCM)
GPIO.setup(config.GPIO_PIN_ADDRESS, GPIO.OUT)

def receive_message_callback(message, counter):
    global RECEIVE_CALLBACKS
    message_buffer = message.get_bytearray()
    size = len(message_buffer)
    print ( "Received Message [%d]:" % counter )
    print ( "    Data: <<<%s>>> & Size=%d" % (message_buffer[:size].decode("utf-8"), size) )
    map_properties = message.properties()
    key_value_pair = map_properties.get_internals()
    print ( "    Properties: %s" % key_value_pair )
    counter += 1
    RECEIVE_CALLBACKS += 1
    print ( "    Total calls received: %d" % RECEIVE_CALLBACKS )
    return IoTHubMessageDispositionResult.ACCEPTED

def send_confirmation_callback(message, result, user_context):
    global SEND_CALLBACKS
    print ( "Confirmation[%d] received for message with result = %s" % (user_context, result) )
    map_properties = message.properties()
    print ( "    message_id: %s" % message.message_id )
    print ( "    correlation_id: %s" % message.correlation_id )
    key_value_pair = map_properties.get_internals()
    print ( "    Properties: %s" % key_value_pair )
    SEND_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_CALLBACKS )
    led_blink()

def device_twin_callback(update_state, payload, user_context):
    global TWIN_CALLBACKS
    print ( "\nTwin callback called with:\nupdateStatus = %s\npayload = %s\ncontext = %s" % (update_state, payload, user_context) )
    TWIN_CALLBACKS += 1
    twin = json.loads(payload)
    print("Property parsed from device twin " + twin['autoControl'])
    print ( "Total calls confirmed: %d\n" % TWIN_CALLBACKS )

def send_reported_state_callback(status_code, user_context):
    global SEND_REPORTED_STATE_CALLBACKS
    print ( "Confirmation for reported state received with:\nstatus_code = [%d]\ncontext = %s" % (status_code, user_context) )
    SEND_REPORTED_STATE_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_REPORTED_STATE_CALLBACKS )

def device_method_callback(method_name, payload, user_context):
    global METHOD_CALLBACKS,MESSAGE_SWITCH
    print ( "\nMethod callback called with:\nmethodName = %s\npayload = %s\ncontext = %s" % (method_name, payload, user_context) )
    METHOD_CALLBACKS += 1
    print ( "Total calls confirmed: %d\n" % METHOD_CALLBACKS )
    device_method_return_value = DeviceMethodReturnValue()
    device_method_return_value.response = "{ \"Response\": \"This is the response from the device\" }"
    device_method_return_value.status = 200
    if method_name == "start":
        MESSAGE_SWITCH = True
        print ( "Start sending message\n" )
        device_method_return_value.response = "{ \"Response\": \"Successfully started\" }"
        return device_method_return_value
    if method_name == "stop":
        MESSAGE_SWITCH = False
        print ( "Stop sending message\n" )
        device_method_return_value.response = "{ \"Response\": \"Successfully stopped\" }"
        return device_method_return_value
    return device_method_return_value

def blob_upload_conf_callback(result, user_context):
    global BLOB_CALLBACKS
    print ( "Blob upload confirmation[%d] received for message with result = %s" % (user_context, result) )
    BLOB_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % BLOB_CALLBACKS )

def iothub_client_init():
    # prepare iothub client
    client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
    if client.protocol == IoTHubTransportProvider.HTTP:
        client.set_option("timeout", TIMEOUT)
        client.set_option("MinimumPollingTime", MINIMUM_POLLING_TIME)
    # set the time until a message times out
    client.set_option("messageTimeout", MESSAGE_TIMEOUT)
    # to enable MQTT logging set to 1
    if client.protocol == IoTHubTransportProvider.MQTT:
        client.set_option("logtrace", 0)
    client.set_message_callback(
        receive_message_callback, RECEIVE_CONTEXT)
    if client.protocol == IoTHubTransportProvider.MQTT or client.protocol == IoTHubTransportProvider.MQTT_WS:
        client.set_device_twin_callback(
            device_twin_callback, TWIN_CONTEXT)
        client.set_device_method_callback(
            device_method_callback, METHOD_CONTEXT)
    return client

def print_last_message_time(client):
    try:
        last_message = client.get_last_message_receive_time()
        print ( "Last Message: %s" % time.asctime(time.localtime(last_message)) )
        print ( "Actual time : %s" % time.asctime() )
    except IoTHubClientError as iothub_client_error:
        if iothub_client_error.args[0].result == IoTHubClientResult.INDEFINITE_TIME:
            print ( "No message received" )
        else:
            print ( iothub_client_error )

def iothub_client_sample_run():
    try:
        client = iothub_client_init()

        if client.protocol == IoTHubTransportProvider.MQTT:
            print ( "IoTHubClient is reporting state" )
            reported_state = "{\"newState\":\"standBy\",\"relaysState\":{\"dining\":\"off\"}}"
            client.send_reported_state(reported_state, len(reported_state), send_reported_state_callback, SEND_REPORTED_STATE_CONTEXT)

        sensor = ReadData()

        #telemetry.send_telemetry_data(parse_iot_hub_name(), EVENT_SUCCESS, "IoT hub connection is established")
        while True:
            global MESSAGE_COUNT,MESSAGE_SWITCH
            if MESSAGE_SWITCH:
                # send a few messages every minute
                print ( "IoTHubClient sending %d messages" % MESSAGE_COUNT )
                #temperature = sensor.read_temperature()
                #humidity = sensor.read_humidity()
                sensor.updVal()
                sensor.logValues()
                msg_txt_formatted = MSG_TXT % (
                    sensor.diningTemp,
                    sensor.bathTemp)
                print (msg_txt_formatted)
                message = IoTHubMessage(msg_txt_formatted)
                # optional: assign ids
                message.message_id = "message_%d" % MESSAGE_COUNT
                message.correlation_id = "correlation_%d" % MESSAGE_COUNT
                # optional: assign properties
                prop_map = message.properties()
                prop_map.add("temperatureAlert", "true" if sensor.diningTemp > TEMPERATURE_ALERT else "false")

                client.send_event_async(message, send_confirmation_callback, MESSAGE_COUNT)
                print ( "IoTHubClient.send_event_async accepted message [%d] for transmission to IoT Hub." % MESSAGE_COUNT )

                status = client.get_send_status()
                print ( "Send status: %s" % status )
                MESSAGE_COUNT += 1
            time.sleep(config.MESSAGE_TIMESPAN / 1000.0)

    except IoTHubError as iothub_error:
        print ( "Unexpected error %s from IoTHub" % iothub_error )
        telemetry.send_telemetry_data(parse_iot_hub_name(), EVENT_FAILED, "Unexpected error %s from IoTHub" % iothub_error)
        return
    except KeyboardInterrupt:
        print ( "IoTHubClient sample stopped" )

    print_last_message_time(client)

def led_blink():
    GPIO.output(config.GPIO_PIN_ADDRESS, GPIO.HIGH)
    time.sleep(config.BLINK_TIMESPAN / 1000.0)
    GPIO.output(config.GPIO_PIN_ADDRESS, GPIO.LOW)

def usage():
    print ( "Usage: iothub_client_sample.py -p <protocol> -c <connectionstring>" )
    print ( "    protocol        : <amqp, amqp_ws, http, mqtt, mqtt_ws>" )
    print ( "    connectionstring: <HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>>" )

def parse_iot_hub_name():
    m = re.search("HostName=(.*?)\.", CONNECTION_STRING)
    return m.group(1)

if __name__ == "__main__":
    print ( "\nPython %s" % sys.version )
    print ( "IoT Hub Client for Python" )

    iothub_client_sample_run()
<|endoftext|>