<commit_before>import json
import requests
import threading
import aiotg
import asyncio
import logging
import mimetypes
import time
from urllib.parse import unquote, quote, urlparse, parse_qs
from aiohttp import web, ClientSession, MultipartWriter
from pprint import pprint
from bs4 import BeautifulSoup

try:
    with open('config.json', 'r') as f:
        config = json.load(f)

        HS_TOKEN = config['tokens']['hs']
        AS_TOKEN = config['tokens']['as']
        TG_TOKEN = config['tokens']['telegram']
        GOOGLE_TOKEN = config['tokens']['google']

        MATRIX_HOST = config['hosts']['internal']
        MATRIX_HOST_EXT = config['hosts']['external']

        MATRIX_PREFIX = MATRIX_HOST + '_matrix/client/r0/'
        MATRIX_MEDIA_PREFIX = MATRIX_HOST + '_matrix/media/r0/'

        USER_ID_FORMAT = config['user_id_format']

        telegram_chats = config['chats']
        matrix_rooms = {v: k for k, v in telegram_chats.items()}
except (OSError, IOError) as e:
    print('Error opening config file:')
    print(e)
    exit(1)

bot = aiotg.Bot(api_token=TG_TOKEN)
client_session = ClientSession()

def create_response(code, obj):
    return web.Response(text=json.dumps(obj), status=code, content_type='application/json', charset='utf-8')

VALID_TAGS = ['b', 'strong', 'i', 'em', 'a', 'pre']
def sanitize_html(h):
    h = h.replace('\n', '')
    h = h.replace('
', '\n').replace('
', '\n').replace('
', '\n')
    soup = BeautifulSoup(h, 'html.parser')
    for tag in soup.find_all(True):
        if tag.name == 'blockquote':
            tag.string = ('\n' + tag.text).replace('\n', '\n> ').rstrip('\n>')
        if tag.name not in VALID_TAGS:
            tag.hidden = True
    return soup.renderContents().decode('utf-8')

async def matrix_transaction(request):
    transaction = request.match_info['transaction']
    body = await request.json()

    events = body['events']
    for event in events:
        room_id = event['room_id']
        if room_id not in matrix_rooms:
            print('{} not in matrix_rooms!'.format(room_id))
        elif event['type'] == 'm.room.message':
            group = bot.group(matrix_rooms[room_id])

            username = event['user_id'].split(':')[0][1:]
            if username.startswith('telegram_'):
                return create_response(200, {})
            content = event['content']
            if content['msgtype'] == 'm.text':
                if 'formatted_body' in content:
                    await group.send_text('<{}> {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('<{}> {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.notice':
                if 'formatted_body' in content:
                    await group.send_text('[{}] {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('[{}] {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.emote':
                if 'formatted_body' in content:
                    await group.send_text('*** {} {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('*** {} {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.image':
                url = urlparse(content['url'])
                async with client_session.get(MATRIX_MEDIA_PREFIX + 'download/{}{}'.format(url.netloc, url.path)) as response:
                    b = await response.read()

                with open('/tmp/{}'.format(content['body']), 'wb') as f:
                    f.write(b)
                with open('/tmp/{}'.format(content['body']), 'rb') as f:
                    url_str = MATRIX_HOST_EXT + '_matrix/media/r0/download/{}{}'.format(url.netloc, quote(url.path))
                    async with ClientSession() as shorten_session:
                        async with shorten_session.post('https://www.googleapis.com/urlshortener/v1/url',
                                                        params={'key': GOOGLE_TOKEN},
                                                        data=json.dumps({'longUrl': url_str}),
                                                        headers={'Content-Type': 'application/json'}) as response:
                            j = await response.json()

                            if 'id' in j:
                                url_str = j['id']
                            else:
                                print('Something went wrong while shortening:')
                                pprint(j)

                    caption = '<{}> {} ({})'.format(username, content['body'], url_str)
                    await group.send_photo(f, caption=caption)
            else:
                print(json.dumps(content, indent=4))

    return create_response(200, {})

async def _matrix_request(method_fun, category, path, user_id, data=None, content_type=None):
    if data is not None:
        if isinstance(data, dict):
            data = json.dumps(data)
            content_type = 'application/json; charset=utf-8'
        elif content_type is None:
            content_type = 'application/octet-stream'

    params = {'access_token': AS_TOKEN}
    if user_id is not None:
        params['user_id'] = user_id

    async with method_fun('{}_matrix/{}/r0/{}'.format(MATRIX_HOST, quote(category), quote(path)),
                          params=params, data=data, headers={'Content-Type': content_type}) as response:
        if response.headers['Content-Type'].split(';')[0] == 'application/json':
            return await response.json()
        else:
            return await response.read()

def matrix_post(category, path, user_id, data, content_type=None):
    return _matrix_request(client_session.post, category, path, user_id, data, content_type)

def matrix_put(category, path, user_id, data, content_type=None):
    return _matrix_request(client_session.put, category, path, user_id, data, content_type)

def matrix_get(category, path, user_id):
    return _matrix_request(client_session.get, category, path, user_id)

def matrix_delete(category, path, user_id):
    return _matrix_request(client_session.delete, category, path, user_id)

async def matrix_room(request):
    room_alias = request.match_info['room_alias']
    args = parse_qs(urlparse(request.path_qs).query)
    print('Checking for {} | {}'.format(unquote(room_alias), args['access_token'][0]))

    try:
        if args['access_token'][0] != HS_TOKEN:
            return create_response(403, {'errcode': 'M_FORBIDDEN'})
    except KeyError:
        return create_response(401, {'errcode': 'NL.SIJMENSCHOON.TELEMATRIX_UNAUTHORIZED'})

    localpart, host = room_alias.split(':')
    chat = '_'.join(localpart.split('_')[1:])

    if chat in telegram_chats:
        await matrix_post('client', 'createRoom', None, {'room_alias_name': localpart[1:]})
        return create_response(200, {})
    else:
        return create_response(404, {'errcode': 'NL.SIJMENSCHOON.TELEMATRIX_NOT_FOUND'})

def send_matrix_message(room_id, user_id, txn_id, **kwargs):
    return matrix_put('client', 'rooms/{}/send/m.room.message/{}'.format(room_id, txn_id), user_id, kwargs)

async def upload_tgfile_to_matrix(file_id, user_id):
    file_path = (await bot.get_file(file_id))['file_path']
    request = await bot.download_file(file_path)
    mimetype = request.headers['Content-Type']

    data = await request.read()
    j = await matrix_post('media', 'upload', user_id, data, mimetype)

    if 'content_uri' in j:
        return (j['content_uri'], mimetype, len(data))
    else:
        return None, None, 0

async def register_join_matrix(chat, room_id, user_id):
    name = chat.sender['first_name']
    if 'last_name' in chat.sender:
        name += ' ' + chat.sender['last_name']
    name += ' (Telegram)'
    user = user_id.split(':')[0][1:]

    await matrix_post('client', 'register', None, {'type': 'm.login.application_service', 'user': user})
    profile_photos = await bot.get_user_profile_photos(chat.sender['id'])
    try:
        pp_file_id = profile_photos['result']['photos'][0][-1]['file_id']
        pp_uri, _, _ = await upload_tgfile_to_matrix(pp_file_id, user_id)
        if pp_uri:
            await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url': pp_uri})
    except IndexError:
        pass

    await matrix_put('client', 'profile/{}/displayname'.format(user_id), user_id, {'displayname': name})
    await matrix_post('client', 'join/{}'.format(room_id), user_id, {})

@bot.handle('photo')
async def aiotg_photo(chat, photo):
    try:
        room_id = telegram_chats[str(chat.id)]
    except KeyError:
        print('Unknown telegram chat {}'.format(chat))
        return

    user_id = USER_ID_FORMAT.format(chat.sender['id'])
    txn_id = quote('{}:{}'.format(chat.message['message_id'], chat.id))

    file_id = photo[-1]['file_id']
    uri, mime, length = await upload_tgfile_to_matrix(file_id, user_id)
    info = {'mimetype': mime, 'size': length, 'h': photo[-1]['height'], 'w': photo[-1]['width']}
    body = 'Image_{}{}'.format(int(time.time() * 1000), mimetypes.guess_extension(mime))

    if uri:
        j = await send_matrix_message(room_id, user_id, txn_id, body=body, url=uri, info=info, msgtype='m.image')
        if 'errcode' in j and j['errcode'] == 'M_FORBIDDEN':
            await register_join_matrix(chat, room_id, user_id)
            await send_matrix_message(room_id, user_id, txn_id, body=body, url=uri, info=info, msgtype='m.image')

@bot.command(r'(?s)(.*)')
async def aiotg_message(chat, match):
    try:
        room_id = telegram_chats[str(chat.id)]
    except KeyError:
        print('Unknown telegram chat {}'.format(chat))
        return

    user_id = USER_ID_FORMAT.format(chat.sender['id'])
    txn_id = quote('{}:{}'.format(chat.message['message_id'], chat.id))
    message = match.group(0)

    j = await send_matrix_message(room_id, user_id, txn_id, body=message, msgtype='m.text')
    if 'errcode' in j and j['errcode'] == 'M_FORBIDDEN':
        await asyncio.sleep(1)
        await register_join_matrix(chat, room_id, user_id)
        await asyncio.sleep(1)
        await send_matrix_message(room_id, user_id, txn_id, body=message, msgtype='m.text')

if __name__ == "__main__":
    logging.basicConfig(level=logging.WARNING)

    loop = asyncio.get_event_loop()
    asyncio.ensure_future(bot.loop())

    app = web.Application(loop=loop)
    app.router.add_route('GET', '/rooms/{room_alias}', matrix_room)
    app.router.add_route('PUT', '/transactions/{transaction}', matrix_transaction)
    web.run_app(app, port=5000)

<commit_msg>Support Tg forwards and replies<commit_after>import json
import requests
import threading
import aiotg
import asyncio
import logging
import mimetypes
import time
import html
import datetime
from urllib.parse import unquote, quote, urlparse, parse_qs
from aiohttp import web, ClientSession, MultipartWriter
from pprint import pprint
from bs4 import BeautifulSoup

try:
    with open('config.json', 'r') as f:
        config = json.load(f)

        HS_TOKEN = config['tokens']['hs']
        AS_TOKEN = config['tokens']['as']
        TG_TOKEN = config['tokens']['telegram']
        GOOGLE_TOKEN = config['tokens']['google']

        MATRIX_HOST = config['hosts']['internal']
        MATRIX_HOST_EXT = config['hosts']['external']

        MATRIX_PREFIX = MATRIX_HOST + '_matrix/client/r0/'
        MATRIX_MEDIA_PREFIX = MATRIX_HOST + '_matrix/media/r0/'

        USER_ID_FORMAT = config['user_id_format']

        telegram_chats = config['chats']
        matrix_rooms = {v: k for k, v in telegram_chats.items()}
except (OSError, IOError) as e:
    print('Error opening config file:')
    print(e)
    exit(1)

bot = aiotg.Bot(api_token=TG_TOKEN)
client_session = ClientSession()

def create_response(code, obj):
    return web.Response(text=json.dumps(obj), status=code, content_type='application/json', charset='utf-8')

VALID_TAGS = ['b', 'strong', 'i', 'em', 'a', 'pre']
def sanitize_html(h):
    h = h.replace('\n', '')
    h = h.replace('
', '\n').replace('
', '\n').replace('
', '\n')
    soup = BeautifulSoup(h, 'html.parser')
    for tag in soup.find_all(True):
        if tag.name == 'blockquote':
            tag.string = ('\n' + tag.text).replace('\n', '\n> ').rstrip('\n>')
        if tag.name not in VALID_TAGS:
            tag.hidden = True
    return soup.renderContents().decode('utf-8')

async def matrix_transaction(request):
    transaction = request.match_info['transaction']
    body = await request.json()

    events = body['events']
    for event in events:
        room_id = event['room_id']
        if room_id not in matrix_rooms:
            print('{} not in matrix_rooms!'.format(room_id))
        elif event['type'] == 'm.room.message':
            group = bot.group(matrix_rooms[room_id])

            username = event['user_id'].split(':')[0][1:]
            if username.startswith('telegram_'):
                return create_response(200, {})
            content = event['content']
            if content['msgtype'] == 'm.text':
                if 'formatted_body' in content:
                    await group.send_text('<{}> {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('<{}> {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.notice':
                if 'formatted_body' in content:
                    await group.send_text('[{}] {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('[{}] {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.emote':
                if 'formatted_body' in content:
                    await group.send_text('*** {} {}'.format(username, sanitize_html(content['formatted_body'])), parse_mode='HTML')
                else:
                    await group.send_text('*** {} {}'.format(username, content['body']))
            elif content['msgtype'] == 'm.image':
                url = urlparse(content['url'])
                async with client_session.get(MATRIX_MEDIA_PREFIX + 'download/{}{}'.format(url.netloc, url.path)) as response:
                    b = await response.read()

                with open('/tmp/{}'.format(content['body']), 'wb') as f:
                    f.write(b)
                with open('/tmp/{}'.format(content['body']), 'rb') as f:
                    url_str = MATRIX_HOST_EXT + '_matrix/media/r0/download/{}{}'.format(url.netloc, quote(url.path))
                    async with ClientSession() as shorten_session:
                        async with shorten_session.post('https://www.googleapis.com/urlshortener/v1/url',
                                                        params={'key': GOOGLE_TOKEN},
                                                        data=json.dumps({'longUrl': url_str}),
                                                        headers={'Content-Type': 'application/json'}) as response:
                            j = await response.json()

                            if 'id' in j:
                                url_str = j['id']
                            else:
                                print('Something went wrong while shortening:')
                                pprint(j)

                    caption = '<{}> {} ({})'.format(username, content['body'], url_str)
                    await group.send_photo(f, caption=caption)
            else:
                print(json.dumps(content, indent=4))

    return create_response(200, {})

async def _matrix_request(method_fun, category, path, user_id, data=None, content_type=None):
    if data is not None:
        if isinstance(data, dict):
            data = json.dumps(data)
            content_type = 'application/json; charset=utf-8'
        elif content_type is None:
            content_type = 'application/octet-stream'

    params = {'access_token': AS_TOKEN}
    if user_id is not None:
        params['user_id'] = user_id

    async with method_fun('{}_matrix/{}/r0/{}'.format(MATRIX_HOST, quote(category), quote(path)),
                          params=params, data=data, headers={'Content-Type': content_type}) as response:
        if response.headers['Content-Type'].split(';')[0] == 'application/json':
            return await response.json()
        else:
            return await response.read()

def matrix_post(category, path, user_id, data, content_type=None):
    return _matrix_request(client_session.post, category, path, user_id, data, content_type)

def matrix_put(category, path, user_id, data, content_type=None):
    return _matrix_request(client_session.put, category, path, user_id, data, content_type)

def matrix_get(category, path, user_id):
    return _matrix_request(client_session.get, category, path, user_id)

def matrix_delete(category, path, user_id):
    return _matrix_request(client_session.delete, category, path, user_id)

async def matrix_room(request):
    room_alias = request.match_info['room_alias']
    args = parse_qs(urlparse(request.path_qs).query)
    print('Checking for {} | {}'.format(unquote(room_alias), args['access_token'][0]))

    try:
        if args['access_token'][0] != HS_TOKEN:
            return create_response(403, {'errcode': 'M_FORBIDDEN'})
    except KeyError:
        return create_response(401, {'errcode': 'NL.SIJMENSCHOON.TELEMATRIX_UNAUTHORIZED'})

    localpart, host = room_alias.split(':')
    chat = '_'.join(localpart.split('_')[1:])

    if chat in telegram_chats:
        await matrix_post('client', 'createRoom', None, {'room_alias_name': localpart[1:]})
        return create_response(200, {})
    else:
        return create_response(404, {'errcode': 'NL.SIJMENSCHOON.TELEMATRIX_NOT_FOUND'})

def send_matrix_message(room_id, user_id, txn_id, **kwargs):
    return matrix_put('client', 'rooms/{}/send/m.room.message/{}'.format(room_id, txn_id), user_id, kwargs)

async def upload_tgfile_to_matrix(file_id, user_id):
    file_path = (await bot.get_file(file_id))['file_path']
    request = await bot.download_file(file_path)
    mimetype = request.headers['Content-Type']

    data = await request.read()
    j = await matrix_post('media', 'upload', user_id, data, mimetype)

    if 'content_uri' in j:
        return (j['content_uri'], mimetype, len(data))
    else:
        return None, None, 0

async def register_join_matrix(chat, room_id, user_id):
    name = chat.sender['first_name']
    if 'last_name' in chat.sender:
        name += ' ' + chat.sender['last_name']
    name += ' (Telegram)'
    user = user_id.split(':')[0][1:]

    await matrix_post('client', 'register', None, {'type': 'm.login.application_service', 'user': user})
    profile_photos = await bot.get_user_profile_photos(chat.sender['id'])
    try:
        pp_file_id = profile_photos['result']['photos'][0][-1]['file_id']
        pp_uri, _, _ = await upload_tgfile_to_matrix(pp_file_id, user_id)
        if pp_uri:
            await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url': pp_uri})
    except IndexError:
        pass

    await matrix_put('client', 'profile/{}/displayname'.format(user_id), user_id, {'displayname': name})
    await matrix_post('client', 'join/{}'.format(room_id), user_id, {})

@bot.handle('photo')
async def aiotg_photo(chat, photo):
    try:
        room_id = telegram_chats[str(chat.id)]
    except KeyError:
        print('Unknown telegram chat {}'.format(chat))
        return

    user_id = USER_ID_FORMAT.format(chat.sender['id'])
    txn_id = quote('{}:{}'.format(chat.message['message_id'], chat.id))

    file_id = photo[-1]['file_id']
    uri, mime, length = await upload_tgfile_to_matrix(file_id, user_id)
    info = {'mimetype': mime, 'size': length, 'h': photo[-1]['height'], 'w': photo[-1]['width']}
    body = 'Image_{}{}'.format(int(time.time() * 1000), mimetypes.guess_extension(mime))

    if uri:
        j = await send_matrix_message(room_id, user_id, txn_id, body=body, url=uri, info=info, msgtype='m.image')
        if 'errcode' in j and j['errcode'] == 'M_FORBIDDEN':
            await register_join_matrix(chat, room_id, user_id)
            await send_matrix_message(room_id, user_id, txn_id, body=body, url=uri, info=info, msgtype='m.image')

@bot.command(r'(?s)(.*)')
async def aiotg_message(chat, match):
    try:
        room_id = telegram_chats[str(chat.id)]
    except KeyError:
        print('Unknown telegram chat {}'.format(chat))
        return

    user_id = USER_ID_FORMAT.format(chat.sender['id'])
    txn_id = quote('{}:{}'.format(chat.message['message_id'], chat.id))

    message = match.group(0)
    if 'forward_from' in chat.message:
        fw_from = chat.message['forward_from']
        if 'last_name' in fw_from:
            msg_from = '{} {} (Telegram)'.format(fw_from['first_name'], fw_from['last_name'])
        else:
            msg_from = '{} (Telegram)'.format(fw_from['first_name'])
        date = datetime.datetime.fromtimestamp(fw_from['date'])

        quoted_msg = '\n'.join(['>{}'.format(x) for x in message.split('\n')])
        quoted_msg = 'Forwarded from {}, said at {}:\n{}'.format(msg_from, date, quoted_msg)

        quoted_html = '
{}
'.format(html.escape(message).replace('\n', '
'))
        quoted_html = 'Forwarded from {}, said at {}:\n{}'.format(html.escape(msg_from), html.escape(str(date)), quoted_html)
        j = await send_matrix_message(room_id, user_id, txn_id, body=quoted_msg, formatted_body=quoted_html, format='org.matrix.custom.html', msgtype='m.text')
    elif 'reply_to_message' in chat.message:
        re_msg = chat.message['reply_to_message']
        if 'last_name' in re_msg['from']:
            msg_from = '{} {} (Telegram)'.format(re_msg['from']['first_name'], re_msg['from']['last_name'])
        else:
            msg_from = '{} (Telegram)'.format(re_msg['from']['first_name'])
        date = datetime.datetime.fromtimestamp(re_msg['date'])

        quoted_msg = '\n'.join(['>{}'.format(x) for x in re_msg['text'].split('\n')])
        quoted_msg = 'Reply to {}, said at {}:\n{}\n\n{}'.format(msg_from, date, quoted_msg, message)

        quoted_html = '
{}
'.format(html.escape(re_msg['text']).replace('\n', '
'))
        quoted_html = 'Reply to {}, said at {}:
{}
{}
'.format(html.escape(msg_from), html.escape(str(date)), quoted_html, html.escape(message).replace('\n', '
'))

        j = await send_matrix_message(room_id, user_id, txn_id, body=quoted_msg, formatted_body=quoted_html, format='org.matrix.custom.html', msgtype='m.text')
    else:
        j = await send_matrix_message(room_id, user_id, txn_id, body=message, msgtype='m.text')

    if 'errcode' in j and j['errcode'] == 'M_FORBIDDEN':
        await asyncio.sleep(1)
        await register_join_matrix(chat, room_id, user_id)
        await asyncio.sleep(1)
        await send_matrix_message(room_id, user_id, txn_id, body=message, msgtype='m.text')

if __name__ == "__main__":
    logging.basicConfig(level=logging.WARNING)

    loop = asyncio.get_event_loop()
    asyncio.ensure_future(bot.loop())

    app = web.Application(loop=loop)
    app.router.add_route('GET', '/rooms/{room_alias}', matrix_room)
    app.router.add_route('PUT', '/transactions/{transaction}', matrix_transaction)
    web.run_app(app, port=5000)

<|endoftext|>


<commit_before>from src.app import app as application

if __name__ == '__main__':
    application.debug = True
    application.run()
<commit_msg>remove debug<commit_after>from src.app import app as application

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


<commit_before>from flask import Flask, render_template, request, flash
from upload import upload
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/mydatabase'
db = SQLAlchemy(app)
db.create_all()

@app.route('/upload', methods=['GET', 'POST'])
def load():
	if request.method == 'POST':
		doc_id = upload(request.form['filepath'])
		request_id = request.form['request_id']
		owner = Owner('anon', request_id)
		owner.doc_id = int(doc_id)
		db.session.add(owner)
		db.session.commit()
		return render_template('uploaded.html', doc_id = doc_id)
	else:
		return render_template('error.html')

@app.route('/request/<int:request_id>')
def show_request(request_id):
    # show the request with the given id, the id is an integer
    r = Request.query.get(request_id)
    doc_ids = []
    if r.owners:
    	for owner in r.owners:
    		doc_ids.append(owner.doc_id)
    return render_template('requested.html', text = r.text, request_id = request_id, doc_ids = doc_ids, status = r.status)

def make_request(str):
	req = Request(str)
	req.status = "Open"
	db.session.add(req)
	db.session.commit()
	return req.id

def change_request_status(id, status):
	try:
		req = Request.query.get(id)
		req.status = status
		db.session.commit()
		return True
	except:
		return False

def open_request(id):
	return change_request_status(id, "Open")

def close_request(id):
	return change_request_status(id, "Closed")

@app.route('/', methods=['GET', 'POST'])
def index():
	if request.method == 'POST':
		text = request.form['request_text']
		request_id = make_request(text)
		return show_request(request_id)
	else:
		return render_template('index.html')

@app.route('/requests', methods=['GET', 'POST'])
def requests():
	all_record_requests = Request.query.all()
	return render_template('requests.html', all_record_requests = all_record_requests)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return '<User %r>' % self.username

class Request(db.Model):
	__tablename__ = 'request'
	id = db.Column(db.Integer, primary_key =True)
	text = db.Column(db.String(400), unique=True)
	owners = relationship("Owner")
	status = db.Column(db.String(400))
	def __init__(self, text):
		self.text = text
	def __repr__(self):
		return self.text

class Owner(db.Model):
	__tablename__ = 'owner'
	id = db.Column(db.Integer, primary_key =True)
	name = db.Column(db.String(20))
	doc_id = db.Column(db.Integer)
	request_id = db.Column(db.Integer, db.ForeignKey('request.id'))
	def __init__(self, name, request_id):
		self.name = name
		self.request_id = request_id
	def __repr__(self):
		return self.name

if __name__ == '__main__':
	app.run(use_debugger=True, debug=True)

<commit_msg>Breaking out database models into models.py<commit_after>from flask import Flask, render_template, request, flash
from models import *
from upload import upload

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/mydatabase'
db = SQLAlchemy(app)
db.create_all()

@app.route('/upload', methods=['GET', 'POST'])
def load():
	if request.method == 'POST':
		doc_id = upload(request.form['filepath'])
		request_id = request.form['request_id']
		owner = Owner('anon', request_id)
		owner.doc_id = int(doc_id)
		db.session.add(owner)
		db.session.commit()
		return render_template('uploaded.html', doc_id = doc_id)
	else:
		return render_template('error.html')

@app.route('/request/<int:request_id>')
def show_request(request_id):
    # show the request with the given id, the id is an integer
    r = Request.query.get(request_id)
    doc_ids = []
    if r.owners:
    	for owner in r.owners:
    		doc_ids.append(owner.doc_id)
    return render_template('requested.html', text = r.text, request_id = request_id, doc_ids = doc_ids, status = r.status)

def make_request(str):
	req = Request(str)
	req.status = "Open"
	db.session.add(req)
	db.session.commit()
	return req.id

def change_request_status(id, status):
	try:
		req = Request.query.get(id)
		req.status = status
		db.session.commit()
		return True
	except:
		return False

def open_request(id):
	return change_request_status(id, "Open")

def close_request(id):
	return change_request_status(id, "Closed")

@app.route('/', methods=['GET', 'POST'])
def index():
	if request.method == 'POST':
		text = request.form['request_text']
		request_id = make_request(text)
		return show_request(request_id)
	else:
		return render_template('index.html')

@app.route('/requests', methods=['GET', 'POST'])
def requests():
	all_record_requests = Request.query.all()
	return render_template('requests.html', all_record_requests = all_record_requests)

if __name__ == '__main__':
	app.run(use_debugger=True, debug=True)

<|endoftext|>


<commit_before>'''
ARCHES - a program developed to inventory and manage immovable cultural heritage.
Copyright (C) 2013 J. Paul Getty Trust and World Monuments Fund

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''

from django.conf import settings
from django.conf.urls import include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.i18n import patterns
from arches.app.views import concept, entity, main, map, resources, search, config, graph, tileserver
from arches.app.views.admin import ReIndexResources
from arches.app.views.graph import GraphManagerView, GraphSettingsView, GraphDataView, DatatypeTemplateView, CardManagerView, CardView, FormManagerView, FormView, ReportManagerView, ReportEditorView, FunctionManagerView
from arches.app.views.resource import ResourceEditorView, ResourceListView, ResourceData, ResourceReportView, RelatedResourcesView, ResourceDescriptors
from arches.app.views.concept import RDMView
from arches.app.views.tile import TileData
from arches.app.views.map import MapLayerManagerView

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

uuid_regex = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'

urlpatterns = [
    url(r'^$', main.index),
    url(r'^index.htm', main.index, name='home'),
    url(r'^auth/', main.auth, name='auth'),
    url(r'^rdm/(?P<conceptid>%s|())$' % uuid_regex , RDMView.as_view(), name='rdm'),
    url(r'^geocoder', search.geocode, name="geocoder"),

    url(r'^admin/reindex/resources$', ReIndexResources.as_view(), name="reindex"),
    url(r'^entities/(?P<entityid>%s)$' % uuid_regex , entity.Entities),
    url(r'^concepts/(?P<conceptid>%s)/manage_parents/$' % uuid_regex, concept.manage_parents, name="concept_manage_parents"),
    url(r'^concepts/(?P<conceptid>%s)/confirm_delete/$' % uuid_regex, concept.confirm_delete, name="confirm_delete"),
    url(r'^concepts/(?P<conceptid>%s|())$' % uuid_regex , concept.concept, name="concept"),
    url(r'^concepts/tree/(?P<mode>.*)', concept.concept_tree, name="concept_tree"),
    url(r'^concepts/search$', concept.search, name="concept_search"),
    url(r'^concepts/(?P<conceptid>%s)/from_sparql_endpoint$' % uuid_regex, concept.add_concepts_from_sparql_endpoint, name="from_sparql_endpoint"),
    url(r'^concepts/search_sparql_endpoint$', concept.search_sparql_endpoint_for_concepts, name="search_sparql_endpoint"),
    url(r'^concepts/dropdown', concept.dropdown, name="dropdown"),
    url(r'^concepts/export/(?P<conceptid>%s)$' % uuid_regex , concept.export, name="export_concept"),
    url(r'^concepts/export/collections', concept.export_collections, name="export_concept_collections"),
    url(r'^concepts/get_pref_label', concept.get_pref_label, name="get_pref_label"),
    url(r'^conceptvalue/', concept.concept_value, name="concept_value"),
    url(r'^search$', search.SearchView.as_view(), name="search_home"),
    url(r'^search/terms$', search.search_terms, name="search_terms"),
    url(r'^search/resources$', search.search_results, name="search_results"),
    url(r'^search/export$', search.export_results, name="search_results_export"),
    url(r'^search/time_wheel_config$', search.time_wheel_config, name="time_wheel_config"),
    url(r'^buffer/$', search.buffer, name="buffer"),
    url(r'^resources/(?P<resourcetypeid>[0-9a-zA-Z_.]*)/(?P<form_id>[a-zA-Z_-]*)/(?P<resourceid>%s|())$' % uuid_regex, resources.resource_manager, name="resource_manager"),
    url(r'^resources/history/(?P<resourceid>%s|())$' % uuid_regex, resources.edit_history, name="edit_history"),
    url(r'^resources/layers/(?P<entitytypeid>.*)$', resources.map_layers, name="map_layers"),
    url(r'^resources/markers/(?P<entitytypeid>.*)$', resources.map_layers, {'get_centroids':True}, name="map_markers"),
    url(r'^reports/(?P<resourceid>%s)$' % uuid_regex , resources.report, name='report'),
    url(r'^get_admin_areas', resources.get_admin_areas, name='get_admin_areas'),
    url(r'^config/', config.manager, name='config'),
    url(r'^graph/(?P<graphid>%s|())$' % uuid_regex, GraphManagerView.as_view(), name='graph'),
    url(r'^graph/(?P<graphid>%s)/settings$' % uuid_regex, GraphSettingsView.as_view(), name='graph_settings'),
    url(r'^graph/(?P<graphid>%s)/card_manager$' % uuid_regex, CardManagerView.as_view(), name='card_manager'),
    url(r'^graph/(?P<graphid>%s)/append_branch$' % uuid_regex, GraphDataView.as_view(action='append_branch'), name='append_branch'),
    url(r'^graph/(?P<graphid>%s)/move_node$' % uuid_regex, GraphDataView.as_view(action='move_node'), name='move_node'),
    url(r'^graph/(?P<graphid>%s)/update_node$' % uuid_regex, GraphDataView.as_view(action='update_node'), name='update_node'),
    url(r'^graph/(?P<graphid>%s)/delete_node$' % uuid_regex, GraphDataView.as_view(action='delete_node'), name='delete_node'),
    url(r'^graph/(?P<graphid>%s)/clone$' % uuid_regex, GraphDataView.as_view(action='clone_graph'), name='clone_graph'),
    url(r'^graph/(?P<graphid>%s)/export$' % uuid_regex, GraphDataView.as_view(action='export_graph'), name='export_graph'),
    url(r'^graph/(?P<graphid>%s)/export_mapping_file$' % uuid_regex, GraphDataView.as_view(action='export_mapping_file'), name='export_mapping_file'),
    url(r'^graph/import/', GraphDataView.as_view(action='import_graph'), name='import_graph'),
    url(r'^graph/datatypes/(?P<template>[a-zA-Z_-]*)', DatatypeTemplateView.as_view(), name='datatype_template'),
    url(r'^graph/new$', GraphDataView.as_view(action='new_graph'), name='new_graph'),
    url(r'^graph/(?P<graphid>%s)/get_related_nodes/(?P<nodeid>%s)$' % (uuid_regex, uuid_regex), GraphDataView.as_view(action='get_related_nodes'), name='get_related_nodes'),
    url(r'^graph/(?P<graphid>%s)/get_valid_domain_nodes/(?P<nodeid>%s)$' % (uuid_regex, uuid_regex), GraphDataView.as_view(action='get_valid_domain_nodes'), name='get_valid_domain_nodes'),
    url(r'^graph/(?P<graphid>%s)/form_manager$' % uuid_regex, FormManagerView.as_view(), name='form_manager'),
    url(r'^graph/(?P<graphid>%s)/add_form$' % uuid_regex, FormManagerView.as_view(action='add_form'), name='add_form'),
    url(r'^graph/(?P<graphid>%s)/reorder_forms$' % uuid_regex, FormManagerView.as_view(action='reorder_forms'), name='reorder_forms'),
    url(r'^graph/(?P<graphid>%s)/report_manager$' % uuid_regex, ReportManagerView.as_view(), name='report_manager'),
    url(r'^graph/(?P<graphid>%s)/add_report$' % uuid_regex, ReportManagerView.as_view(), name='add_report'),
    url(r'^graph/(?P<graphid>%s)/add_resource$' % uuid_regex, ResourceEditorView.as_view(), name='add_resource'),
    url(r'^graph/(?P<graphid>%s)/function_manager$' % uuid_regex, FunctionManagerView.as_view(), name='function_manager'),
    url(r'^graph/(?P<graphid>%s)/apply_functions$' % uuid_regex, FunctionManagerView.as_view(), name='apply_functions'),
    url(r'^graph/(?P<graphid>%s)/remove_functions$' % uuid_regex, FunctionManagerView.as_view(), name='remove_functions'),
    url(r'^resource$', ResourceListView.as_view(), name='resource'),
    url(r'^resource/(?P<resourceid>%s)$' % uuid_regex, ResourceEditorView.as_view(), name='resource_editor'),
    url(r'^resource/(?P<resourceid>%s)/data/(?P<formid>%s)$' % (uuid_regex, uuid_regex), ResourceData.as_view(), name='resource_data'),
    url(r'^resource/related/(?P<resourceid>%s|())$' % uuid_regex, RelatedResourcesView.as_view(), name="related_resources"),
    url(r'^resource/descriptors/(?P<resourceid>%s|())$' % uuid_regex, ResourceDescriptors.as_view(), name="resource_descriptors"),
    url(r'^report/(?P<resourceid>%s)$' % uuid_regex, ResourceReportView.as_view(), name='resource_report'),
    url(r'^card/(?P<cardid>%s|())$' % uuid_regex, CardView.as_view(), name='card'),
    url(r'^form/(?P<formid>%s|())$' % uuid_regex, FormView.as_view(), name='form'),
    url(r'^form/(?P<formid>%s)/delete$' % uuid_regex, FormView.as_view(), name='delete_form'),
    url(r'^report_editor/(?P<reportid>%s|())$' % uuid_regex, ReportEditorView.as_view(), name='report_editor'),
    url(r'^report_editor/(?P<reportid>%s)/delete$' % uuid_regex, ReportEditorView.as_view(), name='delete_report'),
    url(r'^node/(?P<graphid>%s)$' % uuid_regex, GraphDataView.as_view(action='update_node'), name='node'),
    url(r'^widgets/(?P<template>[a-zA-Z_-]*)', main.widget, name="widgets"),
    url(r'^report-templates/(?P<template>[a-zA-Z_-]*)', main.report_templates, name="report-templates"),
    url(r'^function-templates/(?P<template>[a-zA-Z_-]*)', main.function_templates, name="function-templates"),
    url(r'^tile$', TileData.as_view(action='update_tile'), name="tile"),
    url(r'^tiles/reorder_tiles$', TileData.as_view(action='reorder_tiles'), name='reorder_tiles'),
    url(r'^templates/(?P<template>[a-zA-Z_\-./]*)', main.templates, name="templates"),
    url(r'^tileserver/*', tileserver.handle_request, name="tileserver"),
    url(r'^map_layer_manager/(?P<maplayerid>%s)$' % uuid_regex, MapLayerManagerView.as_view(), name='map_layer_update'),
    url(r'^map_layer_manager/*', MapLayerManagerView.as_view(), name="map_layer_manager"),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', admin.site.urls),
]

urlpatterns += staticfiles_urlpatterns()

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<commit_msg>add system settings endpoint, re #1631<commit_after>'''
ARCHES - a program developed to inventory and manage immovable cultural heritage.
Copyright (C) 2013 J. Paul Getty Trust and World Monuments Fund

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''

from django.conf import settings
from django.conf.urls import include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.i18n import patterns
from arches.app.views import concept, entity, main, map, resources, search, config, graph, tileserver
from arches.app.views.admin import ReIndexResources
from arches.app.views.graph import GraphManagerView, GraphSettingsView, GraphDataView, DatatypeTemplateView, CardManagerView, CardView, FormManagerView, FormView, ReportManagerView, ReportEditorView, FunctionManagerView
from arches.app.views.resource import ResourceEditorView, ResourceListView, ResourceData, ResourceReportView, RelatedResourcesView, ResourceDescriptors
from arches.app.views.concept import RDMView
from arches.app.views.tile import TileData
from arches.app.views.map import MapLayerManagerView

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

uuid_regex = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'

urlpatterns = [
    url(r'^$', main.index),
    url(r'^index.htm', main.index, name='home'),
    url(r'^auth/', main.auth, name='auth'),
    url(r'^rdm/(?P<conceptid>%s|())$' % uuid_regex , RDMView.as_view(), name='rdm'),
    url(r'^geocoder', search.geocode, name="geocoder"),

    url(r'^admin/reindex/resources$', ReIndexResources.as_view(), name="reindex"),
    url(r'^entities/(?P<entityid>%s)$' % uuid_regex , entity.Entities),
    url(r'^concepts/(?P<conceptid>%s)/manage_parents/$' % uuid_regex, concept.manage_parents, name="concept_manage_parents"),
    url(r'^concepts/(?P<conceptid>%s)/confirm_delete/$' % uuid_regex, concept.confirm_delete, name="confirm_delete"),
    url(r'^concepts/(?P<conceptid>%s|())$' % uuid_regex , concept.concept, name="concept"),
    url(r'^concepts/tree/(?P<mode>.*)', concept.concept_tree, name="concept_tree"),
    url(r'^concepts/search$', concept.search, name="concept_search"),
    url(r'^concepts/(?P<conceptid>%s)/from_sparql_endpoint$' % uuid_regex, concept.add_concepts_from_sparql_endpoint, name="from_sparql_endpoint"),
    url(r'^concepts/search_sparql_endpoint$', concept.search_sparql_endpoint_for_concepts, name="search_sparql_endpoint"),
    url(r'^concepts/dropdown', concept.dropdown, name="dropdown"),
    url(r'^concepts/export/(?P<conceptid>%s)$' % uuid_regex , concept.export, name="export_concept"),
    url(r'^concepts/export/collections', concept.export_collections, name="export_concept_collections"),
    url(r'^concepts/get_pref_label', concept.get_pref_label, name="get_pref_label"),
    url(r'^conceptvalue/', concept.concept_value, name="concept_value"),
    url(r'^search$', search.SearchView.as_view(), name="search_home"),
    url(r'^search/terms$', search.search_terms, name="search_terms"),
    url(r'^search/resources$', search.search_results, name="search_results"),
    url(r'^search/export$', search.export_results, name="search_results_export"),
    url(r'^search/time_wheel_config$', search.time_wheel_config, name="time_wheel_config"),
    url(r'^buffer/$', search.buffer, name="buffer"),
    url(r'^resources/(?P<resourcetypeid>[0-9a-zA-Z_.]*)/(?P<form_id>[a-zA-Z_-]*)/(?P<resourceid>%s|())$' % uuid_regex, resources.resource_manager, name="resource_manager"),
    url(r'^resources/history/(?P<resourceid>%s|())$' % uuid_regex, resources.edit_history, name="edit_history"),
    url(r'^resources/layers/(?P<entitytypeid>.*)$', resources.map_layers, name="map_layers"),
    url(r'^resources/markers/(?P<entitytypeid>.*)$', resources.map_layers, {'get_centroids':True}, name="map_markers"),
    url(r'^reports/(?P<resourceid>%s)$' % uuid_regex , resources.report, name='report'),
    url(r'^get_admin_areas', resources.get_admin_areas, name='get_admin_areas'),
    url(r'^settings/', ResourceEditorView.as_view(), { 'resourceid': 'a106c400-260c-11e7-a604-14109fd34195'}, name='config'),
    url(r'^graph/(?P<graphid>%s|())$' % uuid_regex, GraphManagerView.as_view(), name='graph'),
    url(r'^graph/(?P<graphid>%s)/settings$' % uuid_regex, GraphSettingsView.as_view(), name='graph_settings'),
    url(r'^graph/(?P<graphid>%s)/card_manager$' % uuid_regex, CardManagerView.as_view(), name='card_manager'),
    url(r'^graph/(?P<graphid>%s)/append_branch$' % uuid_regex, GraphDataView.as_view(action='append_branch'), name='append_branch'),
    url(r'^graph/(?P<graphid>%s)/move_node$' % uuid_regex, GraphDataView.as_view(action='move_node'), name='move_node'),
    url(r'^graph/(?P<graphid>%s)/update_node$' % uuid_regex, GraphDataView.as_view(action='update_node'), name='update_node'),
    url(r'^graph/(?P<graphid>%s)/delete_node$' % uuid_regex, GraphDataView.as_view(action='delete_node'), name='delete_node'),
    url(r'^graph/(?P<graphid>%s)/clone$' % uuid_regex, GraphDataView.as_view(action='clone_graph'), name='clone_graph'),
    url(r'^graph/(?P<graphid>%s)/export$' % uuid_regex, GraphDataView.as_view(action='export_graph'), name='export_graph'),
    url(r'^graph/(?P<graphid>%s)/export_mapping_file$' % uuid_regex, GraphDataView.as_view(action='export_mapping_file'), name='export_mapping_file'),
    url(r'^graph/import/', GraphDataView.as_view(action='import_graph'), name='import_graph'),
    url(r'^graph/datatypes/(?P<template>[a-zA-Z_-]*)', DatatypeTemplateView.as_view(), name='datatype_template'),
    url(r'^graph/new$', GraphDataView.as_view(action='new_graph'), name='new_graph'),
    url(r'^graph/(?P<graphid>%s)/get_related_nodes/(?P<nodeid>%s)$' % (uuid_regex, uuid_regex), GraphDataView.as_view(action='get_related_nodes'), name='get_related_nodes'),
    url(r'^graph/(?P<graphid>%s)/get_valid_domain_nodes/(?P<nodeid>%s)$' % (uuid_regex, uuid_regex), GraphDataView.as_view(action='get_valid_domain_nodes'), name='get_valid_domain_nodes'),
    url(r'^graph/(?P<graphid>%s)/form_manager$' % uuid_regex, FormManagerView.as_view(), name='form_manager'),
    url(r'^graph/(?P<graphid>%s)/add_form$' % uuid_regex, FormManagerView.as_view(action='add_form'), name='add_form'),
    url(r'^graph/(?P<graphid>%s)/reorder_forms$' % uuid_regex, FormManagerView.as_view(action='reorder_forms'), name='reorder_forms'),
    url(r'^graph/(?P<graphid>%s)/report_manager$' % uuid_regex, ReportManagerView.as_view(), name='report_manager'),
    url(r'^graph/(?P<graphid>%s)/add_report$' % uuid_regex, ReportManagerView.as_view(), name='add_report'),
    url(r'^graph/(?P<graphid>%s)/add_resource$' % uuid_regex, ResourceEditorView.as_view(), name='add_resource'),
    url(r'^graph/(?P<graphid>%s)/function_manager$' % uuid_regex, FunctionManagerView.as_view(), name='function_manager'),
    url(r'^graph/(?P<graphid>%s)/apply_functions$' % uuid_regex, FunctionManagerView.as_view(), name='apply_functions'),
    url(r'^graph/(?P<graphid>%s)/remove_functions$' % uuid_regex, FunctionManagerView.as_view(), name='remove_functions'),
    url(r'^resource$', ResourceListView.as_view(), name='resource'),
    url(r'^resource/(?P<resourceid>%s)$' % uuid_regex, ResourceEditorView.as_view(), name='resource_editor'),
    url(r'^resource/(?P<resourceid>%s)/data/(?P<formid>%s)$' % (uuid_regex, uuid_regex), ResourceData.as_view(), name='resource_data'),
    url(r'^resource/related/(?P<resourceid>%s|())$' % uuid_regex, RelatedResourcesView.as_view(), name="related_resources"),
    url(r'^resource/descriptors/(?P<resourceid>%s|())$' % uuid_regex, ResourceDescriptors.as_view(), name="resource_descriptors"),
    url(r'^report/(?P<resourceid>%s)$' % uuid_regex, ResourceReportView.as_view(), name='resource_report'),
    url(r'^card/(?P<cardid>%s|())$' % uuid_regex, CardView.as_view(), name='card'),
    url(r'^form/(?P<formid>%s|())$' % uuid_regex, FormView.as_view(), name='form'),
    url(r'^form/(?P<formid>%s)/delete$' % uuid_regex, FormView.as_view(), name='delete_form'),
    url(r'^report_editor/(?P<reportid>%s|())$' % uuid_regex, ReportEditorView.as_view(), name='report_editor'),
    url(r'^report_editor/(?P<reportid>%s)/delete$' % uuid_regex, ReportEditorView.as_view(), name='delete_report'),
    url(r'^node/(?P<graphid>%s)$' % uuid_regex, GraphDataView.as_view(action='update_node'), name='node'),
    url(r'^widgets/(?P<template>[a-zA-Z_-]*)', main.widget, name="widgets"),
    url(r'^report-templates/(?P<template>[a-zA-Z_-]*)', main.report_templates, name="report-templates"),
    url(r'^function-templates/(?P<template>[a-zA-Z_-]*)', main.function_templates, name="function-templates"),
    url(r'^tile$', TileData.as_view(action='update_tile'), name="tile"),
    url(r'^tiles/reorder_tiles$', TileData.as_view(action='reorder_tiles'), name='reorder_tiles'),
    url(r'^templates/(?P<template>[a-zA-Z_\-./]*)', main.templates, name="templates"),
    url(r'^tileserver/*', tileserver.handle_request, name="tileserver"),
    url(r'^map_layer_manager/(?P<maplayerid>%s)$' % uuid_regex, MapLayerManagerView.as_view(), name='map_layer_update'),
    url(r'^map_layer_manager/*', MapLayerManagerView.as_view(), name="map_layer_manager"),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', admin.site.urls),
]

urlpatterns += staticfiles_urlpatterns()

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<|endoftext|>


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

import pygame, menu, os, sys, shutil, time

if os.path.isfile("lwupdater.exe.new"): #trigger updater rename
	time.sleep(2)
	try:
		shutil.move("lwupdater.exe.new", "lwupdater.exe")
	except:
		pass #usually it works even though it spits out an error, so lets supress that

if len(sys.argv) > 1 and sys.argv[1] == "-k": #used by the updater to trigger the rename but not run the game (when the updater is closed)
	sys.exit(0)

class Main(object):

	def __init__(self):
		version = "indev 0.1.1"

		with open("version.dat") as f:
			fVersion = f.readline().rstrip()

			if version != fVersion:
				version += " (f: %s)" % fVersion

		clock = pygame.time.Clock()
		fps = 120
		resolution = (1280, 720)

		icon = pygame.image.load("assets/icons/icon.png")
		pygame.display.set_icon(icon)
		pygame.display.set_caption("Layer Switcher", "Layer Switcher")

		screen = pygame.display.set_mode(resolution)

		pygame.mixer.music.load("assets/music/Pamgaea.mp3")
		pygame.mixer.music.set_volume(0.05)
		pygame.mixer.music.play(-1)

		objMenu = menu.Menu(screen, clock, fps, resolution, version)

if __name__ == "__main__":
	os.environ["SDL_VIDEO_CENTERED"] = "1"
	pygame.init()
	Main()
<commit_msg>better solution to -k catching<commit_after>#!/usr/bin/env python

import pygame, menu, os, sys, shutil, time

if os.path.isfile("lwupdater.exe.new"): #trigger updater rename
	time.sleep(2)
	try:
		shutil.move("lwupdater.exe.new", "lwupdater.exe")
	except:
		pass #usually it works even though it spits out an error, so lets supress that

if "-k" in sys.argv: #used by the updater to trigger the rename but not run the game (when the updater is closed)
	sys.exit(0)

class Main(object):

	def __init__(self):
		version = "indev 0.1.1"

		with open("version.dat") as f:
			fVersion = f.readline().rstrip()

			if version != fVersion:
				version += " (f: %s)" % fVersion

		clock = pygame.time.Clock()
		fps = 120
		resolution = (1280, 720)

		icon = pygame.image.load("assets/icons/icon.png")
		pygame.display.set_icon(icon)
		pygame.display.set_caption("Layer Switcher", "Layer Switcher")

		screen = pygame.display.set_mode(resolution)

		pygame.mixer.music.load("assets/music/Pamgaea.mp3")
		pygame.mixer.music.set_volume(0.05)
		pygame.mixer.music.play(-1)

		objMenu = menu.Menu(screen, clock, fps, resolution, version)

if __name__ == "__main__":
	os.environ["SDL_VIDEO_CENTERED"] = "1"
	pygame.init()
	Main()
<|endoftext|>


<commit_before>#!/usr/bin/python
import os
from gluster.Gluster import Gluster
import sys
import time
from rancher_metadata import MetadataAPI

__author__ = 'Sebastien LANGOUREAUX'

class ServiceRun():

  def __init__(self, gluster_directory, list_volumes, transport, stripe = None, replica = None, quota = None):
    """ Init gluster
    """

    if gluster_directory is None or gluster_directory == "":
      raise Exception("You must set te directory to store gluster folume")
    if transport is None or transport == "":
      raise Exception("You must set the transport")

    self.__gluster_directory = gluster_directory
    self.__list_volumes = list_volumes
    self.__transport = transport
    self.__stripe = stripe
    self.__replica = replica
    self.__quota = quota
    self.__is_on_cluster = False

  def __is_already_on_glusterfs(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    peer_status = peer_manager.status()
    if peer_status["peers"] == 0:
        return False
    else:
        return True

  def __is_cluster_already_exist(self, list_nodes):
    for node in list_nodes.itervalues():
        gluster = Gluster(node['ip'])
        peer_status = gluster.get_peer_manager().status()
        if peer_status["peers"] > 0:
            return True

    return False

  def __wait_all_glusterfs_start(self, list_nodes):

      loop = True
      while loop:
        time.sleep(1)
        try:
            for node in list_nodes.itervalues():
                gluster = Gluster(node['ip'])
                peer_status = gluster.get_peer_manager().status()

            loop = False
        except Exception,e:
            loop = True

  def __create_all_volumes(self, list_volumes, transport, stripe, replica, quota, directory, list_nodes):
    gluster = Gluster()
    volume_manager = gluster.get_volume_manager()

    for volume in list_volumes:
        if len(volume_manager.info(volume)) == 0:
            list_bricks = []
            for node in list_nodes.itervalues():
                list_bricks.append(node['ip'] + ':' + directory + '/' + volume)
            volume_manager.create(volume, list_bricks, transport, stripe, replica, quota)
            print("Volume '" + volume + "' has been created")

  def __create_cluster(self, list_nodes):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    for node in list_nodes.itervalues():
        peer_manager.probe(node['ip'])
        print(node['name'] +  " ( " + node['ip'] + " ) " + " added on cluster")

    # I wait all node join the glusterfs before continue
    while(self.__get_numbers_peer() != number_node):
        time.sleep(1)

  def __get_numbers_peer(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    peer_status = peer_manager.status()

    return peer_status["peers"]

  def __get_peers(self):
    gluster = Gluster()
    return gluster.get_peer_manager()

  def __get_my_container_info(self):
    metadata_manager = MetadataAPI()
    current_container = {}
    current_container["name"] = metadata_manager.get_container_name()
    current_container["ip"] = metadata_manager.get_container_ip()
    current_container["id"] = metadata_manager.get_container_id()

    return current_container

  def __get_other_container_in_service(self, my_name):
    metadata_manager = MetadataAPI()
    list_containers = {}
    list_containers_name = metadata_manager.wait_service_containers()
    for container_name in list_containers_name:
        if container_name != my_name:
            list_containers[container_name] = {}
            list_containers[container_name]['id'] = metadata_manager.get_container_id(container_name)
            list_containers[container_name]['name'] = container_name
            list_containers[container_name]['ip'] = metadata_manager.get_container_ip(container_name)

    return list_containers

  def __get_numbers_of_node_in_service(self):
      metadata_manager = MetadataAPI()
      return metadata_manager.get_service_scale_size()

  def _is_master(self, current_container, list_containers):

    for container in list_containers.itervalues():
        if container['id'] < current_container["id"]:
            return False

    return True

  def run(self):

    current_container = self.__get_my_container_info()
    list_containers = self.__get_other_container_in_service(current_container)

    print("Wait all glusterfs start on all node \n")
    self.__wait_all_glusterfs_start(list_containers)

    while True:
        try:
            self.manage_cluster()
        except Exception,e:
            print("Some error appear : " + e.message)
            print("I will try again in 60s")

        time.sleep(60)

  def manage_cluster(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    volume_manager = gluster.get_volume_manager()
    metadata_manager = MetadataAPI()

    # I check there are more than 1 container
    number_node = self.__get_numbers_of_node_in_service()

    # I get my container info
    current_container = self.__get_my_container_info()

    # I get all other containers
    list_containers = self.__get_other_container_in_service(current_container["name"])

    # If I am not on cluster and there are no cluster and I am the master, so I create the gluster
    if (self.__is_already_on_glusterfs() is False) and (self._is_master(current_container, list_containers) is True) and (self.__is_cluster_already_exist(list_containers)):
        self.__create_cluster(list_containers)

    # If I am already on cluster and there are new peer, I guest them.
    if (self.__is_already_on_glusterfs() is True) and (number_node > self.__get_numbers_peer()):

        list_nodes = []
        peer_status = self.__get_peers()
        for container in list_containers.itervalues():
            if container['ip'] not in peer_status["host"]:
                list_nodes.append(container)

        self.__create_cluster(list_nodes)

    # I create all volumes
    list_nodes = list_containers.copy()
    list_nodes.append(current_container)
    self.__create_all_volumes(self.__list_volumes, self.__transport, self.__stripe, self.__replica, self.__quota,self.__gluster_directory,list_containers)

if __name__ == '__main__':
    # Start
    if(len(sys.argv) > 1 and sys.argv[1] == "start"):

        service = ServiceRun(os.getenv('GLUSTER_DATA'), os.getenv('GLUSTER_VOLUMES').split(','), os.getenv('GLUSTER_TRANSPORT'), os.getenv('GLUSTER_STRIPE'), os.getenv('GLUSTER_REPLICA'), os.getenv('GLUSTER_QUOTA'))
        service.run()
<commit_msg>simply the cluster management<commit_after>#!/usr/bin/python
import os
from gluster.Gluster import Gluster
import sys
import time
from rancher_metadata import MetadataAPI

__author__ = 'Sebastien LANGOUREAUX'

class ServiceRun():

  def __init__(self, gluster_directory, list_volumes, transport, stripe = None, replica = None, quota = None):
    """ Init gluster
    """

    if gluster_directory is None or gluster_directory == "":
      raise Exception("You must set te directory to store gluster folume")
    if transport is None or transport == "":
      raise Exception("You must set the transport")

    self.__gluster_directory = gluster_directory
    self.__list_volumes = list_volumes
    self.__transport = transport
    self.__stripe = stripe
    self.__replica = replica
    self.__quota = quota
    self.__is_on_cluster = False

  def __is_already_on_glusterfs(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    peer_status = peer_manager.status()
    if peer_status["peers"] == 0:
        return False
    else:
        return True

  def __is_cluster_already_exist(self, list_nodes):
    for node in list_nodes.itervalues():
        gluster = Gluster(node['ip'])
        peer_status = gluster.get_peer_manager().status()
        if peer_status["peers"] > 0:
            return True

    return False

  def __wait_all_glusterfs_start(self, list_nodes):

      loop = True
      while loop:
        time.sleep(1)
        try:
            for node in list_nodes.itervalues():
                gluster = Gluster(node['ip'])
                peer_status = gluster.get_peer_manager().status()

            loop = False
        except Exception,e:
            loop = True

  def __create_all_volumes(self, list_volumes, transport, stripe, replica, quota, directory, list_nodes):
    gluster = Gluster()
    volume_manager = gluster.get_volume_manager()

    for volume in list_volumes:
        if len(volume_manager.info(volume)) == 0:
            list_bricks = []
            for node in list_nodes.itervalues():
                list_bricks.append(node['ip'] + ':' + directory + '/' + volume)
            volume_manager.create(volume, list_bricks, transport, stripe, replica, quota)
            print("Volume '" + volume + "' has been created")

  def __create_cluster(self, list_nodes):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    for node in list_nodes.itervalues():
        peer_manager.probe(node['ip'])
        print(node['name'] +  " ( " + node['ip'] + " ) " + " added on cluster")

    # I wait all node join the glusterfs before continue
    while(self.__get_numbers_peer() != number_node):
        time.sleep(1)

  def __get_numbers_peer(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    peer_status = peer_manager.status()

    return peer_status["peers"]

  def __get_peers(self):
    gluster = Gluster()
    return gluster.get_peer_manager()

  def __get_my_container_info(self):
    metadata_manager = MetadataAPI()
    current_container = {}
    current_container["name"] = metadata_manager.get_container_name()
    current_container["ip"] = metadata_manager.get_container_ip()
    current_container["id"] = metadata_manager.get_container_id()

    return current_container

  def __get_other_container_in_service(self, my_name):
    metadata_manager = MetadataAPI()
    list_containers = {}
    list_containers_name = metadata_manager.wait_service_containers()
    for container_name in list_containers_name:
        if container_name != my_name:
            list_containers[container_name] = {}
            list_containers[container_name]['id'] = metadata_manager.get_container_id(container_name)
            list_containers[container_name]['name'] = container_name
            list_containers[container_name]['ip'] = metadata_manager.get_container_ip(container_name)

    return list_containers

  def __get_numbers_of_node_in_service(self):
      metadata_manager = MetadataAPI()
      return metadata_manager.get_service_scale_size()

  def _is_master(self, current_container, list_containers):

    for container in list_containers.itervalues():
        if container['id'] < current_container["id"]:
            return False

    return True

  def run(self):

    current_container = self.__get_my_container_info()
    list_containers = self.__get_other_container_in_service(current_container)

    print("Wait all glusterfs start on all node \n")
    self.__wait_all_glusterfs_start(list_containers)

    while True:
        try:
            self.manage_cluster()
        except Exception,e:
            print("Some error appear : " + e.message)
            print("I will try again in 60s")

        time.sleep(60)

  def manage_cluster(self):
    gluster = Gluster()
    peer_manager = gluster.get_peer_manager()
    volume_manager = gluster.get_volume_manager()
    metadata_manager = MetadataAPI()

    # I check there are more than 1 container
    number_node = self.__get_numbers_of_node_in_service()

    # I get my container info
    current_container = self.__get_my_container_info()

    # I get all other containers
    list_containers = self.__get_other_container_in_service(current_container["name"])

    # If I am not on cluster and there are no cluster and I am the master, so I create the gluster
    if (self.__is_already_on_glusterfs() is False) and (self._is_master(current_container, list_containers) is True) and (self.__is_cluster_already_exist(list_containers)):
        self.__create_cluster(list_containers)

    # If I am already on cluster and there are new peer, I guest them.
    if (self.__is_already_on_glusterfs() is True) and (number_node > self.__get_numbers_peer()):

        list_nodes = []
        peer_status = self.__get_peers()
        for container in list_containers.itervalues():
            if container['ip'] not in peer_status["host"]:
                list_nodes.append(container)

        self.__create_cluster(list_nodes)

    # I create all volumes
    list_nodes = list_containers.copy()
    list_nodes[current_container["name"]] = current_container
    self.__create_all_volumes(self.__list_volumes, self.__transport, self.__stripe, self.__replica, self.__quota,self.__gluster_directory,list_containers)

if __name__ == '__main__':
    # Start
    if(len(sys.argv) > 1 and sys.argv[1] == "start"):

        service = ServiceRun(os.getenv('GLUSTER_DATA'), os.getenv('GLUSTER_VOLUMES').split(','), os.getenv('GLUSTER_TRANSPORT'), os.getenv('GLUSTER_STRIPE'), os.getenv('GLUSTER_REPLICA'), os.getenv('GLUSTER_QUOTA'))
        service.run()
<|endoftext|>


<commit_before># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import base64
import hashlib
import copy
import hmac

from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import urlencode
from libcloud.utils.py3 import urlquote
from libcloud.utils.py3 import b

from libcloud.common.types import ProviderError
from libcloud.common.base import ConnectionUserAndKey, PollingConnection
from libcloud.common.base import JsonResponse
from libcloud.common.types import MalformedResponseError
from libcloud.compute.types import InvalidCredsError

class CloudStackResponse(JsonResponse):
    def parse_error(self):
        if self.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError('Invalid provider credentials')

        body = self.parse_body()
        values = list(body.values())[0]

        if 'errortext' in values:
            value = values['errortext']
        else:
            value = self.body

        error = ProviderError(value=value, http_code=self.status,
                              driver=self.connection.driver)
        raise error

class CloudStackConnection(ConnectionUserAndKey, PollingConnection):
    responseCls = CloudStackResponse
    poll_interval = 1
    request_method = '_sync_request'
    timeout = 600

    ASYNC_PENDING = 0
    ASYNC_SUCCESS = 1
    ASYNC_FAILURE = 2

    def encode_data(self, data):
        """
        Must of the data is sent as part of query params (eeww),
        but in newer versions, userdata argument can be sent as a
        urlencoded data in the request body.
        """
        if data:
            data = urlencode(data)

        return data

    def _make_signature(self, params):
        signature = [(k.lower(), v) for k, v in list(params.items())]
        signature.sort(key=lambda x: x[0])

        pairs = []
        for pair in signature:
            key = urlquote(str(pair[0]), safe='[]')
            value = urlquote(str(pair[1]), safe='[]')
            item = '%s=%s' % (key, value)
            pairs .append(item)

        signature = '&'.join(pairs)

        signature = signature.lower().replace('+', '%20')
        signature = hmac.new(b(self.key), msg=b(signature),
                             digestmod=hashlib.sha1)
        return base64.b64encode(b(signature.digest()))

    def add_default_params(self, params):
        params['apiKey'] = self.user_id
        params['response'] = 'json'

        return params

    def pre_connect_hook(self, params, headers):
        params['signature'] = self._make_signature(params)

        return params, headers

    def _async_request(self, command, action=None, params=None, data=None,
                       headers=None, method='GET', context=None):
        if params:
            context = copy.deepcopy(params)
        else:
            context = {}

        # Command is specified as part of GET call
        context['command'] = command
        result = super(CloudStackConnection, self).async_request(
            action=action, params=params, data=data, headers=headers,
            method=method, context=context)
        return result['jobresult']

    def get_request_kwargs(self, action, params=None, data='', headers=None,
                           method='GET', context=None):
        command = context['command']
        request_kwargs = {'command': command, 'action': action,
                          'params': params, 'data': data,
                          'headers': headers, 'method': method}
        return request_kwargs

    def get_poll_request_kwargs(self, response, context, request_kwargs):
        job_id = response['jobid']
        params = {'jobid': job_id}
        kwargs = {'command': 'queryAsyncJobResult', 'params': params}
        return kwargs

    def has_completed(self, response):
        status = response.get('jobstatus', self.ASYNC_PENDING)

        if status == self.ASYNC_FAILURE:
            msg = response.get('jobresult', {}).get('errortext', status)
            raise Exception(msg)

        return status == self.ASYNC_SUCCESS

    def _sync_request(self, command, action=None, params=None, data=None,
                      headers=None, method='GET'):
        """
        This method handles synchronous calls which are generally fast
        information retrieval requests and thus return 'quickly'.
        """
        # command is always sent as part of "command" query parameter
        if params:
            params = copy.deepcopy(params)
        else:
            params = {}

        params['command'] = command
        result = self.request(action=self.driver.path, params=params,
                              data=data, headers=headers, method=method)

        command = command.lower()

        if command not in ['revokesecuritygroupingress']:
            command = command + 'response'

        if command not in result.object:
            raise MalformedResponseError(
                "Unknown response format",
                body=result.body,
                driver=self.driver)
        result = result.object[command]
        return result

class CloudStackDriverMixIn(object):
    host = None
    path = None

    connectionCls = CloudStackConnection

    def __init__(self, key, secret=None, secure=True, host=None, port=None):
        host = host or self.host
        super(CloudStackDriverMixIn, self).__init__(key, secret, secure, host,
                                                    port)

    def _sync_request(self, command, action=None, params=None, data=None,
                      headers=None, method='GET'):
        return self.connection._sync_request(command=command, action=action,
                                             params=params, data=data,
                                             headers=headers, method=method)

    def _async_request(self, command, action=None, params=None, data=None,
                       headers=None, method='GET', context=None):
        return self.connection._async_request(command=command, action=action,
                                              params=params, data=data,
                                              headers=headers, method=method,
                                              context=context)
<commit_msg>Fix for new versions of CloudStack which have fixed the delete security group rule response.<commit_after># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import base64
import hashlib
import copy
import hmac

from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import urlencode
from libcloud.utils.py3 import urlquote
from libcloud.utils.py3 import b

from libcloud.common.types import ProviderError
from libcloud.common.base import ConnectionUserAndKey, PollingConnection
from libcloud.common.base import JsonResponse
from libcloud.common.types import MalformedResponseError
from libcloud.compute.types import InvalidCredsError

class CloudStackResponse(JsonResponse):
    def parse_error(self):
        if self.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError('Invalid provider credentials')

        body = self.parse_body()
        values = list(body.values())[0]

        if 'errortext' in values:
            value = values['errortext']
        else:
            value = self.body

        error = ProviderError(value=value, http_code=self.status,
                              driver=self.connection.driver)
        raise error

class CloudStackConnection(ConnectionUserAndKey, PollingConnection):
    responseCls = CloudStackResponse
    poll_interval = 1
    request_method = '_sync_request'
    timeout = 600

    ASYNC_PENDING = 0
    ASYNC_SUCCESS = 1
    ASYNC_FAILURE = 2

    def encode_data(self, data):
        """
        Must of the data is sent as part of query params (eeww),
        but in newer versions, userdata argument can be sent as a
        urlencoded data in the request body.
        """
        if data:
            data = urlencode(data)

        return data

    def _make_signature(self, params):
        signature = [(k.lower(), v) for k, v in list(params.items())]
        signature.sort(key=lambda x: x[0])

        pairs = []
        for pair in signature:
            key = urlquote(str(pair[0]), safe='[]')
            value = urlquote(str(pair[1]), safe='[]')
            item = '%s=%s' % (key, value)
            pairs .append(item)

        signature = '&'.join(pairs)

        signature = signature.lower().replace('+', '%20')
        signature = hmac.new(b(self.key), msg=b(signature),
                             digestmod=hashlib.sha1)
        return base64.b64encode(b(signature.digest()))

    def add_default_params(self, params):
        params['apiKey'] = self.user_id
        params['response'] = 'json'

        return params

    def pre_connect_hook(self, params, headers):
        params['signature'] = self._make_signature(params)

        return params, headers

    def _async_request(self, command, action=None, params=None, data=None,
                       headers=None, method='GET', context=None):
        if params:
            context = copy.deepcopy(params)
        else:
            context = {}

        # Command is specified as part of GET call
        context['command'] = command
        result = super(CloudStackConnection, self).async_request(
            action=action, params=params, data=data, headers=headers,
            method=method, context=context)
        return result['jobresult']

    def get_request_kwargs(self, action, params=None, data='', headers=None,
                           method='GET', context=None):
        command = context['command']
        request_kwargs = {'command': command, 'action': action,
                          'params': params, 'data': data,
                          'headers': headers, 'method': method}
        return request_kwargs

    def get_poll_request_kwargs(self, response, context, request_kwargs):
        job_id = response['jobid']
        params = {'jobid': job_id}
        kwargs = {'command': 'queryAsyncJobResult', 'params': params}
        return kwargs

    def has_completed(self, response):
        status = response.get('jobstatus', self.ASYNC_PENDING)

        if status == self.ASYNC_FAILURE:
            msg = response.get('jobresult', {}).get('errortext', status)
            raise Exception(msg)

        return status == self.ASYNC_SUCCESS

    def _sync_request(self, command, action=None, params=None, data=None,
                      headers=None, method='GET'):
        """
        This method handles synchronous calls which are generally fast
        information retrieval requests and thus return 'quickly'.
        """
        # command is always sent as part of "command" query parameter
        if params:
            params = copy.deepcopy(params)
        else:
            params = {}

        params['command'] = command
        result = self.request(action=self.driver.path, params=params,
                              data=data, headers=headers, method=method)

        command = command.lower()

        # Work around for older verions which don't return "response" suffix
        # in delete ingress rule response command name
        if command == 'revokesecuritygroupingress' and \
           not 'revokesecuritygroupingressresponse' in result.object:
           command = command
        else:
            command = command + 'response'

        if command not in result.object:
            raise MalformedResponseError(
                "Unknown response format",
                body=result.body,
                driver=self.driver)
        result = result.object[command]
        return result

class CloudStackDriverMixIn(object):
    host = None
    path = None

    connectionCls = CloudStackConnection

    def __init__(self, key, secret=None, secure=True, host=None, port=None):
        host = host or self.host
        super(CloudStackDriverMixIn, self).__init__(key, secret, secure, host,
                                                    port)

    def _sync_request(self, command, action=None, params=None, data=None,
                      headers=None, method='GET'):
        return self.connection._sync_request(command=command, action=action,
                                             params=params, data=data,
                                             headers=headers, method=method)

    def _async_request(self, command, action=None, params=None, data=None,
                       headers=None, method='GET', context=None):
        return self.connection._async_request(command=command, action=action,
                                              params=params, data=data,
                                              headers=headers, method=method,
                                              context=context)
<|endoftext|>