<commit_before># -*- coding: utf-8 -*-

import datetime
import httplib2
import os
import re
import string
import uuid

from apiclient import discovery
from celery import Celery
import click
from flask import (
    abort,
    Flask,
    g,
    json,
    redirect,
    render_template,
    request,
    send_from_directory,
    url_for
)
from flask_login import (
    current_user,
    LoginManager,
    login_required,
    login_user,
    logout_user,
    UserMixin,
)
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from oauth2client.client import (
    HttpAccessTokenRefreshError,
    OAuth2WebServerFlow,
    OAuth2Credentials,
)
from raven.contrib.celery import register_signal, register_logger_signal
from raven.contrib.flask import Sentry
from sqlalchemy.dialects.postgresql import JSONB

GOOGLE_SHEETS_DISCOVERY_URL = 'https://sheets.googleapis.com/$discovery/rest?version=v4'
PROFILE_EMBED_TEMPLATE = """<form method="POST" action="%s">
    <input type="hidden" name="_spreadsheet_url" value="YOUR GOOGLE SHEET URL">
    <input type="text" name="YOUR COLUMN NAME">

    <button type="submit"></button>
</form>"""
DEMO_HTML = """<form method="POST" action="https://formendpoint.com/demo">
    <input type="hidden" name="_spreadsheet_url" value="https://docs.google.com/spreadsheets/d/1QWeHPvZW4atIZxobdVXr3IYl8u4EnV99Dm_K4yGfo_8/edit?usp=sharing">
    <input type="email" name="email">

    <button type="submit">Submit</button>
</form>"""
GOOGLE_SHEET_URL_PATTERN = re.compile("^https\://docs\.google\.com/spreadsheets/d/(\S+)/.*")

def make_celery(app):
    celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],
                    broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SERVER_NAME'] = os.environ['SERVER_NAME']
app.config['PREFERRED_URL_SCHEME'] = os.environ['PREFERRED_URL_SCHEME']
app.config['CELERY_RESULT_BACKEND'] = os.environ['REDIS_URL']
app.config['CELERY_BROKER_URL'] = os.environ['REDIS_URL']
app.secret_key = os.environ['FLASK_SECRET_KEY']

login_manager = LoginManager()
login_manager.init_app(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
celery = make_celery(app)
sentry = Sentry(app)

register_logger_signal(sentry.client)
register_signal(sentry.client)

##########
# Models #
##########

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.Text, unique=True, nullable=False)
    username = db.Column(db.String, unique=True)
    verified = db.Column(db.Boolean, default=False)
    credentials_json = db.Column(JSONB)

    validation_hash = db.Column(db.Text)
    validation_hash_added = db.Column(db.DateTime)

    @property
    def credentials(self):
        if self.credentials_json:
            return OAuth2Credentials.from_json(self.credentials_json)
        else:
            return None

    @credentials.setter
    def credentials(self, cred):
        if type(cred) is OAuth2Credentials:
            self.credentials_json = cred.to_json()
        else:
            self.credentials_json = cred

    @property
    def sheets(self):
        http = self.credentials.authorize(httplib2.Http())
        return discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=GOOGLE_SHEETS_DISCOVERY_URL, cache_discovery=False)

    def refresh_validation_hash(self):
        self.validation_hash = uuid.uuid4().hex
        self.validation_hash_added = datetime.datetime.now()

class GoogleSheet(object):
    @staticmethod
    def find_furthest_empty_row(data, ranges):
        return

    @staticmethod
    def convert_to_column_title(num):
        title = ''
        alist = string.ascii_uppercase
        while num:
            mod = (num-1) % 26
            num = int((num - mod) / 26)
            title += alist[mod]
        return title[::-1]

#########
# Tasks #
#########

@celery.task()
def insert_form(user_id, spreadsheet_id, form_data):
    user = User.query.get(user_id)
    spreadsheet = user.sheets.spreadsheets().get(
        spreadsheetId=spreadsheet_id,
        includeGridData=True).execute()

    columnar_named_ranges = {
        r['name']: r['namedRangeId'] for r in spreadsheet.get('namedRanges', [])
        if r['range'].get('startRowIndex') == None
    }

    if columnar_named_ranges:
        furthest_row = GoogleSheet.find_furthest_empty_row(spreadsheet['sheets']['data'], columnar_named_ranges)
        # update_value_ranges = GoogleSheet.insert_form(row=furthest_row, ranges=columnar_named_ranges)

    else:
        first_row = next(iter(spreadsheet['sheets'][0]['data'][0].get('rowData', [])), None)
        if first_row:
            sheet_column_headers = [c.get('effectiveValue', {}).get('stringValue', None) for c in first_row['values']]
            append_row = []
            for header in sheet_column_headers:
                append_row.append(form_data.get(header, None))

            body = {
                'majorDimension': 'ROWS',
                'values': [append_row]
            }

            user.sheets.spreadsheets().values().append(
                spreadsheetId=spreadsheet_id,
                range='A:%s' % GoogleSheet.convert_to_column_title(len(sheet_column_headers)),
                valueInputOption='RAW',
                body=body).execute()

###########
# Helpers #
###########

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

def get_flow():
    flow = OAuth2WebServerFlow(
        client_id=os.environ['GOOGLE_CLIENT_ID'],
        client_secret=os.environ['GOOGLE_CLIENT_SECRET'],
        scope='https://www.googleapis.com/auth/spreadsheets',
        redirect_uri=url_for('auth_finish', _external=True),
        )
    flow.params['access_type'] = 'offline'
    flow.params['prompt'] = 'consent'
    return flow

@app.errorhandler(500)
def internal_server_error(error):
    return render_template('500.html',
        event_id=g.sentry_event_id,
        public_dsn=sentry.client.get_public_dsn('https')
    )

##########
# Routes #
##########

@app.route('/')
def index():
    return render_template('index.html', demo_html=DEMO_HTML)

@app.route('/login/<validation_hash>')
def login(validation_hash):
    user = User.query.filter_by(validation_hash=validation_hash).first()
    if user and user.validation_hash_added and user.validation_hash_added > datetime.datetime.now() - datetime.timedelta(hours=4):
        login_user(user)
    return redirect(url_for('profile', username=user.username))

@login_required
@app.route('/auth-start')
def auth_start():
    if (current_user.is_authenticated and current_user.credentials and
        (current_user.credentials.refresh_token or
        request.args.get('force') != 'True')):
        return redirect(request.args.get('next') or url_for('profile', username=current_user.username))
    return redirect(get_flow().step1_get_authorize_url())

@login_required
@app.route('/auth-finish')
def auth_finish():
    credentials = get_flow().step2_exchange(request.args.get('code'))
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('sheets', 'v4', http=http,
                              discoveryServiceUrl=GOOGLE_SHEETS_DISCOVERY_URL,
                              cache_discovery=False)
    current_user.credentials_json = credentials.to_json()
    db.session.add(current_user)
    db.session.commit()
    return redirect(url_for('profile', username=current_user.username))

@login_required
@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

@app.route('/500')
def test_error():
    assert False

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'),
                               'favicon.ico', mimetype='image/vnd.microsoft.icon')

@app.route('/<username>', methods=['GET', 'POST'])
def profile(username):
    if request.method == 'POST':
        form_data = request.form.copy()
        spreadsheet_id = form_data.pop('_spreadsheet_id')
        if not spreadsheet_id:
            spreadsheet_url = form_data.pop('_spreadsheet_url')
            if spreadsheet_url:
                spreadsheet_id = GOOGLE_SHEET_URL_PATTERN.search(spreadsheet_url).group(1)

        user = User.query.filter_by(username=username).first()
        insert_form.delay(user.id, spreadsheet_id, form_data)

        if request.args.get('next'):
            return redirect(request.args.get('next'))
        else:
            return redirect(url_for('success', username=user.username, _external=True))

    if current_user.is_authenticated:
        embed_form = PROFILE_EMBED_TEMPLATE % url_for('profile', username=current_user.username, _external=True)
        return render_template('profile.html', embed_form=embed_form)
    return redirect(url_for('index'))

@app.route('/<username>/success')
def success(username):
    if current_user.is_authenticated:
        return "Setup your form to redirect anywhere by using the next parameter."
    return "Success!"

############
# Commands #
############

@app.cli.command()
@click.option('--email', prompt="Email")
@click.option('--username', prompt="username")
def createuser(email, username):
    db.session.add(User(email=email, username=username))
    db.session.commit()

@app.cli.command()
@click.option('--email', prompt="Email")
def login(email):
    user = User.query.filter_by(email=email).first()
    if user:
        user.refresh_validation_hash()
        db.session.add(user)
        db.session.commit()
        click.echo('Login at %s' % url_for('login', validation_hash=user.validation_hash))
    else:
        click.echo('%s doesn\'t exist. Run `flask createuser`')
<commit_msg>fix form submission<commit_after># -*- coding: utf-8 -*-

import datetime
import httplib2
import os
import re
import string
import uuid

from apiclient import discovery
from celery import Celery
import click
from flask import (
    abort,
    Flask,
    g,
    json,
    redirect,
    render_template,
    request,
    send_from_directory,
    url_for
)
from flask_login import (
    current_user,
    LoginManager,
    login_required,
    login_user,
    logout_user,
    UserMixin,
)
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from oauth2client.client import (
    HttpAccessTokenRefreshError,
    OAuth2WebServerFlow,
    OAuth2Credentials,
)
from raven.contrib.celery import register_signal, register_logger_signal
from raven.contrib.flask import Sentry
from sqlalchemy.dialects.postgresql import JSONB

GOOGLE_SHEETS_DISCOVERY_URL = 'https://sheets.googleapis.com/$discovery/rest?version=v4'
PROFILE_EMBED_TEMPLATE = """<form method="POST" action="%s">
    <input type="hidden" name="_spreadsheet_url" value="YOUR GOOGLE SHEET URL">
    <input type="text" name="YOUR COLUMN NAME">

    <button type="submit"></button>
</form>"""
DEMO_HTML = """<form method="POST" action="%s://%s/demo">
    <input type="hidden" name="_spreadsheet_url" value="https://docs.google.com/spreadsheets/d/1QWeHPvZW4atIZxobdVXr3IYl8u4EnV99Dm_K4yGfo_8/edit?usp=sharing">
    <input type="email" name="email">

    <button type="submit">Submit</button>
</form>"""
GOOGLE_SHEET_URL_PATTERN = re.compile("^https\://docs\.google\.com/spreadsheets/d/(\S+)/.*")

def make_celery(app):
    celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],
                    broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SERVER_NAME'] = os.environ['SERVER_NAME']
app.config['PREFERRED_URL_SCHEME'] = os.environ['PREFERRED_URL_SCHEME']
app.config['CELERY_RESULT_BACKEND'] = os.environ['REDIS_URL']
app.config['CELERY_BROKER_URL'] = os.environ['REDIS_URL']
app.secret_key = os.environ['FLASK_SECRET_KEY']

login_manager = LoginManager()
login_manager.init_app(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
celery = make_celery(app)
sentry = Sentry(app)

register_logger_signal(sentry.client)
register_signal(sentry.client)

##########
# Models #
##########

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.Text, unique=True, nullable=False)
    username = db.Column(db.String, unique=True)
    verified = db.Column(db.Boolean, default=False)
    credentials_json = db.Column(JSONB)

    validation_hash = db.Column(db.Text)
    validation_hash_added = db.Column(db.DateTime)

    @property
    def credentials(self):
        if self.credentials_json:
            return OAuth2Credentials.from_json(self.credentials_json)
        else:
            return None

    @credentials.setter
    def credentials(self, cred):
        if type(cred) is OAuth2Credentials:
            self.credentials_json = cred.to_json()
        else:
            self.credentials_json = cred

    @property
    def sheets(self):
        http = self.credentials.authorize(httplib2.Http())
        return discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=GOOGLE_SHEETS_DISCOVERY_URL, cache_discovery=False)

    def refresh_validation_hash(self):
        self.validation_hash = uuid.uuid4().hex
        self.validation_hash_added = datetime.datetime.now()

class GoogleSheet(object):
    @staticmethod
    def find_furthest_empty_row(data, ranges):
        return

    @staticmethod
    def convert_to_column_title(num):
        title = ''
        alist = string.ascii_uppercase
        while num:
            mod = (num-1) % 26
            num = int((num - mod) / 26)
            title += alist[mod]
        return title[::-1]

#########
# Tasks #
#########

@celery.task()
def insert_form(user_id, spreadsheet_id, form_data):
    user = User.query.get(user_id)
    spreadsheet = user.sheets.spreadsheets().get(
        spreadsheetId=spreadsheet_id,
        includeGridData=True).execute()

    columnar_named_ranges = {
        r['name']: r['namedRangeId'] for r in spreadsheet.get('namedRanges', [])
        if r['range'].get('startRowIndex') == None
    }

    if columnar_named_ranges:
        furthest_row = GoogleSheet.find_furthest_empty_row(spreadsheet['sheets']['data'], columnar_named_ranges)
        # update_value_ranges = GoogleSheet.insert_form(row=furthest_row, ranges=columnar_named_ranges)

    else:
        first_row = next(iter(spreadsheet['sheets'][0]['data'][0].get('rowData', [])), None)
        if first_row:
            sheet_column_headers = [c.get('effectiveValue', {}).get('stringValue', None) for c in first_row['values']]
            append_row = []
            for header in sheet_column_headers:
                append_row.append(form_data.get(header, None))

            body = {
                'majorDimension': 'ROWS',
                'values': [append_row]
            }

            user.sheets.spreadsheets().values().append(
                spreadsheetId=spreadsheet_id,
                range='A:%s' % GoogleSheet.convert_to_column_title(len(sheet_column_headers)),
                valueInputOption='RAW',
                body=body).execute()

###########
# Helpers #
###########

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

def get_flow():
    flow = OAuth2WebServerFlow(
        client_id=os.environ['GOOGLE_CLIENT_ID'],
        client_secret=os.environ['GOOGLE_CLIENT_SECRET'],
        scope='https://www.googleapis.com/auth/spreadsheets',
        redirect_uri=url_for('auth_finish', _external=True),
        )
    flow.params['access_type'] = 'offline'
    flow.params['prompt'] = 'consent'
    return flow

@app.errorhandler(500)
def internal_server_error(error):
    return render_template('500.html',
        event_id=g.sentry_event_id,
        public_dsn=sentry.client.get_public_dsn('https')
    )

##########
# Routes #
##########

@app.route('/')
def index():
    return render_template('index.html', demo_html=DEMO_HTML  % (app.config['PREFERRED_URL_SCHEME'], app.config['SERVER_NAME']))

@app.route('/login/<validation_hash>')
def login(validation_hash):
    user = User.query.filter_by(validation_hash=validation_hash).first()
    if user and user.validation_hash_added and user.validation_hash_added > datetime.datetime.now() - datetime.timedelta(hours=4):
        login_user(user)
    return redirect(url_for('profile', username=user.username))

@login_required
@app.route('/auth-start')
def auth_start():
    if (current_user.is_authenticated and current_user.credentials and
        (current_user.credentials.refresh_token or
        request.args.get('force') != 'True')):
        return redirect(request.args.get('next') or url_for('profile', username=current_user.username))
    return redirect(get_flow().step1_get_authorize_url())

@login_required
@app.route('/auth-finish')
def auth_finish():
    credentials = get_flow().step2_exchange(request.args.get('code'))
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('sheets', 'v4', http=http,
                              discoveryServiceUrl=GOOGLE_SHEETS_DISCOVERY_URL,
                              cache_discovery=False)
    current_user.credentials_json = credentials.to_json()
    db.session.add(current_user)
    db.session.commit()
    return redirect(url_for('profile', username=current_user.username))

@login_required
@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

@app.route('/500')
def test_error():
    assert False

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'),
                               'favicon.ico', mimetype='image/vnd.microsoft.icon')

@app.route('/<username>', methods=['GET', 'POST'])
def profile(username):
    if request.method == 'POST':
        form_data = request.form.copy()
        if '_spreadsheet_id' in form_data:
            spreadsheet_id = form_data.pop('_spreadsheet_id')
        elif '_spreadsheet_url' in form_data:
            spreadsheet_url = form_data.pop('_spreadsheet_url')
            spreadsheet_id = GOOGLE_SHEET_URL_PATTERN.search(spreadsheet_url).group(1)

        user = User.query.filter_by(username=username).first()
        insert_form.delay(user.id, spreadsheet_id, form_data)

        if request.args.get('next'):
            return redirect(request.args.get('next'))
        else:
            return redirect(url_for('success', username=user.username, _external=True))

    if current_user.is_authenticated:
        embed_form = PROFILE_EMBED_TEMPLATE % url_for('profile', username=current_user.username, _external=True)
        return render_template('profile.html', embed_form=embed_form)
    return redirect(url_for('index'))

@app.route('/<username>/success')
def success(username):
    if current_user.is_authenticated:
        return "Setup your form to redirect anywhere by using the next parameter."
    return "Success!"

############
# Commands #
############

@app.cli.command()
@click.option('--email', prompt="Email")
@click.option('--username', prompt="username")
def createuser(email, username):
    db.session.add(User(email=email, username=username))
    db.session.commit()

@app.cli.command()
@click.option('--email', prompt="Email")
def login(email):
    user = User.query.filter_by(email=email).first()
    if user:
        user.refresh_validation_hash()
        db.session.add(user)
        db.session.commit()
        click.echo('Login at %s' % url_for('login', validation_hash=user.validation_hash))
    else:
        click.echo('%s doesn\'t exist. Run `flask createuser`')
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""
./app.py typogram
"""

import sys

from flask import Flask, jsonify, request

import kilogram
from kilogram.dataset.entity_linking.gerbil import DataSet
from kilogram.entity_linking import syntactic_subsumption
from kilogram.dataset.dbpedia import DBPediaOntology, NgramEntityResolver
from kilogram.entity_types.prediction import NgramTypePredictor
from kilogram import NgramService

NgramService.configure(hbase_host=('diufpc304', '9090'))
kilogram.NER_HOSTNAME = 'diufpc54.unifr.ch'
ner = NgramEntityResolver("/Users/dragoon/Downloads/dbpedia/dbpedia_data.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_uri_excludes.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_lower_includes.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_2015-04.owl")

dbpedia_ontology = DBPediaOntology('dbpedia_2015-04.owl')
ngram_predictor = NgramTypePredictor(sys.argv[1], dbpedia_ontology)

app = Flask(__name__)

@app.route('/entity-linking/d2kb/prior', methods=['POST'])
def d2kb_prior():
    result = request.get_json(force=True)
    candidates = DataSet(result['text'], result['mentions'], ner).candidates
    syntactic_subsumption(candidates)
    new_mentions = []
    for mention, candidate in zip(result['mentions'], candidates):
        mention['uri'] = candidate.get_max_uri()
        new_mentions.append(mention)
    return jsonify(new_mentions)

@app.route('/entity-linking/d2kb/prior-typed', methods=['POST'])
def d2kb_prior():
    result = request.get_json(force=True)
    candidates = DataSet(result['text'], result['mentions'], ner).candidates
    syntactic_subsumption(candidates)
    for candidate in candidates:
        candidate.init_context_types(ngram_predictor)
    new_mentions = []
    for mention, candidate in zip(result['mentions'], candidates):
        context_types_list = [c.context_types for c in candidates
                              if c.context_types and c.cand_string == candidate.cand_string]
        if context_types_list:
            mention['uri'] = candidate.get_max_typed_uri(context_types_list)
        else:
            mention['uri'] = candidate.get_max_uri()
        new_mentions.append(mention)
    return jsonify(new_mentions)

@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
<commit_msg>execute permissions<commit_after>#!/usr/bin/env python
"""
./app.py typogram
"""

import sys

from flask import Flask, jsonify, request

import kilogram
from kilogram.dataset.entity_linking.gerbil import DataSet
from kilogram.entity_linking import syntactic_subsumption
from kilogram.dataset.dbpedia import DBPediaOntology, NgramEntityResolver
from kilogram.entity_types.prediction import NgramTypePredictor
from kilogram import NgramService

NgramService.configure(hbase_host=('diufpc304', '9090'))
kilogram.NER_HOSTNAME = 'diufpc54.unifr.ch'
ner = NgramEntityResolver("/Users/dragoon/Downloads/dbpedia/dbpedia_data.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_uri_excludes.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_lower_includes.txt",
                          "/Users/dragoon/Downloads/dbpedia/dbpedia_2015-04.owl")

dbpedia_ontology = DBPediaOntology('dbpedia_2015-04.owl')
ngram_predictor = NgramTypePredictor(sys.argv[1], dbpedia_ontology)

app = Flask(__name__)

@app.route('/entity-linking/d2kb/prior', methods=['POST'])
def d2kb_prior():
    result = request.get_json(force=True)
    candidates = DataSet(result['text'], result['mentions'], ner).candidates
    syntactic_subsumption(candidates)
    new_mentions = []
    for mention, candidate in zip(result['mentions'], candidates):
        mention['uri'] = candidate.get_max_uri()
        new_mentions.append(mention)
    return jsonify(new_mentions)

@app.route('/entity-linking/d2kb/prior-typed', methods=['POST'])
def d2kb_prior():
    result = request.get_json(force=True)
    candidates = DataSet(result['text'], result['mentions'], ner).candidates
    syntactic_subsumption(candidates)
    for candidate in candidates:
        candidate.init_context_types(ngram_predictor)
    new_mentions = []
    for mention, candidate in zip(result['mentions'], candidates):
        context_types_list = [c.context_types for c in candidates
                              if c.context_types and c.cand_string == candidate.cand_string]
        if context_types_list:
            mention['uri'] = candidate.get_max_typed_uri(context_types_list)
        else:
            mention['uri'] = candidate.get_max_uri()
        new_mentions.append(mention)
    return jsonify(new_mentions)

@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

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


<commit_before>import os
import sys

import paho.mqtt.client as mqtt

import tornado.ioloop
import tornado.web
import tornado.template
import tornado.gen
from tornado.queues import Queue

import settings
from display import displayText, clock, dimmer
from standby import stabdby_mode

brokerIP = settings.read('settings', 'mqtt', 'brokerIP')
brokerPort = settings.read('settings', 'mqtt', 'brokerPort')
httpPort = settings.read('settings', 'http', 'port')
standbyFrom = settings.read('settings', 'standby', 'from')
standbyTo = settings.read('settings', 'standby', 'to')

q = Queue(maxsize=2)

class HomePage(tornado.web.RequestHandler):

    def get(self):
        self.render('app.tpl')

class MessagePage(tornado.web.RequestHandler):

    def get(self):
        self.render('message.tpl')

    def post(self):
        msg = self.get_argument('msg')
        text_color = self.get_argument('text_color')
        bg_color = self.get_argument('bg_color')
        delay = self.get_argument('delay')

        if msg:
            displayText(5, str(msg), text_color, bg_color, delay)
        else:
            print 'err'
        self.render('message.tpl')

def on_connect(client, obj, flags, rc):
    print("rc: " + str(rc))

@tornado.gen.coroutine
def on_message(client, obj, msg):
    # print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
    item = str(msg.payload)
    yield q.put(item)
    # print('Put %s' % item)

def mqtt_run():
    feeds = settings.read('feeds')
    print("Follow %s topics") % (len(feeds))
    feedsTopics = [(f.get('topic'),f.get('priority')) for f in feeds]

    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(brokerIP, brokerPort, 60)
    client.subscribe(feedsTopics)

    client.loop_start()

class SettingsPage(tornado.web.RequestHandler):
    def get(self):
        self.render('settings.tpl')

def make_app():
    # run MQTT loop in background
    mqtt_run()
    return tornado.web.Application([
        (r'/', HomePage),
        (r'/message', MessagePage),
        (r'/settings', SettingsPage),
        (r'/favicon.ico', tornado.web.StaticFileHandler, {'path': os.path.join(os.path.dirname(__file__), "static")}),
    ],
    template_path=os.path.join(os.path.dirname(__file__), "views"),
    static_path=os.path.join(os.path.dirname(__file__), "static"),
    debug=True)

@tornado.gen.coroutine
def update():
    if not standby:
        dimmer()
        standby = stabdby_mode(standbyFrom, standbyTo)
        # if items in queue - display them
        if q.qsize():
            item = yield q.get()
            try:
                # print('Doing work on %s' % item)
                displayText(2, item, 'text_green', 'bg_black', 5)
                yield tornado.gen.sleep(0.01)
            finally:
                q.task_done()
            yield q.join()
        clock()

if __name__ == "__main__":
    app = make_app()
    app.listen(httpPort)
    mainLoop = tornado.ioloop.IOLoop.current()
    scheduler = tornado.ioloop.PeriodicCallback(
        update, 500, io_loop=mainLoop)

    scheduler.start()
    mainLoop.start()
<commit_msg>Standby Mode fixes #2<commit_after>import os
import sys

import paho.mqtt.client as mqtt

import tornado.ioloop
import tornado.web
import tornado.template
import tornado.gen
from tornado.queues import Queue

import settings
from display import displayText, clock, dimmer
from standby import stabdby_mode

brokerIP = settings.read('settings', 'mqtt', 'brokerIP')
brokerPort = settings.read('settings', 'mqtt', 'brokerPort')
httpPort = settings.read('settings', 'http', 'port')
standbyFrom = settings.read('settings', 'standby', 'from')
standbyTo = settings.read('settings', 'standby', 'to')

q = Queue(maxsize=2)

class HomePage(tornado.web.RequestHandler):

    def get(self):
        self.render('app.tpl')

class MessagePage(tornado.web.RequestHandler):

    def get(self):
        self.render('message.tpl')

    def post(self):
        msg = self.get_argument('msg')
        text_color = self.get_argument('text_color')
        bg_color = self.get_argument('bg_color')
        delay = self.get_argument('delay')

        if msg:
            displayText(5, str(msg), text_color, bg_color, delay)
        else:
            print 'err'
        self.render('message.tpl')

def on_connect(client, obj, flags, rc):
    print("rc: " + str(rc))

@tornado.gen.coroutine
def on_message(client, obj, msg):
    # print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
    item = str(msg.payload)
    yield q.put(item)
    # print('Put %s' % item)

def mqtt_run():
    feeds = settings.read('feeds')
    print("Follow %s topics") % (len(feeds))
    feedsTopics = [(f.get('topic'),f.get('priority')) for f in feeds]

    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(brokerIP, brokerPort, 60)
    client.subscribe(feedsTopics)

    client.loop_start()

class SettingsPage(tornado.web.RequestHandler):
    def get(self):
        self.render('settings.tpl')

def make_app():
    # run MQTT loop in background
    mqtt_run()
    return tornado.web.Application([
        (r'/', HomePage),
        (r'/message', MessagePage),
        (r'/settings', SettingsPage),
        (r'/favicon.ico', tornado.web.StaticFileHandler, {'path': os.path.join(os.path.dirname(__file__), "static")}),
    ],
    template_path=os.path.join(os.path.dirname(__file__), "views"),
    static_path=os.path.join(os.path.dirname(__file__), "static"),
    debug=True)

@tornado.gen.coroutine
def update():
    standby = stabdby_mode(standbyFrom, standbyTo)
    if not standby:
        dimmer()
        # if items in queue - display them
        if q.qsize():
            item = yield q.get()
            try:
                # print('Doing work on %s' % item)
                displayText(2, item, 'text_green', 'bg_black', 5)
                yield tornado.gen.sleep(0.01)
            finally:
                q.task_done()
            yield q.join()
        clock()

if __name__ == "__main__":
    app = make_app()
    app.listen(httpPort)
    mainLoop = tornado.ioloop.IOLoop.current()
    scheduler = tornado.ioloop.PeriodicCallback(
        update, 500, io_loop=mainLoop)

    scheduler.start()
    mainLoop.start()
<|endoftext|>


<commit_before># python3
# coding=utf-8
# Copyright 2021 Google LLC.
#
# 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.

r"""Script to run the end-to-end ML Windowing Pipeline.

Before running this pipeline, first run the end-to-end windowing pipeline, and
then use the data to train an ML model. Once the model is deployed and you want
predictions about live customers, run this script to generate features for the
customers over a single window of data, and then input the features into the
ML model to get it's predictions.

Example Usage:

python run_prediction_pipeline.py \
--project_id=<PROJECT_ID> \
--dataset_id=<DATASET_ID> \
--analytics_table="bigquery-public-data.google_analytics_sample.ga_sessions_*" \
--snapshot_date_offset_in_days=1 \
--lookback_window_size_in_days=30 \
--lookback_window_gap_in_days=0 \
--categorical_fact_value_to_column_name_table=<BIGQUERY TABLE from training run>

python run_prediction_pipeline.py \
--project_id=<PROJECT_ID> \
--dataset_id=<DATASET_ID> \
--analytics_table="bigquery-public-data.google_analytics_sample.ga_sessions_*" \
--snapshot_date_offset_in_days=1 \
--lookback_window_size_in_days=30 \
--lookback_window_gap_in_days=0 \
--features_sql='features_from_input.sql' \
--sum_values='totals_visits;totals_hits' \
--avg_values='totals_visits;totals_hits' \
--count_values='geoNetwork_metro:[Providence-New Bedford///,MA",Rochester-Mason City-Austin///,IA]:[Others]' \
--mode_values='hits_eCommerceAction_action_type:[3]:[Others]' \
--proportions_values='channelGrouping:[Organic Search,Social,Direct,Referral,Paid Search,Affiliates]:[Others]' \
--latest_values='device_isMobile:[false,true]:[Others]'
"""

import base64
import datetime
import json
from typing import Any, Dict

from absl import app
from absl import flags

from google.cloud import pubsub_v1
from gps_building_blocks.ml.data_prep.ml_windowing_pipeline import ml_windowing_pipeline

FLAGS = flags.FLAGS

# GCP flags.
flags.DEFINE_string('project_id', None, 'Google Cloud project to run inside.')
flags.DEFINE_string('dataset_id', None, 'BigQuery dataset to write the output.')
flags.DEFINE_string('run_id', None,
                    'By default, all output tables have the snapshot_date '
                    'suffix. Use this flag to override the suffix which must '
                    'be compatible with BigQuery table naming requirements.')
# BigQuery input flags.
flags.DEFINE_string('analytics_table', None,
                    'Full BigQuery id of the Google Analytics/Firebase table.')
# Windowing flags.
# Either set the snapshot_date with a specific date or the
# snapshot_date_offset_in_days with a relative offset from today.
flags.DEFINE_string('snapshot_date', None,
                    'YYYY-MM-DD snapshot date to make predictions from.')
flags.DEFINE_integer('snapshot_date_offset_in_days', None,
                     'Number of days before today to set the snapshot_date.')
flags.DEFINE_string('timezone', 'UTC',
                    'Timezone for the Google Analytics Data, '
                    'e.g. "Australia/Sydney", or "+11:00"')
flags.DEFINE_integer('lookback_window_gap_in_days', None,
                     'The lookback window ends on (snapshot_ts - '
                     'lookback_window_gap_in_days) days. Sessions '
                     'outside the lookback window are ignored.',
                     lower_bound=0)
flags.DEFINE_integer('lookback_window_size_in_days', None,
                     'The lookback window starts on (snapshot_ts - '
                     'lookback_window_size_in_days - '
                     'lookback_window_gap_in_days) days. Sessions outside the '
                     'lookback window are ignored.',
                     lower_bound=0)

# Location of SQL templates that can be overridden by the user.
flags.DEFINE_string('conversions_sql', 'conversions_google_analytics.sql',
                    'Name of the conversion extraction SQL file in templates/.')
flags.DEFINE_string('sessions_sql', 'sessions_google_analytics.sql',
                    'Name of the session extraction SQL file in templates/.')
flags.DEFINE_string('windows_sql', 'sliding_windows.sql',
                    'Name of the windows extraction SQL file in templates/.')
flags.DEFINE_string('features_sql', 'automatic_features.sql',
                    'Name of the feature extraction SQL file in templates/.'
                    'Override default value with `features_from_input.sql` for '
                    'user-provided Feature Option configurations.')
# Feature options:
# Required flag only when using automatic_features.sql.
flags.DEFINE_string('categorical_fact_value_to_column_name_table', None,
                    'BigQuery table containing the fact (name, value) to '
                    'column name mapping from the model\'s training run using '
                    'automatic_features.sql.')
# Alternative feature extraction using command line flags.
flags.DEFINE_string('sum_values', '', 'Feature Options for Sum')
flags.DEFINE_string('avg_values', '', 'Feature Options for Average')
flags.DEFINE_string('count_values', '', 'Feature Options for Count')
flags.DEFINE_string('mode_values', '', 'Feature Options for Mode')
flags.DEFINE_string('proportions_values', '', 'Feature Options for Proportion')
flags.DEFINE_string('latest_values', '', 'Feature Options for Recent')
# Debug flag.
flags.DEFINE_bool('verbose', False, 'Debug logging.')

def run(params: Dict[str, Any]) -> int:
  """Sets default flag values and runs the features pipeline.

  Side-effect: Updates params with additional normalized parameters.

  Args:
    params: Mapping of pipeline string parameter names to values.
  Returns:
    0 on success and non-zero otherwise.
  Raises:
    ValueError: User formatted message on error.
  """
  if params.get('snapshot_date') and params.get('snapshot_date_offset_in_days'):
    raise ValueError(
        'Specify either snapshot_date or snapshot_date_offset_in_days.')
  elif params.get('snapshot_date'):
    params['snapshot_start_date'] = params['snapshot_date']
    params['snapshot_end_date'] = params['snapshot_date']
  elif params.get('snapshot_date_offset_in_days'):
    offset_days = int(params['snapshot_date_offset_in_days'])
    end_date = (datetime.date.today() - datetime.timedelta(days=offset_days))
    params['snapshot_start_date'] = end_date.strftime('%Y-%m-%d')
    params['snapshot_end_date'] = end_date.strftime('%Y-%m-%d')
  else:
    raise ValueError('Set snapshot_date or snapshot_date_offset_in_days.')
  if not params.get('run_id'):
    params['run_id'] = datetime.datetime.strptime(
        params['snapshot_end_date'], '%Y-%m-%d').strftime('%Y%m%d')
  params['slide_interval_in_days'] = 1
  params['prediction_window_gap_in_days'] = 1
  params['prediction_window_size_in_days'] = 1
  ml_windowing_pipeline.run_prediction_pipeline(params)
  return 0

def cloud_function_main(event: Dict[Any, Any], unused_context=None) -> int:
  """Entry point for Cloud Function.

  Args:
    event: Input PubSub message. Must contain an attributes dict and data dict.
           attributes - Contains an optional topic_id to publish the results, as
                        well as the next_task id to trigger after the pipeline
                        has finished.
           data - Dict from prediction pipeline parameter to value. See the
                  flags in this file for a list of possible parameters.
    unused_context: Unused.
  Returns:
    0 on success, and non-zero otherwise.
  """
  # Extract the task parameters from the input PubSub message.
  task_params = json.loads(
      base64.b64decode(event['attributes']).decode('utf-8'))
  # Extract the pipeline parameters from the input PubSub message.
  params = json.loads(base64.b64decode(event['data']).decode('utf-8'))
  # Run the Prediction pipeline
  if run(params):
    return -1
  # Publish the results to the PubSub topic_id
  if 'topic_id' not in task_params:
    return 0
  publisher = pubsub_v1.PublisherClient()
  topic_path = publisher.topic_path(
      params['project_id'], task_params['topic_id'])
  data = {
      'projectId': params['project_id'],
      'datasetId': params['dataset_id'],
      'tableId': '{}.{}.features'.format(
          params['project_id'], params['dataset_id']),
      'partitionDay': datetime.datetime.strptime(
          params['snapshot_start_date'], '%Y-%m-%d').strftime('%Y%m%d')
  }
  data = json.dumps(data).encode('utf-8')
  future = publisher.publish(
      topic_path, data,
      topicId=task_params['topic_id'], taskId=task_params.get('next_task')
  )
  future.result()
  return 0

def main(_):
  params = FLAGS.flag_values_dict()
  return run(params)

if __name__ == '__main__':
  app.run(main)
<commit_msg>Remove cloud function logic from run_prediction_pipeline. Cloud Functions must be in a main.py file.<commit_after># python3
# coding=utf-8
# Copyright 2021 Google LLC.
#
# 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.

r"""Script to run the end-to-end ML Windowing Pipeline.

Before running this pipeline, first run the end-to-end windowing pipeline, and
then use the data to train an ML model. Once the model is deployed and you want
predictions about live customers, run this script to generate features for the
customers over a single window of data, and then input the features into the
ML model to get it's predictions.

Example Usage:

python run_prediction_pipeline.py \
--project_id=<PROJECT_ID> \
--dataset_id=<DATASET_ID> \
--analytics_table="bigquery-public-data.google_analytics_sample.ga_sessions_*" \
--snapshot_date_offset_in_days=1 \
--lookback_window_size_in_days=30 \
--lookback_window_gap_in_days=0 \
--categorical_fact_value_to_column_name_table=<BIGQUERY TABLE from training run>

python run_prediction_pipeline.py \
--project_id=<PROJECT_ID> \
--dataset_id=<DATASET_ID> \
--analytics_table="bigquery-public-data.google_analytics_sample.ga_sessions_*" \
--snapshot_date_offset_in_days=1 \
--lookback_window_size_in_days=30 \
--lookback_window_gap_in_days=0 \
--features_sql='features_from_input.sql' \
--sum_values='totals_visits;totals_hits' \
--avg_values='totals_visits;totals_hits' \
--count_values='geoNetwork_metro:[Providence-New Bedford///,MA",Rochester-Mason City-Austin///,IA]:[Others]' \
--mode_values='hits_eCommerceAction_action_type:[3]:[Others]' \
--proportions_values='channelGrouping:[Organic Search,Social,Direct,Referral,Paid Search,Affiliates]:[Others]' \
--latest_values='device_isMobile:[false,true]:[Others]'
"""

import datetime
from typing import Any, Dict

from absl import app
from absl import flags

from gps_building_blocks.ml.data_prep.ml_windowing_pipeline import ml_windowing_pipeline

FLAGS = flags.FLAGS

# GCP flags.
flags.DEFINE_string('project_id', None, 'Google Cloud project to run inside.')
flags.DEFINE_string('dataset_id', None, 'BigQuery dataset to write the output.')
flags.DEFINE_string('run_id', None,
                    'By default, all output tables have the snapshot_date '
                    'suffix. Use this flag to override the suffix which must '
                    'be compatible with BigQuery table naming requirements.')
# BigQuery input flags.
flags.DEFINE_string('analytics_table', None,
                    'Full BigQuery id of the Google Analytics/Firebase table.')
# Windowing flags.
# Either set the snapshot_date with a specific date or the
# snapshot_date_offset_in_days with a relative offset from today.
flags.DEFINE_string('snapshot_date', None,
                    'YYYY-MM-DD snapshot date to make predictions from.')
flags.DEFINE_integer('snapshot_date_offset_in_days', None,
                     'Number of days before today to set the snapshot_date.')
flags.DEFINE_string('timezone', 'UTC',
                    'Timezone for the Google Analytics Data, '
                    'e.g. "Australia/Sydney", or "+11:00"')
flags.DEFINE_integer('lookback_window_gap_in_days', None,
                     'The lookback window ends on (snapshot_ts - '
                     'lookback_window_gap_in_days) days. Sessions '
                     'outside the lookback window are ignored.',
                     lower_bound=0)
flags.DEFINE_integer('lookback_window_size_in_days', None,
                     'The lookback window starts on (snapshot_ts - '
                     'lookback_window_size_in_days - '
                     'lookback_window_gap_in_days) days. Sessions outside the '
                     'lookback window are ignored.',
                     lower_bound=0)

# Location of SQL templates that can be overridden by the user.
flags.DEFINE_string('conversions_sql', 'conversions_google_analytics.sql',
                    'Name of the conversion extraction SQL file in templates/.')
flags.DEFINE_string('sessions_sql', 'sessions_google_analytics.sql',
                    'Name of the session extraction SQL file in templates/.')
flags.DEFINE_string('windows_sql', 'sliding_windows.sql',
                    'Name of the windows extraction SQL file in templates/.')
flags.DEFINE_string('features_sql', 'automatic_features.sql',
                    'Name of the feature extraction SQL file in templates/.'
                    'Override default value with `features_from_input.sql` for '
                    'user-provided Feature Option configurations.')
# Feature options:
# Required flag only when using automatic_features.sql.
flags.DEFINE_string('categorical_fact_value_to_column_name_table', None,
                    'BigQuery table containing the fact (name, value) to '
                    'column name mapping from the model\'s training run using '
                    'automatic_features.sql.')
# Alternative feature extraction using command line flags.
flags.DEFINE_string('sum_values', '', 'Feature Options for Sum')
flags.DEFINE_string('avg_values', '', 'Feature Options for Average')
flags.DEFINE_string('count_values', '', 'Feature Options for Count')
flags.DEFINE_string('mode_values', '', 'Feature Options for Mode')
flags.DEFINE_string('proportions_values', '', 'Feature Options for Proportion')
flags.DEFINE_string('latest_values', '', 'Feature Options for Recent')
# Debug flag.
flags.DEFINE_bool('verbose', False, 'Debug logging.')

def run(params: Dict[str, Any]) -> int:
  """Sets default flag values and runs the features pipeline.

  Side-effect: Updates params with additional normalized parameters.

  Args:
    params: Mapping of pipeline string parameter names to values.
  Returns:
    0 on success and non-zero otherwise.
  Raises:
    ValueError: User formatted message on error.
  """
  if params.get('snapshot_date') and params.get('snapshot_date_offset_in_days'):
    raise ValueError(
        'Specify either snapshot_date or snapshot_date_offset_in_days.')
  elif params.get('snapshot_date'):
    params['snapshot_start_date'] = params['snapshot_date']
    params['snapshot_end_date'] = params['snapshot_date']
  elif params.get('snapshot_date_offset_in_days'):
    offset_days = int(params['snapshot_date_offset_in_days'])
    end_date = (datetime.date.today() - datetime.timedelta(days=offset_days))
    params['snapshot_start_date'] = end_date.strftime('%Y-%m-%d')
    params['snapshot_end_date'] = end_date.strftime('%Y-%m-%d')
  else:
    raise ValueError('Set snapshot_date or snapshot_date_offset_in_days.')
  if not params.get('run_id'):
    params['run_id'] = datetime.datetime.strptime(
        params['snapshot_end_date'], '%Y-%m-%d').strftime('%Y%m%d')
  params['slide_interval_in_days'] = 1
  params['prediction_window_gap_in_days'] = 1
  params['prediction_window_size_in_days'] = 1
  ml_windowing_pipeline.run_prediction_pipeline(params)
  return 0

def main(_):
  params = FLAGS.flag_values_dict()
  return run(params)

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


<commit_before>from flask import Flask, request, jsonify, send_from_directory
import os
import uuid
app = Flask(__name__)
UPLOAD_FOLDER = "uploads/"

@app.route("/")
def index():
    return send_from_directory('static/', 'index.html')

@app.route("/<path:path>")
def serve_static_files():
    return send_from_directory('static/', path)

@app.route("/sounds")
def get_sounds_list():
    if not os.path.isdir(UPLOAD_FOLDER):
        os.mkdir(UPLOAD_FOLDER)
    sounds = os.listdir(UPLOAD_FOLDER)
    return jsonify({'sounds': sounds})

@app.route("/sounds/<path:path>")
def serve_static(path):
    return send_from_directory(UPLOAD_FOLDER, path)

@app.route("/upload", methods=["POST"])
def upload_file():
    file = request.files["sound"]
    if file:
        if not os.path.isdir(UPLOAD_FOLDER):
            os.mkdir(UPLOAD_FOLDER)
        filename = uuid.uuid4().__str__()

        file.save(os.path.join(UPLOAD_FOLDER, filename))
        return filename + "\n"

if __name__ == "__main__":
    app.run(host = "0.0.0.0", debug=True)
<commit_msg>Hotfix: fix broken index page<commit_after>from flask import Flask, request, jsonify, send_from_directory
import os
import uuid
app = Flask(__name__)
UPLOAD_FOLDER = "uploads/"

@app.route("/")
def index():
    return send_from_directory('static/', 'index.html')

@app.route("/<path:path>")
def serve_static_files(path):
    return send_from_directory('static/', path)

@app.route("/sounds")
def get_sounds_list():
    if not os.path.isdir(UPLOAD_FOLDER):
        os.mkdir(UPLOAD_FOLDER)
    sounds = os.listdir(UPLOAD_FOLDER)
    return jsonify({'sounds': sounds})

@app.route("/sounds/<path:path>")
def serve_static(path):
    return send_from_directory(UPLOAD_FOLDER, path)

@app.route("/upload", methods=["POST"])
def upload_file():
    file = request.files["sound"]
    if file:
        if not os.path.isdir(UPLOAD_FOLDER):
            os.mkdir(UPLOAD_FOLDER)
        filename = uuid.uuid4().__str__()

        file.save(os.path.join(UPLOAD_FOLDER, filename))
        return filename + "\n"

if __name__ == "__main__":
    app.run(host = "0.0.0.0", debug=True)
<|endoftext|>


<commit_before>__author__ = 'boye'

from boye import Spotify
from flask import Flask, url_for, redirect, render_template

app = Flask(__name__)

@app.route('/')
@app.route('/playlist')
@app.route('/playlist/<uri>')
def home(uri='spotify:user:pumazz:playlist:2e3fd32clPYmADf809LrM6'):

    playlist = spotify.get_playlist(uri)

    if spotify.Queue.has_next():
        current = spotify.Queue.get_current()['track'].name
        return render_template('playlist.html', now_playing=current, playlist=playlist)

    return render_template('playlist.html', playlist=playlist)

@app.route('/queue/<uri>')
def add_queue(uri):
    spotify.Queue.add_queue(uri)
    return redirect(url_for('home'))

@app.route('/next/<uri>')
def add_next(uri):
    spotify.Queue.add_next(uri)
    return redirect(url_for('home'))

@app.route('/now/<uri>')
def play_now(uri):
    spotify.Queue.add_next(uri)
    spotify.Player.play_next()
    return redirect(url_for('home'))

@app.route('/play')
def play():
    if not spotify.Player.is_loaded():
        spotify.Player.restart()
    else:
        spotify.Player.play()
    return redirect(url_for('home'))

@app.route('/pause')
def pause():
    if spotify.Player.is_loaded():
        spotify.Player.pause()
    return redirect(url_for('home'))

if __name__ == '__main__':
    spotify = Spotify()
    app.run(debug=True, host='0.0.0.0')<commit_msg>changed port<commit_after>__author__ = 'boye'

from boye import Spotify
from flask import Flask, url_for, redirect, render_template

app = Flask(__name__)

@app.route('/')
@app.route('/playlist')
@app.route('/playlist/<uri>')
def home(uri='spotify:user:pumazz:playlist:2e3fd32clPYmADf809LrM6'):

    playlist = spotify.get_playlist(uri)

    if spotify.Queue.has_next():
        current = spotify.Queue.get_current()['track'].name
        return render_template('playlist.html', now_playing=current, playlist=playlist)

    return render_template('playlist.html', playlist=playlist)

@app.route('/queue/<uri>')
def add_queue(uri):
    spotify.Queue.add_queue(uri)
    return redirect(url_for('home'))

@app.route('/next/<uri>')
def add_next(uri):
    spotify.Queue.add_next(uri)
    return redirect(url_for('home'))

@app.route('/now/<uri>')
def play_now(uri):
    spotify.Queue.add_next(uri)
    spotify.Player.play_next()
    return redirect(url_for('home'))

@app.route('/play')
def play():
    if not spotify.Player.is_loaded():
        spotify.Player.restart()
    else:
        spotify.Player.play()
    return redirect(url_for('home'))

@app.route('/pause')
def pause():
    if spotify.Player.is_loaded():
        spotify.Player.pause()
    return redirect(url_for('home'))

if __name__ == '__main__':
    spotify = Spotify()
    app.run(debug=True, host='0.0.0.0', port=80)<|endoftext|>


<commit_before>'''
SDL Window: Windowing provider directly based on our own wrapped version of SDL
'''

__all__ = ('WindowSDL', )

from kivy.core.window import WindowBase
from kivy.base import EventLoop, ExceptionManager, stopTouchApp
from kivy.config import Config
import os
import sys

try:
    from kivy.core import sdl
except:
    Logger.warning('WinPygame: SDL wrapper failed to import!')
    raise

class WindowSDL(WindowBase):

    def create_window(self):
        params = self.params

        # force display to show (available only for fullscreen)
        displayidx = Config.getint('graphics', 'display')
        if not 'SDL_VIDEO_FULLSCREEN_HEAD' in os.environ and displayidx != -1:
            os.environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx

        if params['position'] == 'auto':
            self._pos = None
        elif params['position'] == 'custom':
            self._pos = params['left'], params['top']
        else:
            raise ValueError('position token in configuration accept only '
                             '"auto" or "custom"')

        use_fake = False
        use_fullscreen = False
        self._fullscreenmode = params['fullscreen']
        if self._fullscreenmode == 'fake':
            Logger.debug('WinPygame: Set window to fake fullscreen mode')
            use_fake = True
            # if no position set, in fake mode, we always need to set the
            # position. so replace 0, 0.
            if self._pos is None:
                self._pos = (0, 0)
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos

        elif self._fullscreenmode:
            Logger.debug('WinPygame: Set window to fullscreen mode')
            use_fullscreen = True

        elif self._pos is not None:
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos

        # never stay with a None pos, application using w.center will be fired.
        self._pos = (0, 0)

        '''
        # prepare keyboard
        repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay'))
        repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate'))
        pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate))

        # set window icon before calling set_mode
        filename_icon = Config.get('kivy', 'window_icon')
        self.set_icon(filename_icon)
        '''

        # init ourself size + setmode
        # before calling on_resize
        self._size = params['width'], params['height']

        # setup !
        w, h = self._size
        sdl.setup_window(w, h, use_fake, use_fullscreen)

        super(WindowSDL, self).create_window()

        '''
        # set mouse visibility
        pygame.mouse.set_visible(
            Config.getboolean('graphics', 'show_cursor'))
        '''

        # set rotation
        self.rotation = params['rotation']

    def close(self):
        sdl.teardown_window()
        self.dispatch('on_close')

    def set_title(self, title):
        return
        pygame.display.set_caption(title)

    def set_icon(self, filename):
        return
        try:
            if not exists(filename):
                return False
            icon = pygame.image.load(filename)
            pygame.display.set_icon(icon)
        except:
            Logger.exception('WinPygame: unable to set icon')

    def screenshot(self, *largs, **kwargs):
        return
        filename = super(WindowPygame, self).screenshot(*largs, **kwargs)
        if filename is None:
            return None
        from kivy.core.gl import glReadPixels, GL_RGB, GL_UNSIGNED_BYTE
        width, height = self.size
        data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
        data = str(buffer(data))
        surface = pygame.image.fromstring(data, self.size, 'RGB', True)
        pygame.image.save(surface, filename)
        Logger.debug('Window: Screenshot saved at <%s>' % filename)
        return filename

    def on_keyboard(self, key, scancode=None, unicode=None, modifier=None):
        return
        # Quit if user presses ESC or the typical OSX shortcuts CMD+q or CMD+w
        # TODO If just CMD+w is pressed, only the window should be closed.
        is_osx = sys.platform == 'darwin'
        if key == 27 or (is_osx and key in (113, 119) and modifier == 1024):
            stopTouchApp()
            self.close()  #not sure what to do here
            return True
        super(WindowPygame, self).on_keyboard(key, scancode, unicode, modifier)

    def flip(self):
        sdl.flip()
        super(WindowSDL, self).flip()

    def _mainloop(self):
        EventLoop.idle()

        while True:
            event = sdl.poll()
            if event is False:
                break
            if event is None:
                continue

            print 'sdl receive', event
            action, args = event[0], event[1:]
            if action == 'quit':
                EventLoop.quit = True
                self.close()
                break

            if action == 'mousemotion':
                x, y = args
                self.dispatch('on_mouse_move', x, y, self.modifiers)

            elif action in ('mousebuttondown', 'mousebuttonup'):
                x, y, button = args
                btn = 'left'
                if button == 3:
                    btn = 'right'
                elif button == 2:
                    btn = 'middle'
                eventname = 'on_mouse_down'
                if action == 'mousebuttonup':
                    eventname = 'on_mouse_up'
                self.dispatch(eventname, x, y, btn, self.modifiers)

            # video resize
            elif action == 'windowresized':
                self._size = args
                # don't use trigger here, we want to delay the resize event
                cb = self._do_resize
                Clock.unschedule(cb)
                Clock.schedule_once(cb, .1)

            elif action == 'windowresized':
                 self.canvas.ask_update()

            elif action in ('keydown', 'keyup'):
                mod, key, scancode, unicode = args
                self._pygame_update_modifiers(mod)
                if action == 'keyup':
                    self.dispatch('on_key_up', key, scancode)
                    continue

                # don't dispatch more key if down event is accepted
                if self.dispatch('on_key_down', key,
                                 scancode, unicode,
                                 self.modifiers):
                    continue
                self.dispatch('on_keyboard', key,
                              scancode, unicode,
                              self.modifiers)

            elif action == 'textinput':
                self.dispatch('on_keyboard', None, None, args[0],
                              self.modifiers)
        #    # video resize
        #    elif event.type == pygame.VIDEORESIZE:
        #        self._size = event.size
        #        # don't use trigger here, we want to delay the resize event
        #        cb = self._do_resize
        #        Clock.unschedule(cb)
        #        Clock.schedule_once(cb, .1)

        #    elif event.type == pygame.VIDEOEXPOSE:
        #        self.canvas.ask_update()

        #    # ignored event
        #    elif event.type == pygame.ACTIVEEVENT:
        #        pass

        #    # unhandled event !
        #    else:
        #        Logger.debug('WinPygame: Unhandled event %s' % str(event))

    def _do_resize(self, dt):
        Logger.debug('Window: Resize window to %s' % str(self._size))
        sdl.resize_window(*self._size)
        self.dispatch('on_resize', *self._size)

    def mainloop(self):
        # don't known why, but pygame required a resize event
        # for opengl, before mainloop... window reinit ?
        self.dispatch('on_resize', *self.size)

        while not EventLoop.quit and EventLoop.status == 'started':
            try:
                self._mainloop()
            except BaseException, inst:
                # use exception manager first
                r = ExceptionManager.handle_exception(inst)
                if r == ExceptionManager.RAISE:
                    stopTouchApp()
                    raise
                else:
                    pass

        # force deletion of window
        sdl.teardown_window()

    #
    # Pygame wrapper
    #
    def _pygame_update_modifiers(self, mods=None):
        return
        # Available mod, from dir(pygame)
        # 'KMOD_ALT', 'KMOD_CAPS', 'KMOD_CTRL', 'KMOD_LALT',
        # 'KMOD_LCTRL', 'KMOD_LMETA', 'KMOD_LSHIFT', 'KMOD_META',
        # 'KMOD_MODE', 'KMOD_NONE'
        if mods is None:
            mods = pygame.key.get_mods()
        self._modifiers = []
        if mods & (pygame.KMOD_SHIFT | pygame.KMOD_LSHIFT):
            self._modifiers.append('shift')
        if mods & (pygame.KMOD_ALT | pygame.KMOD_LALT):
            self._modifiers.append('alt')
        if mods & (pygame.KMOD_CTRL | pygame.KMOD_LCTRL):
            self._modifiers.append('ctrl')
        if mods & (pygame.KMOD_META | pygame.KMOD_LMETA):
            self._modifiers.append('meta')

    def on_keyboard(self, key, scancode=None, unicode=None, modifier=None):
        # Quit if user presses ESC or the typical OSX shortcuts CMD+q or CMD+w
        # TODO If just CMD+w is pressed, only the window should be closed.
        is_osx = sys.platform == 'darwin'
        if key == 27 or (is_osx and key in (113, 119) and modifier == 1024):
            stopTouchApp()
            self.close()  #not sure what to do here
            return True
        super(WindowSDL, self).on_keyboard(key, scancode, unicode, modifier)
<commit_msg>sdl: add missing import<commit_after>'''
SDL Window: Windowing provider directly based on our own wrapped version of SDL
'''

__all__ = ('WindowSDL', )

from kivy.logger import Logger
from kivy.core.window import WindowBase
from kivy.base import EventLoop, ExceptionManager, stopTouchApp
from kivy.config import Config
import os
import sys

try:
    from kivy.core import sdl
except:
    Logger.warning('WinPygame: SDL wrapper failed to import!')
    raise

class WindowSDL(WindowBase):

    def create_window(self):
        params = self.params

        # force display to show (available only for fullscreen)
        displayidx = Config.getint('graphics', 'display')
        if not 'SDL_VIDEO_FULLSCREEN_HEAD' in os.environ and displayidx != -1:
            os.environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx

        if params['position'] == 'auto':
            self._pos = None
        elif params['position'] == 'custom':
            self._pos = params['left'], params['top']
        else:
            raise ValueError('position token in configuration accept only '
                             '"auto" or "custom"')

        use_fake = False
        use_fullscreen = False
        self._fullscreenmode = params['fullscreen']
        if self._fullscreenmode == 'fake':
            Logger.debug('WinPygame: Set window to fake fullscreen mode')
            use_fake = True
            # if no position set, in fake mode, we always need to set the
            # position. so replace 0, 0.
            if self._pos is None:
                self._pos = (0, 0)
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos

        elif self._fullscreenmode:
            Logger.debug('WinPygame: Set window to fullscreen mode')
            use_fullscreen = True

        elif self._pos is not None:
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos

        # never stay with a None pos, application using w.center will be fired.
        self._pos = (0, 0)

        '''
        # prepare keyboard
        repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay'))
        repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate'))
        pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate))

        # set window icon before calling set_mode
        filename_icon = Config.get('kivy', 'window_icon')
        self.set_icon(filename_icon)
        '''

        # init ourself size + setmode
        # before calling on_resize
        self._size = params['width'], params['height']

        # setup !
        w, h = self._size
        sdl.setup_window(w, h, use_fake, use_fullscreen)

        super(WindowSDL, self).create_window()

        '''
        # set mouse visibility
        pygame.mouse.set_visible(
            Config.getboolean('graphics', 'show_cursor'))
        '''

        # set rotation
        self.rotation = params['rotation']

    def close(self):
        sdl.teardown_window()
        self.dispatch('on_close')

    def set_title(self, title):
        return
        pygame.display.set_caption(title)

    def set_icon(self, filename):
        return
        try:
            if not exists(filename):
                return False
            icon = pygame.image.load(filename)
            pygame.display.set_icon(icon)
        except:
            Logger.exception('WinPygame: unable to set icon')

    def screenshot(self, *largs, **kwargs):
        return
        filename = super(WindowPygame, self).screenshot(*largs, **kwargs)
        if filename is None:
            return None
        from kivy.core.gl import glReadPixels, GL_RGB, GL_UNSIGNED_BYTE
        width, height = self.size
        data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
        data = str(buffer(data))
        surface = pygame.image.fromstring(data, self.size, 'RGB', True)
        pygame.image.save(surface, filename)
        Logger.debug('Window: Screenshot saved at <%s>' % filename)
        return filename

    def on_keyboard(self, key, scancode=None, unicode=None, modifier=None):
        return
        # Quit if user presses ESC or the typical OSX shortcuts CMD+q or CMD+w
        # TODO If just CMD+w is pressed, only the window should be closed.
        is_osx = sys.platform == 'darwin'
        if key == 27 or (is_osx and key in (113, 119) and modifier == 1024):
            stopTouchApp()
            self.close()  #not sure what to do here
            return True
        super(WindowPygame, self).on_keyboard(key, scancode, unicode, modifier)

    def flip(self):
        sdl.flip()
        super(WindowSDL, self).flip()

    def _mainloop(self):
        EventLoop.idle()

        while True:
            event = sdl.poll()
            if event is False:
                break
            if event is None:
                continue

            print 'sdl receive', event
            action, args = event[0], event[1:]
            if action == 'quit':
                EventLoop.quit = True
                self.close()
                break

            if action == 'mousemotion':
                x, y = args
                self.dispatch('on_mouse_move', x, y, self.modifiers)

            elif action in ('mousebuttondown', 'mousebuttonup'):
                x, y, button = args
                btn = 'left'
                if button == 3:
                    btn = 'right'
                elif button == 2:
                    btn = 'middle'
                eventname = 'on_mouse_down'
                if action == 'mousebuttonup':
                    eventname = 'on_mouse_up'
                self.dispatch(eventname, x, y, btn, self.modifiers)

            # video resize
            elif action == 'windowresized':
                self._size = args
                # don't use trigger here, we want to delay the resize event
                cb = self._do_resize
                Clock.unschedule(cb)
                Clock.schedule_once(cb, .1)

            elif action == 'windowresized':
                 self.canvas.ask_update()

            elif action in ('keydown', 'keyup'):
                mod, key, scancode, unicode = args
                self._pygame_update_modifiers(mod)
                if action == 'keyup':
                    self.dispatch('on_key_up', key, scancode)
                    continue

                # don't dispatch more key if down event is accepted
                if self.dispatch('on_key_down', key,
                                 scancode, unicode,
                                 self.modifiers):
                    continue
                self.dispatch('on_keyboard', key,
                              scancode, unicode,
                              self.modifiers)

            elif action == 'textinput':
                self.dispatch('on_keyboard', None, None, args[0],
                              self.modifiers)
        #    # video resize
        #    elif event.type == pygame.VIDEORESIZE:
        #        self._size = event.size
        #        # don't use trigger here, we want to delay the resize event
        #        cb = self._do_resize
        #        Clock.unschedule(cb)
        #        Clock.schedule_once(cb, .1)

        #    elif event.type == pygame.VIDEOEXPOSE:
        #        self.canvas.ask_update()

        #    # ignored event
        #    elif event.type == pygame.ACTIVEEVENT:
        #        pass

        #    # unhandled event !
        #    else:
        #        Logger.debug('WinPygame: Unhandled event %s' % str(event))

    def _do_resize(self, dt):
        Logger.debug('Window: Resize window to %s' % str(self._size))
        sdl.resize_window(*self._size)
        self.dispatch('on_resize', *self._size)

    def mainloop(self):
        # don't known why, but pygame required a resize event
        # for opengl, before mainloop... window reinit ?
        self.dispatch('on_resize', *self.size)

        while not EventLoop.quit and EventLoop.status == 'started':
            try:
                self._mainloop()
            except BaseException, inst:
                # use exception manager first
                r = ExceptionManager.handle_exception(inst)
                if r == ExceptionManager.RAISE:
                    stopTouchApp()
                    raise
                else:
                    pass

        # force deletion of window
        sdl.teardown_window()

    #
    # Pygame wrapper
    #
    def _pygame_update_modifiers(self, mods=None):
        return
        # Available mod, from dir(pygame)
        # 'KMOD_ALT', 'KMOD_CAPS', 'KMOD_CTRL', 'KMOD_LALT',
        # 'KMOD_LCTRL', 'KMOD_LMETA', 'KMOD_LSHIFT', 'KMOD_META',
        # 'KMOD_MODE', 'KMOD_NONE'
        if mods is None:
            mods = pygame.key.get_mods()
        self._modifiers = []
        if mods & (pygame.KMOD_SHIFT | pygame.KMOD_LSHIFT):
            self._modifiers.append('shift')
        if mods & (pygame.KMOD_ALT | pygame.KMOD_LALT):
            self._modifiers.append('alt')
        if mods & (pygame.KMOD_CTRL | pygame.KMOD_LCTRL):
            self._modifiers.append('ctrl')
        if mods & (pygame.KMOD_META | pygame.KMOD_LMETA):
            self._modifiers.append('meta')

    def on_keyboard(self, key, scancode=None, unicode=None, modifier=None):
        # Quit if user presses ESC or the typical OSX shortcuts CMD+q or CMD+w
        # TODO If just CMD+w is pressed, only the window should be closed.
        is_osx = sys.platform == 'darwin'
        if key == 27 or (is_osx and key in (113, 119) and modifier == 1024):
            stopTouchApp()
            self.close()  #not sure what to do here
            return True
        super(WindowSDL, self).on_keyboard(key, scancode, unicode, modifier)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

import os
import re
import requests

from flask import Flask, Response, request, render_template, abort, jsonify
from bs4 import BeautifulSoup

from filters import support_jsonp, cached

app = Flask(__name__)
app.config.from_object('settings')

@app.errorhandler(404)
def page_not_found(error):
    return render_template('errors/404.html'), 404

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

@app.route('/poster/<file>')
def proxy_image(file):
    """ Proxy the image since IMDb doesn't allow direct linking """
    image = requests.get('http://ia.media-imdb.com/images/M/{}'.format(file))
    return Response(image.content, mimetype=image.headers['content-type'])

@app.route('/search/<id>/<int:width>/<int:height>')
@app.route('/search/<id>/<int:width>')
@app.route('/search/<id>')
@support_jsonp
@cached
def search(id, width=200, height=296):
    """ Fetches and scrapes a movie or tv show by imdb id """
    html = requests.get('http://www.imdb.com/title/{}/'.format(id))
    host = request.headers['Host']

    if not html.ok:
        abort(404)

    try:
        soup = BeautifulSoup(html.text, 'lxml')
    except:
        return jsonify(error='Error occured while parsing.')

    items = soup.find_all(itemprop=True)

    poster = soup.find(rel='image_src')['href']
    # Change poster size
    poster = re.sub(r'@@.+', '@@.SX{}_SY{}.jpg'.format(
        width, height), poster)
    poster = poster.rpartition('/')[2]
    poster = 'http://{}/poster/{}'.format(host, poster)

    title = list(items[1].strings)[0].strip()
    description = items[8].text.strip()
    vote_count = int(items[5].text.replace(',', ''))
    vote_average = float(items[3].text)

    year = soup.time['datetime']

    genres = []
    for g in soup.find_all(itemprop='genre'):
        genres.append(g.strings.next())

    return jsonify(poster=poster,
            title=title,
            release_date=year,
            overview=description,
            vote_count=vote_count,
            vote_average=vote_average,
            genres=genres)

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8000))
    app.run(host='0.0.0.0', port=port)
<commit_msg>Indentation fix.<commit_after># -*- coding: utf-8 -*-

import os
import re
import requests

from flask import Flask, Response, request, render_template, abort, jsonify
from bs4 import BeautifulSoup

from filters import support_jsonp, cached

app = Flask(__name__)
app.config.from_object('settings')

@app.errorhandler(404)
def page_not_found(error):
    return render_template('errors/404.html'), 404

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

@app.route('/poster/<file>')
def proxy_image(file):
    """ Proxy the image since IMDb doesn't allow direct linking """
    image = requests.get('http://ia.media-imdb.com/images/M/{}'.format(file))
    return Response(image.content, mimetype=image.headers['content-type'])

@app.route('/search/<id>/<int:width>/<int:height>')
@app.route('/search/<id>/<int:width>')
@app.route('/search/<id>')
@support_jsonp
@cached
def search(id, width=200, height=296):
    """ Fetches and scrapes a movie or tv show by imdb id """
    html = requests.get('http://www.imdb.com/title/{}/'.format(id))
    host = request.headers['Host']

    if not html.ok:
        abort(404)

    try:
        soup = BeautifulSoup(html.text, 'lxml')
    except:
        return jsonify(error='Error occured while parsing.')

    items = soup.find_all(itemprop=True)

    poster = soup.find(rel='image_src')['href']
    # Change poster size
    poster = re.sub(r'@@.+', '@@.SX{}_SY{}.jpg'.format(
        width, height), poster)
    poster = poster.rpartition('/')[2]
    poster = 'http://{}/poster/{}'.format(host, poster)

    title = list(items[1].strings)[0].strip()
    description = items[8].text.strip()
    vote_count = int(items[5].text.replace(',', ''))
    vote_average = float(items[3].text)

    year = soup.time['datetime']

    genres = []
    for g in soup.find_all(itemprop='genre'):
        genres.append(g.strings.next())

    return jsonify(poster=poster,
                   title=title,
                   release_date=year,
                   overview=description,
                   vote_count=vote_count,
                   vote_average=vote_average,
                   genres=genres)

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


<commit_before>def string2object(message, data):
    splitted = data.split()
    _get_headers_from_list(message, splitted[:len(message.header)], message.header)
    _get_ies_from_list(message,splitted[len(message.header):])
    print message.header
    print message.ie

def _get_headers_from_list(message, all_headers, headers_schema):
    print all_headers
    print headers_schema
    header_tmp = []
    header_tmp += [[str(headers_schema[i]), all_headers[i]] for i in range(len(headers_schema))]
    message.header = header_tmp

def _get_ies_from_list(message, splitted):
    ie_tmp = []
    ie_tmp += [[splitted[i][:-1], splitted[i+1]] for i in range(0,len(splitted),2)]
    message.ie = ie_tmp<commit_msg>removed some debug prints<commit_after>def string2object(message, data):
    splitted = data.split()
    _get_headers_from_list(message, splitted[:len(message.header)], message.header)
    _get_ies_from_list(message,splitted[len(message.header):])

def _get_headers_from_list(message, all_headers, headers_schema):
    header_tmp = []
    header_tmp += [[str(headers_schema[i]), all_headers[i]] for i in range(len(headers_schema))]
    message.header = header_tmp

def _get_ies_from_list(message, splitted):
    ie_tmp = []
    ie_tmp += [[splitted[i][:-1], splitted[i+1]] for i in range(0,len(splitted),2)]
    message.ie = ie_tmp<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#  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
#
#       https://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.

from __future__ import unicode_literals

import os
import sys
from argparse import ArgumentParser

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError, LineBotApiError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, ImageSendMessage
)

app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)

@app.route('/')
def hello():
    return 'Hello!'

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    print(body)

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    # if event is MessageEvent and message is TextMessage, then echo text
    for event in events:
        if not isinstance(event, MessageEvent):
            continue
        if not isinstance(event.message, TextMessage):
            continue

        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=event.message.text)
        )

    return 'OK'

#@app.route("/sendEternity", methods=['POST'])
#def sendEternity():
#
#
#    try:
#        line_bot_api.push_message('<to>', TextSendMessage(text='Hello World!'))
#    except LineBotApiError as e:
#        abort(400)
#{
#    "type": "image",
#    "originalContentUrl": "https://www.dropbox.com/s/1voyd04049xt6up/S__75849824.jpg",
#    "previewImageUrl": "https://www.dropbox.com/s/1voyd04049xt6up/S__75849824.jpg"
#}
#
#
#
#    return 'OK'

if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
    )
    arg_parser.add_argument('-p', '--port', default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()

    app.run(debug=options.debug, port=options.port)
<commit_msg>Test push message to group<commit_after># -*- coding: utf-8 -*-

#  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
#
#       https://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.

from __future__ import unicode_literals

import os
import sys
from argparse import ArgumentParser

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError, LineBotApiError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, ImageSendMessage
)

app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

my_group_id = os.getenv('GROUP_ID', None)
if my_group_id is None:
    print('GROUP_ID as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)

@app.route('/')
def hello():
    return 'Hello!'

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    print(body)

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    # if event is MessageEvent and message is TextMessage, then echo text
    for event in events:
        if not isinstance(event, MessageEvent):
            continue
        if not isinstance(event.message, TextMessage):
            continue

        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=event.message.text)
        )

    return 'OK'

@app.route("/sendEternity", methods=['POST'])
def sendEternity():

    try:
        #I just want my group to receive msg
        line_bot_api.push_message(my_group_id, TextSendMessage(text='Hello World!'))
    except LineBotApiError as e:
        abort(400)
#{
#    "type": "image",
#    "originalContentUrl": "https://www.dropbox.com/s/1voyd04049xt6up/S__75849824.jpg",
#    "previewImageUrl": "https://www.dropbox.com/s/1voyd04049xt6up/S__75849824.jpg"
#}

    return 'OK'

if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
    )
    arg_parser.add_argument('-p', '--port', default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()

    app.run(debug=options.debug, port=options.port)
<|endoftext|>


<commit_before># coding: utf-8

import urllib3
import gzip
import json
import StringIO
import telegram

from flask import Flask
from flask import render_template, request

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

app = Flask(__name__)

bot = telegram.Bot(token='288756371:AAGwm08t-JlqF161zkBj_75syb56zqd16pM')

@app.route("/")
def hello():
    return "Hello! Welcome to yuchen's Home"

# telegram yctpebusbot
@app.route("/bot/tpebus", methods=['POST'])
def botHook_tpebus():
    try:
        update = telegram.Update.de_json(request.get_json(force=True), bot)
        print update
        message = update.message
        text = u'您剛剛輸入的指令是：' + message.text
        bot.sendMessage(chat_id=message.chat.id, text=str(update))
        return 'ok'
    except Exception as e:
        print e

@app.route("/youbike")
def youbike():
    # configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'})
    url = "http://data.taipei/youbike"
    data = send_request(url)
    bikeDict = json.loads(data)
    return data #  bikeDict['retVal']

@app.route("/bus/route")
def busroute():
    try:
        url = "http://data.taipei/bus/ROUTE"
        data = send_request(url, compress=True)
        routeDict = json.loads(data)
        return data #  bikeDict['retVal']
    except Exception as e:
        print e

def send_request(url, compress = False):
    urllib3.disable_warnings()
    http = urllib3.PoolManager()
    r = http.request('GET', url, preload_content=False)
    if compress:
        data = decompressGzip(r.read())
    else:
        data = r.read()

    r.release_conn()
    return data

def decompressGzip(compressStr):
    compressedStram = StringIO.StringIO()
    compressedStram.write(compressStr)
    compressedStram.seek(0)
    decompressedStream = gzip.GzipFile(fileobj=compressedStram, mode='rb')
    result = decompressedStream.read()
    return result

if __name__ == "__main__":
    app.run()<commit_msg>finish test send message<commit_after># coding: utf-8

import urllib3
import gzip
import json
import StringIO
import telegram

from flask import Flask
from flask import render_template, request

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

app = Flask(__name__)

bot = telegram.Bot(token='288756371:AAGwm08t-JlqF161zkBj_75syb56zqd16pM')

@app.route("/")
def hello():
    return "Hello! Welcome to yuchen's Home"

# telegram yctpebusbot
@app.route("/bot/tpebus", methods=['POST'])
def botHook_tpebus():
    try:
        update = telegram.Update.de_json(request.get_json(force=True), bot)
        print update
        message = update.message
        text = u'您剛剛輸入的指令是：' + message.text
        bot.sendMessage(chat_id=message.chat.id, text=text)
        return 'ok'
    except Exception as e:
        print e

@app.route("/youbike")
def youbike():
    # configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'})
    url = "http://data.taipei/youbike"
    data = send_request(url)
    bikeDict = json.loads(data)
    return data #  bikeDict['retVal']

@app.route("/bus/route")
def busroute():
    try:
        url = "http://data.taipei/bus/ROUTE"
        data = send_request(url, compress=True)
        routeDict = json.loads(data)
        return data #  bikeDict['retVal']
    except Exception as e:
        print e

def send_request(url, compress = False):
    urllib3.disable_warnings()
    http = urllib3.PoolManager()
    r = http.request('GET', url, preload_content=False)
    if compress:
        data = decompressGzip(r.read())
    else:
        data = r.read()

    r.release_conn()
    return data

def decompressGzip(compressStr):
    compressedStram = StringIO.StringIO()
    compressedStram.write(compressStr)
    compressedStram.seek(0)
    decompressedStream = gzip.GzipFile(fileobj=compressedStram, mode='rb')
    result = decompressedStream.read()
    return result

if __name__ == "__main__":
    app.run()<|endoftext|>


<commit_before>import os
from flask import Flask, redirect, render_template, abort, request
from functools import wraps
from flask.ext.assets import Environment, Bundle
from flask.ext.basicauth import BasicAuth
import logging
from raven.contrib.flask import Sentry
from flask import jsonify
import forms
import string
import json
import requests
import geojson
from utils import geo

TITLES_SCHEME_DOMAIN_PORT = os.environ.get('TITLES_SCHEME_DOMAIN_PORT', os.environ.get('TITLES_1_PORT_8004_TCP', '').replace('tcp://', 'http://'))
GEO_SCHEME_DOMAIN_PORT = os.environ.get('GEO_SCHEME_DOMAIN_PORT', os.environ.get('GEO_1_PORT_8005_TCP', '').replace('tcp://', 'http://'))

app = Flask(__name__)

# Auth
if os.environ.get('BASIC_AUTH_USERNAME'):
    app.config['BASIC_AUTH_USERNAME'] = os.environ['BASIC_AUTH_USERNAME']
    app.config['BASIC_AUTH_PASSWORD'] = os.environ['BASIC_AUTH_PASSWORD']
    app.config['BASIC_AUTH_FORCE'] = True
    basic_auth = BasicAuth(app)

# Static assets
assets = Environment(app)
css_main = Bundle(
    'stylesheets/main.scss',
    filters='scss',
    output='build/stylesheets/main.css',
    depends="**/*.scss"
)
assets.register('css_main', css_main)

# Sentry exception reporting
if 'SENTRY_DSN' in os.environ:
    sentry = Sentry(app, dsn=os.environ['SENTRY_DSN'])

def load_title(property_id):
    res = requests.get("%s/titles/%s" % (TITLES_SCHEME_DOMAIN_PORT, property_id))
    if res.status_code == 404:
        return None
    return res.json()

# Logging
@app.before_first_request
def setup_logging():
    if not app.debug:
        app.logger.addHandler(logging.StreamHandler())
        app.logger.setLevel(logging.INFO)

@app.route('/')
def home():
    form = forms.SearchForm()

    res = requests.get("%s/titles" % TITLES_SCHEME_DOMAIN_PORT)
    res.raise_for_status()
    return render_template('/index.html', titles=res.json()['titles'], form=form)

@app.route('/properties/<property_id>')
def property(property_id):
    title_info = load_title(property_id)
    if title_info:
        title_extent_json = json.dumps(title_info['title'].get('extent', {}))
        return render_template("property.html",
            title=title_info['title'],
            title_extent_json=title_extent_json
        )
    else:
        return abort(404)

@app.route('/properties')
def properties():
    return "Request for all titles not supported", 403

@app.route('/search')
def search():

    search_term = None
    form = forms.SearchForm()
    titles = []
    latlng = False

    if 'q' in request.args:
        search_term = request.args['q']
        form.q.data = search_term

        #work out the type of search, they try and get a latlng for it
        if geo.is_postcode(search_term):
            latlng = geo.postcode_to_latlng(search_term)
        else:
            latlng = geo.geocode_place_name(search_term)

        #if we have a location, then do a search
        if latlng:

            #make a geojson point
            geojson_point = geojson.Point([latlng[1], latlng[0]], crs={"type": "name","properties": {"name": "EPSG:4326"}})

            #call the geo service -
            url = "%s/titles?near=%s" % (GEO_SCHEME_DOMAIN_PORT, geojson.dumps(geojson_point))
            res = requests.get(url)
            titles = res.json()['objects']

    return render_template('/search.html', titles=titles, form=form, search_term=search_term, latlng=latlng)

if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=8001)
<commit_msg>removed titles list<commit_after>import os
from flask import Flask, redirect, render_template, abort, request
from functools import wraps
from flask.ext.assets import Environment, Bundle
from flask.ext.basicauth import BasicAuth
import logging
from raven.contrib.flask import Sentry
from flask import jsonify
import forms
import string
import json
import requests
import geojson
from utils import geo

TITLES_SCHEME_DOMAIN_PORT = os.environ.get('TITLES_SCHEME_DOMAIN_PORT', os.environ.get('TITLES_1_PORT_8004_TCP', '').replace('tcp://', 'http://'))
GEO_SCHEME_DOMAIN_PORT = os.environ.get('GEO_SCHEME_DOMAIN_PORT', os.environ.get('GEO_1_PORT_8005_TCP', '').replace('tcp://', 'http://'))

app = Flask(__name__)

# Auth
if os.environ.get('BASIC_AUTH_USERNAME'):
    app.config['BASIC_AUTH_USERNAME'] = os.environ['BASIC_AUTH_USERNAME']
    app.config['BASIC_AUTH_PASSWORD'] = os.environ['BASIC_AUTH_PASSWORD']
    app.config['BASIC_AUTH_FORCE'] = True
    basic_auth = BasicAuth(app)

# Static assets
assets = Environment(app)
css_main = Bundle(
    'stylesheets/main.scss',
    filters='scss',
    output='build/stylesheets/main.css',
    depends="**/*.scss"
)
assets.register('css_main', css_main)

# Sentry exception reporting
if 'SENTRY_DSN' in os.environ:
    sentry = Sentry(app, dsn=os.environ['SENTRY_DSN'])

def load_title(property_id):
    res = requests.get("%s/titles/%s" % (TITLES_SCHEME_DOMAIN_PORT, property_id))
    if res.status_code == 404:
        return None
    return res.json()

# Logging
@app.before_first_request
def setup_logging():
    if not app.debug:
        app.logger.addHandler(logging.StreamHandler())
        app.logger.setLevel(logging.INFO)

@app.route('/')
def home():
    form = forms.SearchForm()
    return render_template('/index.html', form=form)

@app.route('/properties/<property_id>')
def property(property_id):
    title_info = load_title(property_id)
    if title_info:
        title_extent_json = json.dumps(title_info['title'].get('extent', {}))
        return render_template("property.html",
            title=title_info['title'],
            title_extent_json=title_extent_json
        )
    else:
        return abort(404)

@app.route('/properties')
def properties():
    return "Request for all titles not supported", 403

@app.route('/search')
def search():

    search_term = None
    form = forms.SearchForm()
    titles = []
    latlng = False

    if 'q' in request.args:
        search_term = request.args['q']
        form.q.data = search_term

        #work out the type of search, they try and get a latlng for it
        if geo.is_postcode(search_term):
            latlng = geo.postcode_to_latlng(search_term)
        else:
            latlng = geo.geocode_place_name(search_term)

        #if we have a location, then do a search
        if latlng:

            #make a geojson point
            geojson_point = geojson.Point([latlng[1], latlng[0]], crs={"type": "name","properties": {"name": "EPSG:4326"}})

            #call the geo service -
            url = "%s/titles?near=%s" % (GEO_SCHEME_DOMAIN_PORT, geojson.dumps(geojson_point))
            res = requests.get(url)
            titles = res.json()['objects']

    return render_template('/search.html', titles=titles, form=form, search_term=search_term, latlng=latlng)

if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=8001)
<|endoftext|>