<commit_before>import json
from typing import Any, Dict, Set

from six.moves import range

class CompareFail(Exception):

    @classmethod
    def format(cls, expected, actual, cause=None):
        # type: (Any, Any, Any) -> CompareFail
        message = u"expected: %s\ngot: %s" % (
            json.dumps(expected, indent=4, sort_keys=True),
            json.dumps(actual, indent=4, sort_keys=True))
        if cause:
            message += u"\ncaused by: %s" % cause
        return cls(message)

def compare_location(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    if "path" in expected:
        comp = "path"
        if "path" not in actual:
            actual["path"] = actual["location"]
    elif "location" in expected:
        comp = "location"
    else:
        return
    if expected[comp] != "Any" and (not (actual[comp].endswith("/" + expected[comp]) or
                                    ("/" not in actual[comp] and expected[comp] == actual[comp]))):
        raise CompareFail.format(expected, actual, u"%s does not end with %s" % (actual[comp], expected[comp]))

def check_keys(keys, expected, actual):
    # type: (Set[str], Dict[str,Any], Dict[str,Any]) -> None
    for k in keys:
        try:
            compare(expected.get(k), actual.get(k))
        except CompareFail as e:
            raise CompareFail.format(expected, actual, u"field '%s' failed comparison: %s" %(
                k, str(e)
            ))

def compare_file(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    compare_location(expected, actual)
    other_keys = set(expected.keys()) - {'path', 'location', 'listing'}
    check_keys(other_keys, expected, actual)

def compare_directory(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    if actual.get("class") != 'Directory':
        raise CompareFail.format(expected, actual, u"expected object with a class 'Directory'")
    if "listing" not in actual:
        raise CompareFail.format(expected, actual, u"'listing' is mandatory field in Directory object")
    for i in expected["listing"]:
        found = False
        for j in actual["listing"]:
            try:
                compare(i, j)
                found = True
                break
            except CompareFail:
                pass
        if not found:
            raise CompareFail.format(expected, actual, u"%s not found" % json.dumps(i, indent=4, sort_keys=True))
    compare_file(expected, actual)

def compare_dict(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    for c in expected:
        try:
            compare(expected[c], actual.get(c))
        except CompareFail as e:
            raise CompareFail.format(expected, actual, u"failed comparison for key '%s': %s" % (c, e))
    extra_keys = set(actual.keys()).difference(list(expected.keys()))
    for k in extra_keys:
        if actual[k] is not None:
            raise CompareFail.format(expected, actual, u"unexpected key '%s'" % k)

def compare(expected, actual):  # type: (Any, Any) -> None
    if expected == "Any":
        return
    if expected is not None and actual is None:
        raise CompareFail.format(expected, actual)

    try:
        if isinstance(expected, dict):
            if not isinstance(actual, dict):
                raise CompareFail.format(expected, actual)

            if expected.get("class") == "File":
                compare_file(expected, actual)
            elif expected.get("class") == "Directory":
                compare_directory(expected, actual)
            else:
                compare_dict(expected, actual)

        elif isinstance(expected, list):
            if not isinstance(actual, list):
                raise CompareFail.format(expected, actual)

            if len(expected) != len(actual):
                raise CompareFail.format(expected, actual, u"lengths don't match")
            for c in range(0, len(expected)):
                try:
                    compare(expected[c], actual[c])
                except CompareFail as e:
                    raise CompareFail.format(expected, actual, e)
        else:
            if expected != actual:
                raise CompareFail.format(expected, actual)

    except Exception as e:
        raise CompareFail(str(e))
<commit_msg>In the case of comparing directories strip the trailing slash in the actual result’s path<commit_after>import json
from typing import Any, Dict, Set

from six.moves import range

class CompareFail(Exception):

    @classmethod
    def format(cls, expected, actual, cause=None):
        # type: (Any, Any, Any) -> CompareFail
        message = u"expected: %s\ngot: %s" % (
            json.dumps(expected, indent=4, sort_keys=True),
            json.dumps(actual, indent=4, sort_keys=True))
        if cause:
            message += u"\ncaused by: %s" % cause
        return cls(message)

def compare_location(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    if "path" in expected:
        comp = "path"
        if "path" not in actual:
            actual["path"] = actual["location"]
    elif "location" in expected:
        comp = "location"
    else:
        return
    if actual.get("class") == "Directory":
      actual[comp] = actual[comp].rstrip("/")

    if expected[comp] != "Any" and (not (actual[comp].endswith("/" + expected[comp]) or
                                    ("/" not in actual[comp] and expected[comp] == actual[comp]))):
        raise CompareFail.format(expected, actual, u"%s does not end with %s" % (actual[comp], expected[comp]))

def check_keys(keys, expected, actual):
    # type: (Set[str], Dict[str,Any], Dict[str,Any]) -> None
    for k in keys:
        try:
            compare(expected.get(k), actual.get(k))
        except CompareFail as e:
            raise CompareFail.format(expected, actual, u"field '%s' failed comparison: %s" %(
                k, str(e)
            ))

def compare_file(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    compare_location(expected, actual)
    other_keys = set(expected.keys()) - {'path', 'location', 'listing'}
    check_keys(other_keys, expected, actual)

def compare_directory(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    if actual.get("class") != 'Directory':
        raise CompareFail.format(expected, actual, u"expected object with a class 'Directory'")
    if "listing" not in actual:
        raise CompareFail.format(expected, actual, u"'listing' is mandatory field in Directory object")
    for i in expected["listing"]:
        found = False
        for j in actual["listing"]:
            try:
                compare(i, j)
                found = True
                break
            except CompareFail:
                pass
        if not found:
            raise CompareFail.format(expected, actual, u"%s not found" % json.dumps(i, indent=4, sort_keys=True))
    compare_file(expected, actual)

def compare_dict(expected, actual):
    # type: (Dict[str,Any], Dict[str,Any]) -> None
    for c in expected:
        try:
            compare(expected[c], actual.get(c))
        except CompareFail as e:
            raise CompareFail.format(expected, actual, u"failed comparison for key '%s': %s" % (c, e))
    extra_keys = set(actual.keys()).difference(list(expected.keys()))
    for k in extra_keys:
        if actual[k] is not None:
            raise CompareFail.format(expected, actual, u"unexpected key '%s'" % k)

def compare(expected, actual):  # type: (Any, Any) -> None
    if expected == "Any":
        return
    if expected is not None and actual is None:
        raise CompareFail.format(expected, actual)

    try:
        if isinstance(expected, dict):
            if not isinstance(actual, dict):
                raise CompareFail.format(expected, actual)

            if expected.get("class") == "File":
                compare_file(expected, actual)
            elif expected.get("class") == "Directory":
                compare_directory(expected, actual)
            else:
                compare_dict(expected, actual)

        elif isinstance(expected, list):
            if not isinstance(actual, list):
                raise CompareFail.format(expected, actual)

            if len(expected) != len(actual):
                raise CompareFail.format(expected, actual, u"lengths don't match")
            for c in range(0, len(expected)):
                try:
                    compare(expected[c], actual[c])
                except CompareFail as e:
                    raise CompareFail.format(expected, actual, e)
        else:
            if expected != actual:
                raise CompareFail.format(expected, actual)

    except Exception as e:
        raise CompareFail(str(e))
<|endoftext|>


<commit_before>from tracked.settings import *
DEBUG = False
DATABASE_HOST = 'localhost'
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/offspinner/webapps/mytracks/tracked/geo/templates',

)
MEDIA_ROOT = '/home/offspinner/webapps/mytracks/tracked'

<commit_msg>live settings<commit_after>from tracked.settings import *
DEBUG = False
DATABASE_HOST = 'localhost'
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    '/home/offspinner/webapps/mytracks/tracked/geo/templates',

)
MEDIA_ROOT = '/home/offspinner/webapps/mytracks/tracked/media'

<|endoftext|>


<commit_before>"""
Django settings for desecapi project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'lk*42u45uy9dg8l+o9$x56&%_@+85u+20#m82+f8r#w_*cj483'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'djoser',
    'desecapi',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'desecapi.urls'

WSGI_APPLICATION = 'desecapi.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'CHARSET': 'utf8',
        'COLLATION': 'utf8_general_ci',
        'TEST': {
            'CHARSET': 'utf8',
            'COLLATION': 'utf8_general_ci',
        },
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        }
    },

}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/api/static/'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}

# user management configuration
DJOSER = {
    'DOMAIN': 'desec.io',
    'SITE_NAME': 'deSEC',
    'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
    'ACTIVATION_URL': '#/activate/{uid}/{token}',
    'LOGIN_AFTER_ACTIVATION': True,
    'SEND_ACTIVATION_EMAIL': False,
}

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# How to send mail
EMAIL_HOST = ''
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = ''
DEFAULT_FROM_EMAIL = 'deSEC.io <support@desec.io>'

# use our own user model
AUTH_USER_MODEL = 'desecapi.User'

# Import local settings
try:
    from settings_local import *
except ImportError, exp:
    pass
<commit_msg>feat(django): fail if local settings unavailable<commit_after>"""
Django settings for desecapi project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'lk*42u45uy9dg8l+o9$x56&%_@+85u+20#m82+f8r#w_*cj483'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'djoser',
    'desecapi',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'desecapi.urls'

WSGI_APPLICATION = 'desecapi.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'CHARSET': 'utf8',
        'COLLATION': 'utf8_general_ci',
        'TEST': {
            'CHARSET': 'utf8',
            'COLLATION': 'utf8_general_ci',
        },
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        }
    },

}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/api/static/'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}

# user management configuration
DJOSER = {
    'DOMAIN': 'desec.io',
    'SITE_NAME': 'deSEC',
    'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
    'ACTIVATION_URL': '#/activate/{uid}/{token}',
    'LOGIN_AFTER_ACTIVATION': True,
    'SEND_ACTIVATION_EMAIL': False,
}

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# How to send mail
EMAIL_HOST = ''
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = ''
DEFAULT_FROM_EMAIL = 'deSEC.io <support@desec.io>'

# use our own user model
AUTH_USER_MODEL = 'desecapi.User'

# Import local settings
from .settings_local import *
<|endoftext|>


<commit_before><commit_msg>1.1.4dev: Enforce use of pysqlite >= 2.4.1. Refs #11969.<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python

from __future__ import print_function

import argparse
import calendar
import json
import os
import psycopg2
import re
import socket
import string
import sys

import multiprocessing as mp
from datetime import datetime
from subprocess import PIPE, Popen

from settings import *

verbose = False
warning = False
logging = False

def print_log(*objs):
    if logging or verbose:
        print("[LOGS] ", *objs, file=sys.stderr)

def print_info(*objs):
    if verbose:
        print("[INFO] ", *objs, file=sys.stderr)

def print_warn(*objs):
    if warning or verbose:
        print("[WARN] ", *objs, file=sys.stderr)

def print_error(*objs):
    print("[ERROR] ", *objs, file=sys.stderr)

def outputPostgres(dbconnstr, queue):
    print_info(dbconnstr)
    try:
        con = psycopg2.connect(dbconnstr)
    except Exception, e:
        print_error("failed with: %s" % (e.message))
        print_error("connecting to database")
        sys.exit(1)
    cur = con.cursor()
    update_validity =   "UPDATE t_validity SET state=%s, ts=%s, " \
                        "roa_prefix=%s, roa_maxlen=%s, roa_asn=%s, " \
                        "next_hop=%s, src_asn=%s, src_addr=%s " \
                        "WHERE prefix=%s AND origin=%s"
    insert_validity =   "INSERT INTO t_validity (prefix, origin, state, ts, roa_prefix, roa_maxlen, roa_asn, next_hop, src_asn, src_addr) " \
                        "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s, %s " \
                        "WHERE NOT EXISTS (SELECT 1 FROM t_validity WHERE prefix=%s AND origin=%s)"
    while True:
        data = queue.get()
        if (data == 'DONE'):
            break
        try:
            if data['type'] == 'announcement':
                try:
                    ts_str = datetime.fromtimestamp(
                        data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
                    cur.execute(update_validity, [data['state'], ts_str,
                        data['roa_prefix'], data['roa_maxlen'], data['roa_asn'],
                        data['next_hop'], data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    cur.execute(insert_validity, [data['prefix'],
                        data['origin'], data['state'], ts_str,
                        data['roa_prefix'], data['roa_maxlen'], data['roa_asn'],
                        data['next_hop'], data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    con.commit()
                except:
                    print_error("updating or inserting entry, announcement")
                    con.rollback()
            elif (data['type'] == 'withdraw') and (keepwithdrawn):
                try:
                    ts_str = datetime.fromtimestamp(
                        data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
                    cur.execute(update_validity, ['withdrawn', ts_str, None,
                        None, None, None, data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    con.commit()
                except:
                    print_error("updating entry, withdraw")
                    con.rollback()
            else:
                continue
        except Exception, e:
            print_error("%s failed with: %s" %
                        (mp.current_process().name, e.message))
    return True

def main():
    parser = argparse.ArgumentParser(description='', epilog='')
    parser.add_argument('-l', '--logging',
                        help='Ouptut log info.', action='store_true')
    parser.add_argument('-w', '--warning',
                        help='Output warnings.', action='store_true')
    parser.add_argument('-v', '--verbose',
                        help='Verbose output.', action='store_true')
    parser.add_argument('-k', '--keepwithdrawn',
                        help='Keep withdrawn prefixes.', action='store_true')
    parser.add_argument('-d', '--database',
                        help='Postgres database connection parameters.',
                        default='dbname=lbv', type=str, required=True)

    args = vars(parser.parse_args())

    global verbose
    verbose   = args['verbose']
    global warning
    warning   = args['warning']
    global logging
    logging = args['logging']

    dbconnstr = args['database'].strip()
    keepwithdrawn = args['keepwithdrawn']
    # BEGIN
    print_log(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + " starting ...")
    queue = mp.Queue()
    output_p = mp.Process(target=outputPostgres,
                           args=(dbconnstr,queue))
    output_p.start()
    # main loop
    while True:
        line = sys.stdin.readline().strip()
        try:
            data = json.loads(line)
        except:
            print_warn("Failed to parse JSON from input.")
        else:
            queue.put(data)
            print_info("output queue size: " + queue.qsize())

if __name__ == "__main__":
    main()
<commit_msg>update<commit_after>#!/usr/bin/python

from __future__ import print_function

import argparse
import calendar
import json
import os
import psycopg2
import re
import socket
import string
import sys

import multiprocessing as mp
from datetime import datetime
from subprocess import PIPE, Popen

from settings import *

verbose = False
warning = False
logging = False
keepwithdrawn = False

def print_log(*objs):
    if logging or verbose:
        print("[LOGS] ", *objs, file=sys.stderr)

def print_info(*objs):
    if verbose:
        print("[INFO] ", *objs, file=sys.stderr)

def print_warn(*objs):
    if warning or verbose:
        print("[WARN] ", *objs, file=sys.stderr)

def print_error(*objs):
    print("[ERROR] ", *objs, file=sys.stderr)

def outputPostgres(dbconnstr, queue):
    print_info(dbconnstr)
    try:
        con = psycopg2.connect(dbconnstr)
    except Exception, e:
        print_error("failed with: %s" % (e.message))
        print_error("connecting to database")
        sys.exit(1)
    cur = con.cursor()
    update_validity =   "UPDATE t_validity SET state=%s, ts=%s, " \
                        "roa_prefix=%s, roa_maxlen=%s, roa_asn=%s, " \
                        "next_hop=%s, src_asn=%s, src_addr=%s " \
                        "WHERE prefix=%s AND origin=%s"
    insert_validity =   "INSERT INTO t_validity (prefix, origin, state, ts, roa_prefix, roa_maxlen, roa_asn, next_hop, src_asn, src_addr) " \
                        "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s, %s " \
                        "WHERE NOT EXISTS (SELECT 1 FROM t_validity WHERE prefix=%s AND origin=%s)"
    while True:
        data = queue.get()
        if (data == 'DONE'):
            break
        try:
            if data['type'] == 'announcement':
                try:
                    ts_str = datetime.fromtimestamp(
                        data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
                    cur.execute(update_validity, [data['state'], ts_str,
                        data['roa_prefix'], data['roa_maxlen'], data['roa_asn'],
                        data['next_hop'], data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    cur.execute(insert_validity, [data['prefix'],
                        data['origin'], data['state'], ts_str,
                        data['roa_prefix'], data['roa_maxlen'], data['roa_asn'],
                        data['next_hop'], data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    con.commit()
                except:
                    print_error("updating or inserting entry, announcement")
                    con.rollback()
            elif (data['type'] == 'withdraw') and (keepwithdrawn):
                try:
                    ts_str = datetime.fromtimestamp(
                        data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
                    cur.execute(update_validity, ['withdrawn', ts_str, None,
                        None, None, None, data['src_asn'], data['src_addr'],
                        data['prefix'], data['origin']])
                    con.commit()
                except:
                    print_error("updating entry, withdraw")
                    con.rollback()
            else:
                continue
        except Exception, e:
            print_error("%s failed with: %s" %
                        (mp.current_process().name, e.message))
    return True

def main():
    parser = argparse.ArgumentParser(description='', epilog='')
    parser.add_argument('-l', '--logging',
                        help='Ouptut log info.', action='store_true')
    parser.add_argument('-w', '--warning',
                        help='Output warnings.', action='store_true')
    parser.add_argument('-v', '--verbose',
                        help='Verbose output.', action='store_true')
    parser.add_argument('-k', '--keepwithdrawn',
                        help='Keep withdrawn prefixes.', action='store_true')
    parser.add_argument('-d', '--database',
                        help='Postgres database connection parameters.',
                        default='dbname=lbv', type=str, required=True)

    args = vars(parser.parse_args())

    global verbose
    verbose   = args['verbose']
    global warning
    warning   = args['warning']
    global logging
    logging = args['logging']

    dbconnstr = args['database'].strip()
    global keepwithdrawn
    keepwithdrawn = args['keepwithdrawn']
    # BEGIN
    print_log(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + " starting ...")
    queue = mp.Queue()
    output_p = mp.Process(target=outputPostgres,
                           args=(dbconnstr,queue))
    output_p.start()
    # main loop
    while True:
        line = sys.stdin.readline().strip()
        try:
            data = json.loads(line)
        except:
            print_warn("Failed to parse JSON from input.")
        else:
            queue.put(data)
            print_info("output queue size: " + str(queue.qsize()))

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


<commit_before># Copyright (c) 2013 Molly White
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import HTMLParser
import tweepy
import urllib2
from secrets import *
from bs4 import BeautifulSoup
from topia.termextract import tag

tagger = tag.Tagger()
tagger.initialize()
hparser = HTMLParser.HTMLParser()

def get():
    try:
        request = urllib2.Request(
            "http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss")
        response = urllib2.urlopen(request)
    except urllib2.URLError as e:
        print e.reason
    else:
        html = BeautifulSoup(response.read())
        items = html.find_all('item')
        for item in items:
            headline = item.title.string
            h_split = headline.split()

            # We don't want to use incomplete headlines
            if "..." in headline:
                continue

            # Try to weed out all-caps headlines
            if count_caps(h_split) >= len(h_split) - 3:
                continue

            # Remove attribution string
            if "-" in headline:
                headline = headline.split("-")[:-1]
                headline = ' '.join(headline).strip()

            if process(headline):
                break
            else:
                continue

def count_caps(headline):
    count = 0
    for word in headline:
        if word[0].isupper():
            count += 1
    return count

def is_replaceable(word):
    # Prefix any noun (singular or plural) that begins with a lowercase letter
    if (word[1] == 'NN' or word[1] == 'NNS') and word[0][0].isalpha \
        and word[0][0].islower():
        return True
    else:
        return False

def process(headline):
    headline = hparser.unescape(headline)
    tagged = tagger(headline)
    for i, word in enumerate(tagged):
        # Avoid having two "cybers" in a row
        if is_replaceable(word) and not is_replaceable(tagged[i-1]):
            headline = headline.replace(" " + word[0], " cyber" + word[0], 1)
    if len(headline) > 140:
        return False
    else:
        return tweet(headline)

def tweet(headline):
    auth = tweepy.OAuthHandler(C_KEY, C_SECRET)
    auth.set_access_token(A_TOKEN, A_TOKEN_SECRET)
    api = tweepy.API(auth)
    tweets = api.user_timeline('CyberPrefixer')

    # Check that we haven't tweeted this before
    for tweet in tweets:
        if headline == tweet.text:
            return False
    api.update_status(headline)
    return True

if __name__ == "__main__":
    get()<commit_msg>Add basic logging functionality<commit_after># Copyright (c) 2013 Molly White
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import HTMLParser
import tweepy
import urllib2
from secrets import *
from bs4 import BeautifulSoup
from topia.termextract import tag
from time import gmtime, strftime

tagger = tag.Tagger()
tagger.initialize()
hparser = HTMLParser.HTMLParser()

def get():
    try:
        request = urllib2.Request(
            "http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss")
        response = urllib2.urlopen(request)
    except urllib2.URLError as e:
        print e.reason
    else:
        html = BeautifulSoup(response.read())
        items = html.find_all('item')
        for item in items:
            headline = item.title.string
            h_split = headline.split()

            # We don't want to use incomplete headlines
            if "..." in headline:
                continue

            # Try to weed out all-caps headlines
            if count_caps(h_split) >= len(h_split) - 3:
                continue

            # Remove attribution string
            if "-" in headline:
                headline = headline.split("-")[:-1]
                headline = ' '.join(headline).strip()

            if process(headline):
                break
            else:
                continue

def count_caps(headline):
    count = 0
    for word in headline:
        if word[0].isupper():
            count += 1
    return count

def is_replaceable(word):
    # Prefix any noun (singular or plural) that begins with a lowercase letter
    if (word[1] == 'NN' or word[1] == 'NNS') and word[0][0].isalpha \
        and word[0][0].islower():
        return True
    else:
        return False

def process(headline):
    headline = hparser.unescape(headline)
    tagged = tagger(headline)
    for i, word in enumerate(tagged):
        # Avoid having two "cybers" in a row
        if is_replaceable(word) and not is_replaceable(tagged[i-1]):
            headline = headline.replace(" " + word[0], " cyber" + word[0], 1)
    if len(headline) > 140:
        return False
    else:
        return tweet(headline)

def tweet(headline):
    auth = tweepy.OAuthHandler(C_KEY, C_SECRET)
    auth.set_access_token(A_TOKEN, A_TOKEN_SECRET)
    api = tweepy.API(auth)
    tweets = api.user_timeline('CyberPrefixer')

    # Check that we haven't tweeted this before
    for tweet in tweets:
        if headline == tweet.text:
            return False

    # Log tweet to file
    f = open("cyberprefixer.log", 'a')
    t = strftime("%d %b %Y %H:%M:%S", gmtime())
    f.write("\n" + t + " " + headline)
    f.close()

    # Post tweet
    api.update_status(headline)
    return True

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


<commit_before>import os
import logging
import logging.config
import yaml

NAME = __name__ + '.audit'

class AuditLogger(logging.getLoggerClass()):
    """ Custom logging class, to ensure that audit log calls always succeed. """

    def __init__(self, name=NAME):
        """ Specify lowest level possible (above NOTSET), to avoid delegation to parent. """

        super().__init__(name)

    def audit(self, msg, *args, **kwargs):
        msg = "[AUDIT] " + msg
        self._log(logging.CRITICAL, msg, args, **kwargs)

def get_log_path(name=None):

    # 'logs' directory name is assumed - see "logging.yaml".
    log_path = 'logs'
    return log_path if name is None else log_path + '/' + name

def setup_logging(default_cfg='logging.yaml', default_level=logging.INFO, env_key='LOG_CFG'):
    """Setup logging configuration. """

    logging.setLoggerClass(AuditLogger)

    directory = os.path.dirname(__file__)
    default_cfg_path = os.path.join(directory, default_cfg)
    cfg_path = os.getenv(env_key, default_cfg_path)
    if os.path.exists(cfg_path):
        with open(cfg_path, 'rt') as f:
            config = yaml.load(f.read())

        # Make sure that directory for logs exists.
        try:
            os.mkdir(get_log_path())
        except OSError as e:
            pass

        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)
<commit_msg>Bug fix.<commit_after>import os
import logging
import logging.config
import yaml

class AuditLogger(logging.getLoggerClass()):
    """ Custom logging class, to ensure that audit log calls always succeed. """

    def __init__(self, name):
        super().__init__(name)

    def audit(self, msg, *args, **kwargs):
        msg = "[AUDIT] " + msg
        self._log(logging.CRITICAL, msg, args, **kwargs)

def get_log_path(name=None):

    # 'logs' directory name is assumed - see "logging.yaml".
    log_path = 'logs'
    return log_path if name is None else log_path + '/' + name

def setup_logging(default_cfg='logging.yaml', default_level=logging.INFO, env_key='LOG_CFG'):
    """Setup logging configuration. """

    logging.setLoggerClass(AuditLogger)

    directory = os.path.dirname(__file__)
    default_cfg_path = os.path.join(directory, default_cfg)
    cfg_path = os.getenv(env_key, default_cfg_path)
    if os.path.exists(cfg_path):
        with open(cfg_path, 'rt') as f:
            config = yaml.load(f.read())

        # Make sure that directory for logs exists.
        try:
            os.mkdir(get_log_path())
        except OSError as e:
            pass

        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)
<|endoftext|>


<commit_before>#!/usr/bin/env python2.7

"""schedule_aws.py:

Synchronize google calendar.

"""

from __future__ import print_function

__author__           = "Dilawar Singh"
__copyright__        = "Copyright 2016, Dilawar singh <dilawars@ncbs.res.in>"
__credits__          = ["NCBS Bangalore"]
__license__          = "GNU GPL"
__version__          = "1.0.0"
__maintainer__       = "Dilawra Singh"
__email__            = "dilawars@ncbs.res.in"
__status__           = "Development/Production"

import sys
import os
import math
from collections import defaultdict, OrderedDict
import datetime
import tempfile
import subprocess
from logger import _logger
from db_connect import db_

fmt_ = '%Y-%m-%d'

# gcalcli command.
cmd_ = [ "/usr/bin/gcalcli" ]
options_ = [ "--calendar", 'NCBS Public Calendar', "--tsv", '--details', 'all' ]

def init( cur ):
    """
    Create a temporaty table for scheduling AWS
    """
    pass

def listToEventDict( event ):
    assert type( event ) == list
    e = { }
    if not event:
        return e
    e[ 'start_date' ] = event[0]
    e[ 'start_time' ] = event[1]
    e[ 'end_date' ] = event[2]
    e[ 'end_time' ] = event[3]
    e[ 'url' ] = event[4]
    e[ 'calendar_event_id' ] = event[4].split( 'eid=', 1 )[-1]
    e[ 'title'] = event[6]
    e[ 'location'] = event[7]
    e[ 'description'] = event[8]
    return e

def execute( cmd ):
    print( '[INFO] Executing %s' % ' '.join( cmd ) )
    o = subprocess.check_output( cmd, shell = False )
    return filter( lambda x: len( x.strip( )) > 10, o.split( '\n' ) )

def get_agenda( start, end ):
    global cmd_, options_
    global fmt_
    start_date = start.strftime( fmt_ )
    end_date = end.strftime( fmt_ )
    print( '[INFO] Getting events between %s and %s' % (start_date, end_date))
    cmd = cmd_ + [ 'agenda' , '%s' % start_date, '%s' % end_date ] + options_
    events = execute( cmd )
    return map( lambda x: listToEventDict( x.split( '\t' ) ), events )

def addOrUpdateEvent( e ):
    st, et = e[ 'start_time'], e['end_time']
    date = e['date']
    title = e['title']

def is_event_in_google_calendar( event, dbEvents ):
    for i, eventDict in enumerate( dbEvents ):
        if eventDict[ 'calendar_event_id' ] == e[ 'calendar_event_id' ]:
            print( '[INFO] Event already exists' )
            return True
    return True

def deleteOrUpdate( googleEvents, localEvents ):
    if is_event_in_google_calendar(

def synchronize( localEvents, googleEvents ):
    global cmd_

    # First delete/update any google event.
    for i, g in enumerate( googleEvents ):
        deleteOrUpdate( e,  localEvents )

def process( ):
    global db_
    try:
        cur = db_.cursor( dictionary = True )
    except Exception as e:
        print(
        '''If complain is about dictionary keyword. Install
        https://pypi.python.org/pypi/mysql-connector-python-rf/2.2.2
        using easy_install'''
        )
        quit( )

    assert( cur )

    today = datetime.datetime.today()
    endDay = today + datetime.timedelta( days = 14 )
    todayStr = today.strftime( fmt_ )
    endDayStr = endDay.strftime( fmt_ )

    # Events in google calendar.
    googleEvents = get_agenda( today, endDay )

    print( 'Getting events between %s and %s' % (todayStr, endDayStr ))
    cur.execute( """
        SELECT * FROM events WHERE is_public_event='YES' AND date >= '%s'
        AND date <= '%s'""" % (todayStr, endDayStr)
        )
    es = cur.fetchall( )
    synchronize( es, googleEvents )

def main( outfile ):
    global db_
    _logger.info( 'Synchronuzing calendar...' )
    process( )
    db_.close( )

if __name__ == '__main__':
    outfile = tempfile.NamedTemporaryFile( ).name
    if len( sys.argv ) > 1:
        outfile = sys.argv[1]
    main( outfile )
<commit_msg>gcalcli is ready.<commit_after>#!/usr/bin/env python2.7

"""schedule_aws.py:

Synchronize google calendar.

"""

from __future__ import print_function

__author__           = "Dilawar Singh"
__copyright__        = "Copyright 2016, Dilawar singh <dilawars@ncbs.res.in>"
__credits__          = ["NCBS Bangalore"]
__license__          = "GNU GPL"
__version__          = "1.0.0"
__maintainer__       = "Dilawra Singh"
__email__            = "dilawars@ncbs.res.in"
__status__           = "Development/Production"

import sys
import os
import math
from collections import defaultdict, OrderedDict
import datetime
import tempfile
import base64
import subprocess
from logger import _logger
from db_connect import db_

fmt_ = '%Y-%m-%d'

# gcalcli command.
cmd_ = [ "/usr/bin/gcalcli" ]
options_ = [ "--calendar", 'NCBS Public Calendar', "--tsv", '--details', 'all' ]

def init( cur ):
    """
    Create a temporaty table for scheduling AWS
    """
    pass

def b64decode( b64_string ):
    b64_string += "=" * ((4 - len(b64_string) % 4) % 4)
    return base64.b64decode( b64_string ).strip( )

def getEid( eid ):
    eid = eid.split( 'eid=', 1)[-1].split('&')[0]
    eid = b64decode( eid )
    return eid.split( ' ' )[0]

def listToEventDict( event ):
    assert type( event ) == list
    e = { }
    if not event:
        return e
    e[ 'start_date' ] = event[0]
    e[ 'date' ] = event[0]
    e[ 'start_time' ] = event[1]
    e[ 'end_date' ] = event[2]
    e[ 'end_time' ] = event[3]
    e[ 'url' ] = event[4]
    e[ 'calendar_event_id' ] = getEid( event[4] )
    e[ 'title'] = event[6]
    e[ 'location'] = event[7]
    e[ 'description'] = event[8]
    return e

def eventToStr( event ):
    return "%s (%s), %s to %s" % ( event[ 'title'], event[ 'location' ]
            , event[ 'start_date' ], event[ 'end_date' ]
            )

def execute( cmd ):
    print( '[INFO] Executing %s' % ' '.join( cmd ) )
    o = subprocess.check_output( cmd, shell = False )
    return filter( lambda x: len( x.strip( )) > 10, o.split( '\n' ) )

def get_agenda( start, end ):
    global cmd_, options_
    global fmt_
    start_date = start.strftime( fmt_ )
    end_date = end.strftime( fmt_ )
    print( '[INFO] Getting events between %s and %s' % (start_date, end_date))
    cmd = cmd_ + [ 'agenda' , '%s' % start_date, '%s' % end_date ] + options_
    events = execute( cmd )
    return map( lambda x: listToEventDict( x.split( '\t' ) ), events )

def addOrUpdateEvent( e ):
    st, et = e[ 'start_time'], e['end_time']
    date = e['date']
    title = e['title']

def is_event_in_google_calendar( event, dbEvents ):
    for i, eventDict in enumerate( dbEvents ):
        if eventDict[ 'calendar_event_id' ] == e[ 'calendar_event_id' ]:
            print( '[INFO] Event already exists' )
            return True
    return True

def areSameEvents( local, google ):
    res = True
    for i in [ 'title', 'description' ]:
        res = res and ( local[i] == google[i] )

    res = res and ( local[ 'venue' ] in google[ 'location' ] )
    res = res and ( '%s' % local[ 'start_time' ] == '%s:00' % google[ 'start_time' ] )
    res = res and ( '%s' % local[ 'end_time' ] == '%s:00' % google[ 'end_time' ] )
    return res

def deleteEvent( event ):
    global cmd_
    title = event[ 'title' ]
    start, end = event[ 'start_date' ], event[ 'end_date' ]
    print( "Deleting event %s" % eventToStr( event ) )
    cmd = cmd_ + [ 'delete', title, start, end, '--imaexpert' ]

def deleteOrUpdate( googleEvent, localEvents ):
    foundLocalEvent = False
    calEventId = googleEvent[ 'calendar_event_id' ]
    for le in localEvents:
        if areSameEvents( le, googleEvent ):
            foundLocalEvent = True
            break
    if not foundLocalEvent:
        # delete this event.
        deleteEvent( googleEvent )

def synchronize( localEvents, googleEvents ):
    global cmd_
    # First delete/update any google event.
    for i, ge in enumerate( googleEvents ):
        deleteOrUpdate( ge,  localEvents )

def process( ):
    global db_
    try:
        cur = db_.cursor( dictionary = True )
    except Exception as e:
        print(
        '''If complain is about dictionary keyword. Install
        https://pypi.python.org/pypi/mysql-connector-python-rf/2.2.2
        using easy_install'''
        )
        quit( )

    assert( cur )

    today = datetime.datetime.today()
    endDay = today + datetime.timedelta( days = 14 )
    todayStr = today.strftime( fmt_ )
    endDayStr = endDay.strftime( fmt_ )

    # Events in google calendar.
    googleEvents = get_agenda( today, endDay )

    print( 'Getting events between %s and %s' % (todayStr, endDayStr ))
    cur.execute( """
        SELECT * FROM events WHERE is_public_event='YES' AND date >= '%s'
        AND date <= '%s'""" % (todayStr, endDayStr)
        )
    es = cur.fetchall( )
    synchronize( es, googleEvents )

def main( outfile ):
    global db_
    _logger.info( 'Synchronuzing calendar...' )
    process( )
    db_.close( )

if __name__ == '__main__':
    outfile = tempfile.NamedTemporaryFile( ).name
    if len( sys.argv ) > 1:
        outfile = sys.argv[1]
    main( outfile )
<|endoftext|>


<commit_before><commit_msg>First (working) version of trvs import script<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
"""
A simple demo app.

It sports a small canvas and some trivial operations:

 - Add a line/box
 - Zoom in/out
 - Split a line segment
 - Delete focused item
 - Record state changes
 - Play back state changes (= undo !) With visual updates
 - Exports to SVG and PNG

"""

import gi
gi.require_version("Gtk", "3.0")

import math

import cairo
from gi.repository import Gtk

from gaphas import Canvas, GtkView, View
from gaphas import state
from gaphas.examples import Box, PortoBox, Text, FatLine, Circle
from gaphas.freehand import FreeHandPainter
from gaphas.item import Line
from gaphas.painter import (
    PainterChain,
    ItemPainter,
    HandlePainter,
    FocusedItemPainter,
    ToolPainter,
    BoundingBoxPainter,
)
from gaphas.segment import Segment
from gaphas.tool import PlacementTool, HandleTool
from gaphas.util import text_extents, text_underline

# painter.DEBUG_DRAW_BOUNDING_BOX = True

# Ensure data gets picked well:
import gaphas.picklers

# Global undo list
undo_list = []

def undo_handler(event):
    global undo_list
    undo_list.append(event)

def factory(view, cls):
    """
    Simple canvas item factory.
    """

    def wrapper():
        item = cls()
        view.canvas.add(item)
        return item

    return wrapper

class MyBox(Box):
    """Box with an example connection protocol.
    """

class MyLine(Line):
    """Line with experimental connection protocol.
    """

    def __init__(self):
        super(MyLine, self).__init__()
        self.fuzziness = 2

    def draw_head(self, context):
        cr = context.cairo
        cr.move_to(0, 0)
        cr.line_to(10, 10)
        cr.stroke()
        # Start point for the line to the next handle
        cr.move_to(0, 0)

    def draw_tail(self, context):
        cr = context.cairo
        cr.line_to(0, 0)
        cr.line_to(10, 10)
        cr.stroke()

class MyText(Text):
    """
    Text with experimental connection protocol.
    """

    def draw(self, context):
        Text.draw(self, context)
        cr = context.cairo
        w, h = text_extents(cr, self.text, multiline=self.multiline)
        cr.rectangle(0, 0, w, h)
        cr.set_source_rgba(0.3, 0.3, 1.0, 0.6)
        cr.stroke()

class UnderlineText(Text):
    def draw(self, context):
        cr = context.cairo
        text_underline(cr, 0, 0, "Some text(y)")

def create_window(canvas, title, zoom=1.0):
    view = GtkView()
    view.painter = (
        PainterChain()
        .append(FreeHandPainter(ItemPainter()))
        .append(HandlePainter())
        .append(FocusedItemPainter())
        .append(ToolPainter())
    )
    view.bounding_box_painter = FreeHandPainter(BoundingBoxPainter())
    w = Gtk.Window()
    w.set_title(title)
    w.set_default_size(400, 120)
    h = Gtk.HBox()
    w.add(h)

    # VBox contains buttons that can be used to manipulate the canvas:
    v = Gtk.VBox()
    v.set_property("border-width", 3)
    v.set_property("spacing", 2)
    f = Gtk.Frame()
    f.set_property("border-width", 1)
    f.add(v)
    h.pack_start(f, False, True, 0)

    v.add(Gtk.Label.new("Item placement:"))

    b = Gtk.Button.new_with_label("Add box")

    def on_clicked(button, view):
        # view.window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.CROSSHAIR))
        view.tool.grab(PlacementTool(view, factory(view, MyBox), HandleTool(), 2))

    b.connect("clicked", on_clicked, view)
    v.add(b)

    b = Gtk.Button.new_with_label("Add line")

    def on_clicked(button):
        view.tool.grab(PlacementTool(view, factory(view, MyLine), HandleTool(), 1))

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Zooming:"))

    b = Gtk.Button.new_with_label("Zoom in")

    def on_clicked(button):
        view.zoom(1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Zoom out")

    def on_clicked(button):
        view.zoom(1 / 1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Misc:"))

    b = Gtk.Button.new_with_label("Split line")

    def on_clicked(button):
        if isinstance(view.focused_item, Line):
            segment = Segment(view.focused_item, view)
            segment.split_segment(0)
            view.queue_draw_item(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Delete focused")

    def on_clicked(button):
        if view.focused_item:
            canvas.remove(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("State:"))
    b = Gtk.ToggleButton.new_with_label("Record")

    def on_toggled(button):
        global undo_list
        if button.get_active():
            print("start recording")
            del undo_list[:]
            state.subscribers.add(undo_handler)
        else:
            print("stop recording")
            state.subscribers.remove(undo_handler)

    b.connect("toggled", on_toggled)
    v.add(b)

    b = Gtk.Button.new_with_label("Play back")

    def on_clicked(self):
        global undo_list
        apply_me = list(undo_list)
        del undo_list[:]
        print("Actions on the undo stack:", len(apply_me))
        apply_me.reverse()
        saveapply = state.saveapply
        for event in apply_me:
            print("Undo: invoking", event)
            saveapply(*event)
            print("New undo stack size:", len(undo_list))
            # Visualize each event:
            # while Gtk.events_pending():
            #    Gtk.main_iteration()

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Export:"))

    b = Gtk.Button.new_with_label("Write demo.png")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h))
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        cr.save()
        svgview.paint(cr)

        cr.restore()
        cr.show_page()
        surface.write_to_png("demo.png")

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Write demo.svg")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.SVGSurface("demo.svg", w, h)
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        svgview.paint(cr)
        cr.show_page()
        surface.flush()
        surface.finish()

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Dump QTree")

    def on_clicked(button, li):
        view._qtree.dump()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Pickle (save)")

    def on_clicked(button, li):
        f = open("demo.pickled", "wb")
        try:
            import pickle

            pickle.dump(view.canvas, f)
        finally:
            f.close()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (load)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
            canvas.update_now()
        finally:
            f.close()
        create_window(canvas, "Unpickled diagram")

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (in place)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
        finally:
            f.close()
        # [i.request_update() for i in canvas.get_all_items()]
        canvas.update_now()
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Reattach (in place)")

    def on_clicked(button, li):
        view.canvas = None
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    # Add the actual View:

    view.canvas = canvas
    view.zoom(zoom)
    view.set_size_request(150, 120)
    s = Gtk.ScrolledWindow.new()
    s.set_hexpand(True)
    s.add(view)
    h.add(s)

    w.show_all()

    w.connect("destroy", Gtk.main_quit)

    def handle_changed(view, item, what):
        print(what, "changed: ", item)

    view.connect("focus-changed", handle_changed, "focus")
    view.connect("hover-changed", handle_changed, "hover")
    view.connect("selection-changed", handle_changed, "selection")

def create_canvas(c=None):
    if not c:
        c = Canvas()
    b = MyBox()
    b.min_width = 20
    b.min_height = 30
    b.matrix = (1.0, 0.0, 0.0, 1, 20, 20)
    b.width = b.height = 40
    c.add(b)

    bb = Box()
    bb.matrix = (1.0, 0.0, 0.0, 1, 10, 10)
    c.add(bb, parent=b)

    fl = FatLine()
    fl.height = 50
    fl.matrix.translate(100, 100)
    c.add(fl)

    circle = Circle()
    h1, h2 = circle.handles()
    circle.radius = 20
    circle.matrix.translate(50, 100)
    c.add(circle)

    # AJM: extra boxes:
    bb = Box()
    bb.matrix.rotate(math.pi / 1.567)
    c.add(bb, parent=b)
    # for i in xrange(10):
    #     bb = Box()
    #     print('box', bb)
    #     bb.matrix.rotate(math.pi/4.0 * i / 10.0)
    #     c.add(bb, parent=b)

    b = PortoBox(60, 60)
    b.min_width = 40
    b.min_height = 50
    b.matrix.translate(55, 55)
    c.add(b)

    t = UnderlineText()
    t.matrix.translate(70, 30)
    c.add(t)

    t = MyText("Single line")
    t.matrix.translate(70, 70)
    c.add(t)

    l = MyLine()
    c.add(l)
    l.handles()[1].pos = (30, 30)
    segment = Segment(l, view=None)
    segment.split_segment(0, 3)
    l.matrix.translate(30, 60)
    l.orthogonal = True

    off_y = 0
    for align_x in (-1, 0, 1):
        for align_y in (-1, 0, 1):
            t = MyText(
                "Aligned text %d/%d" % (align_x, align_y),
                align_x=align_x,
                align_y=align_y,
            )
            t.matrix.translate(120, 200 + off_y)
            off_y += 30
            c.add(t)

    t = MyText("Multiple\nlines", multiline=True)
    t.matrix.translate(70, 100)
    c.add(t)

    return c

def main():
    ##
    ## State handling (a.k.a. undo handlers)
    ##

    # First, activate the revert handler:
    state.observers.add(state.revert_handler)

    def print_handler(event):
        print("event:", event)

    c = Canvas()

    create_window(c, "View created before")

    create_canvas(c)

    # state.subscribers.add(print_handler)

    ##
    ## Start the main application
    ##

    create_window(c, "View created after")

    Gtk.main()

if __name__ == "__main__":
    import sys

    if "-p" in sys.argv:
        print("Profiling...")
        import hotshot, hotshot.stats

        prof = hotshot.Profile("demo-gaphas.prof")
        prof.runcall(main)
        prof.close()
        stats = hotshot.stats.load("demo-gaphas.prof")
        stats.strip_dirs()
        stats.sort_stats("time", "calls")
        stats.print_stats(20)
    else:
        main()

# vim: sw=4:et:
<commit_msg>Fix formatting of demo<commit_after>#!/usr/bin/env python
"""
A simple demo app.

It sports a small canvas and some trivial operations:

 - Add a line/box
 - Zoom in/out
 - Split a line segment
 - Delete focused item
 - Record state changes
 - Play back state changes (= undo !) With visual updates
 - Exports to SVG and PNG

"""

import gi

gi.require_version("Gtk", "3.0")

import math

import cairo
from gi.repository import Gtk

from gaphas import Canvas, GtkView, View
from gaphas import state
from gaphas.examples import Box, PortoBox, Text, FatLine, Circle
from gaphas.freehand import FreeHandPainter
from gaphas.item import Line
from gaphas.painter import (
    PainterChain,
    ItemPainter,
    HandlePainter,
    FocusedItemPainter,
    ToolPainter,
    BoundingBoxPainter,
)
from gaphas.segment import Segment
from gaphas.tool import PlacementTool, HandleTool
from gaphas.util import text_extents, text_underline

# painter.DEBUG_DRAW_BOUNDING_BOX = True

# Ensure data gets picked well:
import gaphas.picklers

# Global undo list
undo_list = []

def undo_handler(event):
    global undo_list
    undo_list.append(event)

def factory(view, cls):
    """
    Simple canvas item factory.
    """

    def wrapper():
        item = cls()
        view.canvas.add(item)
        return item

    return wrapper

class MyBox(Box):
    """Box with an example connection protocol.
    """

class MyLine(Line):
    """Line with experimental connection protocol.
    """

    def __init__(self):
        super(MyLine, self).__init__()
        self.fuzziness = 2

    def draw_head(self, context):
        cr = context.cairo
        cr.move_to(0, 0)
        cr.line_to(10, 10)
        cr.stroke()
        # Start point for the line to the next handle
        cr.move_to(0, 0)

    def draw_tail(self, context):
        cr = context.cairo
        cr.line_to(0, 0)
        cr.line_to(10, 10)
        cr.stroke()

class MyText(Text):
    """
    Text with experimental connection protocol.
    """

    def draw(self, context):
        Text.draw(self, context)
        cr = context.cairo
        w, h = text_extents(cr, self.text, multiline=self.multiline)
        cr.rectangle(0, 0, w, h)
        cr.set_source_rgba(0.3, 0.3, 1.0, 0.6)
        cr.stroke()

class UnderlineText(Text):
    def draw(self, context):
        cr = context.cairo
        text_underline(cr, 0, 0, "Some text(y)")

def create_window(canvas, title, zoom=1.0):
    view = GtkView()
    view.painter = (
        PainterChain()
        .append(FreeHandPainter(ItemPainter()))
        .append(HandlePainter())
        .append(FocusedItemPainter())
        .append(ToolPainter())
    )
    view.bounding_box_painter = FreeHandPainter(BoundingBoxPainter())
    w = Gtk.Window()
    w.set_title(title)
    w.set_default_size(400, 120)
    h = Gtk.HBox()
    w.add(h)

    # VBox contains buttons that can be used to manipulate the canvas:
    v = Gtk.VBox()
    v.set_property("border-width", 3)
    v.set_property("spacing", 2)
    f = Gtk.Frame()
    f.set_property("border-width", 1)
    f.add(v)
    h.pack_start(f, False, True, 0)

    v.add(Gtk.Label.new("Item placement:"))

    b = Gtk.Button.new_with_label("Add box")

    def on_clicked(button, view):
        # view.window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.CROSSHAIR))
        view.tool.grab(PlacementTool(view, factory(view, MyBox), HandleTool(), 2))

    b.connect("clicked", on_clicked, view)
    v.add(b)

    b = Gtk.Button.new_with_label("Add line")

    def on_clicked(button):
        view.tool.grab(PlacementTool(view, factory(view, MyLine), HandleTool(), 1))

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Zooming:"))

    b = Gtk.Button.new_with_label("Zoom in")

    def on_clicked(button):
        view.zoom(1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Zoom out")

    def on_clicked(button):
        view.zoom(1 / 1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Misc:"))

    b = Gtk.Button.new_with_label("Split line")

    def on_clicked(button):
        if isinstance(view.focused_item, Line):
            segment = Segment(view.focused_item, view)
            segment.split_segment(0)
            view.queue_draw_item(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Delete focused")

    def on_clicked(button):
        if view.focused_item:
            canvas.remove(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("State:"))
    b = Gtk.ToggleButton.new_with_label("Record")

    def on_toggled(button):
        global undo_list
        if button.get_active():
            print("start recording")
            del undo_list[:]
            state.subscribers.add(undo_handler)
        else:
            print("stop recording")
            state.subscribers.remove(undo_handler)

    b.connect("toggled", on_toggled)
    v.add(b)

    b = Gtk.Button.new_with_label("Play back")

    def on_clicked(self):
        global undo_list
        apply_me = list(undo_list)
        del undo_list[:]
        print("Actions on the undo stack:", len(apply_me))
        apply_me.reverse()
        saveapply = state.saveapply
        for event in apply_me:
            print("Undo: invoking", event)
            saveapply(*event)
            print("New undo stack size:", len(undo_list))
            # Visualize each event:
            # while Gtk.events_pending():
            #    Gtk.main_iteration()

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Export:"))

    b = Gtk.Button.new_with_label("Write demo.png")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h))
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        cr.save()
        svgview.paint(cr)

        cr.restore()
        cr.show_page()
        surface.write_to_png("demo.png")

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Write demo.svg")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.SVGSurface("demo.svg", w, h)
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        svgview.paint(cr)
        cr.show_page()
        surface.flush()
        surface.finish()

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Dump QTree")

    def on_clicked(button, li):
        view._qtree.dump()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Pickle (save)")

    def on_clicked(button, li):
        f = open("demo.pickled", "wb")
        try:
            import pickle

            pickle.dump(view.canvas, f)
        finally:
            f.close()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (load)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
            canvas.update_now()
        finally:
            f.close()
        create_window(canvas, "Unpickled diagram")

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (in place)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
        finally:
            f.close()
        # [i.request_update() for i in canvas.get_all_items()]
        canvas.update_now()
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Reattach (in place)")

    def on_clicked(button, li):
        view.canvas = None
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    # Add the actual View:

    view.canvas = canvas
    view.zoom(zoom)
    view.set_size_request(150, 120)
    s = Gtk.ScrolledWindow.new()
    s.set_hexpand(True)
    s.add(view)
    h.add(s)

    w.show_all()

    w.connect("destroy", Gtk.main_quit)

    def handle_changed(view, item, what):
        print(what, "changed: ", item)

    view.connect("focus-changed", handle_changed, "focus")
    view.connect("hover-changed", handle_changed, "hover")
    view.connect("selection-changed", handle_changed, "selection")

def create_canvas(c=None):
    if not c:
        c = Canvas()
    b = MyBox()
    b.min_width = 20
    b.min_height = 30
    b.matrix = (1.0, 0.0, 0.0, 1, 20, 20)
    b.width = b.height = 40
    c.add(b)

    bb = Box()
    bb.matrix = (1.0, 0.0, 0.0, 1, 10, 10)
    c.add(bb, parent=b)

    fl = FatLine()
    fl.height = 50
    fl.matrix.translate(100, 100)
    c.add(fl)

    circle = Circle()
    h1, h2 = circle.handles()
    circle.radius = 20
    circle.matrix.translate(50, 100)
    c.add(circle)

    # AJM: extra boxes:
    bb = Box()
    bb.matrix.rotate(math.pi / 1.567)
    c.add(bb, parent=b)
    # for i in xrange(10):
    #     bb = Box()
    #     print('box', bb)
    #     bb.matrix.rotate(math.pi/4.0 * i / 10.0)
    #     c.add(bb, parent=b)

    b = PortoBox(60, 60)
    b.min_width = 40
    b.min_height = 50
    b.matrix.translate(55, 55)
    c.add(b)

    t = UnderlineText()
    t.matrix.translate(70, 30)
    c.add(t)

    t = MyText("Single line")
    t.matrix.translate(70, 70)
    c.add(t)

    l = MyLine()
    c.add(l)
    l.handles()[1].pos = (30, 30)
    segment = Segment(l, view=None)
    segment.split_segment(0, 3)
    l.matrix.translate(30, 60)
    l.orthogonal = True

    off_y = 0
    for align_x in (-1, 0, 1):
        for align_y in (-1, 0, 1):
            t = MyText(
                "Aligned text %d/%d" % (align_x, align_y),
                align_x=align_x,
                align_y=align_y,
            )
            t.matrix.translate(120, 200 + off_y)
            off_y += 30
            c.add(t)

    t = MyText("Multiple\nlines", multiline=True)
    t.matrix.translate(70, 100)
    c.add(t)

    return c

def main():
    ##
    ## State handling (a.k.a. undo handlers)
    ##

    # First, activate the revert handler:
    state.observers.add(state.revert_handler)

    def print_handler(event):
        print("event:", event)

    c = Canvas()

    create_window(c, "View created before")

    create_canvas(c)

    # state.subscribers.add(print_handler)

    ##
    ## Start the main application
    ##

    create_window(c, "View created after")

    Gtk.main()

if __name__ == "__main__":
    import sys

    if "-p" in sys.argv:
        print("Profiling...")
        import hotshot, hotshot.stats

        prof = hotshot.Profile("demo-gaphas.prof")
        prof.runcall(main)
        prof.close()
        stats = hotshot.stats.load("demo-gaphas.prof")
        stats.strip_dirs()
        stats.sort_stats("time", "calls")
        stats.print_stats(20)
    else:
        main()

# vim: sw=4:et:
<|endoftext|>


<commit_before>from twisted.web.resource import Resource
from twisted.python.failure import Failure
from twisted.python import log
from twisted.web.server import NOT_DONE_YET
from twisted.internet import defer
from logging import DEBUG
from ujson import decode as json_decode, encode as json_encode

import time

class BaseService(Resource):

    def prepare(self, request):
        request.content.seek(0, 0)
        content = request.content.read()
        log.msg("content size = %d" % len(content), level=DEBUG)
        if content:
            return defer.succeed(json_decode(content))
        else:
            return defer.succeed(None)

    def render(self, *args, **kwargs):
        self.startTime = time.time()
        return Resource.render(self, *args, **kwargs)

    def doCancel(self, err, call):
        log.msg("Cancelling current request.", level=DEBUG)
        call.cancel()

    def doResponse(self, value, request):
        request.setHeader("Content-Type", "application/json; charset=UTF-8")
        if isinstance(value, Failure):
            reply = dict(error=str(value.value),
                         traceback=value.getTraceback())
            request.setResponseCode(500)
            request.write(json_encode(reply))

        else:
            request.setResponseCode(200)
            request.write(json_encode(value))

        log.msg("respone time: %.3fms" % (
            (time.time() - self.startTime) * 1000), level=DEBUG)

        request.finish()

class MessageService(BaseService):

    isLeaf = True

    def __init__(self, clients, *args, **kwargs):
        self.clients = clients
        Resource.__init__(self, *args, **kwargs)

    def sendMessage(self, messages):
        if not isinstance(messages, list):
            raise TypeError("input JSON must be a list")

        for message in messages:
            if not isinstance(messages, list):
                raise TypeError("item must be a dict")
            message = dict(map(lambda v: (v[0].encode("UTF-8"), v[1]),
                               message.items()))
            if message["servername"] not in self.clients:
                continue

            self.clients[message["servername"]].protocol.mq_append(message)
            self.clients[message["servername"]].protocol.schedule()

    def render_POST(self, request):
        d = self.prepare(request)
        request.notifyFinish().addErrback(self.doCancel, d)
        d.addCallback(self.sendMessage)
        d.addBoth(self.doResponse, request)
        return NOT_DONE_YET
<commit_msg>bugfix:service data encoding problem<commit_after>from twisted.web.resource import Resource
from twisted.python.failure import Failure
from twisted.python import log
from twisted.web.server import NOT_DONE_YET
from twisted.internet import defer
from logging import DEBUG
from ujson import decode as json_decode, encode as json_encode

import time

class BaseService(Resource):

    def prepare(self, request):
        request.content.seek(0, 0)
        content = request.content.read()
        log.msg("content size = %d" % len(content), level=DEBUG)
        if content:
            return defer.succeed(json_decode(content))
        else:
            return defer.succeed(None)

    def render(self, *args, **kwargs):
        self.startTime = time.time()
        return Resource.render(self, *args, **kwargs)

    def doCancel(self, err, call):
        log.msg("Cancelling current request.", level=DEBUG)
        call.cancel()

    def doResponse(self, value, request):
        request.setHeader("Content-Type", "application/json; charset=UTF-8")
        if isinstance(value, Failure):
            reply = dict(error=str(value.value),
                         traceback=value.getTraceback())
            request.setResponseCode(500)
            request.write(json_encode(reply))

        else:
            request.setResponseCode(200)
            request.write(json_encode(value))

        log.msg("respone time: %.3fms" % (
            (time.time() - self.startTime) * 1000), level=DEBUG)

        request.finish()

class MessageService(BaseService):

    isLeaf = True

    def __init__(self, clients, *args, **kwargs):
        self.clients = clients
        Resource.__init__(self, *args, **kwargs)

    def sendMessage(self, messages):
        if not isinstance(messages, list):
            raise TypeError("input JSON must be a list")

        for message in messages:

            if not isinstance(message, dict):
                raise TypeError("item must be a dict")
            encode_message = dict(map(lambda v: (v[0].encode("UTF-8"), v[1]),
                                      message.items()))

            name = encode_message["servername"]
            if name not in self.clients:
                continue
            encode_message["channels"] = map(lambda x: x.encode("UTF-8"),
                                             encode_message["channels"])
            encode_message["users"] = map(lambda x: x.encode("UTF-8"),
                                          encode_message["users"])
            print encode_message
            self.clients[name].protocol.mq_append(encode_message)
            self.clients[name].protocol.schedule()

    def render_POST(self, request):
        d = self.prepare(request)
        request.notifyFinish().addErrback(self.doCancel, d)
        d.addCallback(self.sendMessage)
        d.addBoth(self.doResponse, request)
        return NOT_DONE_YET
<|endoftext|>


<commit_before>"""
A plugin for setuptools to find files under the Mercurial version control
system which uses the Python library by default and falls back to use the
command line programm hg(1).
"""
__version__ = '0.2'
__author__ = 'Jannis Leidel'
__all__ = ['hg_file_finder']

import os
import subprocess

next = lambda iter: iter.next()

class HGRepoManager(object):
	def __init__(self, location='.'):
		self.location = location
		self.do_imports()

	def is_valid(self):
		return True

	def do_imports(self):
		pass

	@staticmethod
	def get_valid_managers(location):
		classes = (LibraryManager, LegacyLibraryManager, SubprocessManager)
		managers = (cls(location) for cls in classes)
		return (mgr for mgr in managers if mgr.is_valid())

class SubprocessManager(HGRepoManager):
	exe = 'hg'

	def is_valid(self):
		return subprocess.call([self.exe, 'version']) == 0

	def find_files():
		"""
		Use the hg command to recursively find versioned files in dirname.
		"""
		try:
			proc = subprocess.Popen(
				['hg', 'locate'],
				stdout=subprocess.PIPE,
				cwd=self.location,
				)
			stdout, stderr = proc.communicate()
		except:
			# Let's behave a bit nicer and return nothing if something fails.
			return []
		return stdout.splitlines()

class LibraryManager(HGRepoManager):
	OLD_VERSIONS = ('1.0', '1.0.1', '1.0.2')

	def do_imports(self):
		try:
			from mercurial.__version__ import version
			from mercurial import hg, ui, cmdutil
		except ImportError:
			pass

		try:
			from mercurial import error
		except ImportError:
			# mercurial < 1.2
			from mercurial import repo as error
		RepoError = error.RepoError
		del self
		del error
		globals().update(vars())

	def is_valid(self):
		force_cmd = os.environ.get('HG_SETUPTOOLS_FORCE_CMD', False)
		return not force_cmd and 'hg' in globals() and self.version_match()

	def version_match(self):
		return version not in self.OLD_VERSIONS

	def _get_repo(self):
		return hg.repository(ui.ui(), path=self.location)

	def _get_excluded(self, repo):
		"""
		Return all files that hg knows about, but haven't been added,
		deleted, or removed or have an unknown status.
		"""
		modified, added, removed, deleted, unknown = repo.status()[:5]
		return removed + deleted + unknown

	def find_files(self):
		"""
		Use the Mercurial library to recursively find versioned files in dirname.
		"""
		repo = self._get_repo()
		excluded = self._get_excluded()
		rev = None
		match = cmdutil.match(repo, [], {}, default='relglob')
		match.bad = lambda x, y: False
		return (abs
			for abs in repo[rev].walk(match)
			if rev and abs in repo.dirstate and abs not in excluded
			)

class LegacyLibraryManager(LibraryManager):
	def version_match(self):
		return version in self.OLD_VERSIONS

	def find_files(self):
		repo = self._get_repo()
		excluded = self._get_excluded()
		from mercurial import util
		node = None
		walker = cmdutil.walk(repo, [], {}, node=node,
			badmatch=util.always, default='relglob')
		return (abs
			for src, abs, rel, exact in walker
			if src != 'b' and (node or abs in repo.dirstate)
			and abs not in excluded
			)

def hg_file_finder(dirname="."):
	"""
	Find the files in ``dirname`` under Mercurial version control.
	"""
	dirname = dirname or '.'
	for mgr in HGRepoManager.get_valid_managers(dirname):
		try:
			return mgr.find_files()
		except:
			pass
	return []
<commit_msg>Fixed a number of errors - the classes now work in my environment<commit_after>"""
Classes for working with repositories using the Mercurial version
control system. Includes a plugin for setuptools to find files managed
by the version control system.

Classes support using the native Python library interfaces or using the
hg(1) command as a subprocess.
"""
__version__ = '0.3'
__author__ = 'Jannis Leidel'
__all__ = ['hg_file_finder']

import os
import subprocess

class HGRepoManager(object):
	def __init__(self, location='.'):
		self.location = location
		self.setup()

	def is_valid(self):
		return True

	def setup(self):
		pass

	@staticmethod
	def get_valid_managers(location):
		classes = (LibraryManager, LegacyLibraryManager, SubprocessManager)
		managers = (cls(location) for cls in classes)
		return (mgr for mgr in managers if mgr.is_valid())

	def __repr__(self):
		class_name = self.__class__.__name__
		loc = self.location
		return '%(class_name)s(%(loc)r)' % vars()

class SubprocessManager(HGRepoManager):
	exe = 'hg'

	def is_valid(self):
		return 0 == subprocess.call(
			[self.exe, 'version'],
			stdout=self._get_devnull(),
			)

	def find_files(self):
		"""
		Use the hg command to recursively find versioned files in dirname.
		"""
		try:
			proc = subprocess.Popen(
				['hg', 'locate'],
				stdout=subprocess.PIPE,
				cwd=self.location,
				)
			stdout, stderr = proc.communicate()
		except:
			# Let's behave a bit nicer and return nothing if something fails.
			return []
		return stdout.splitlines()

	@staticmethod
	def _get_devnull():
		return open(os.path.devnull, 'w')

class LibraryManager(HGRepoManager):
	OLD_VERSIONS = ('1.0', '1.0.1', '1.0.2')

	def setup(self):
		try:
			from mercurial.__version__ import version
			from mercurial import hg, ui, cmdutil
		except ImportError:
			pass

		try:
			from mercurial.error import RepoError
		except ImportError:
			# mercurial < 1.2
			from mercurial.repo import RepoError
		del self
		globals().update(vars())

	def is_valid(self):
		force_cmd = os.environ.get('HG_SETUPTOOLS_FORCE_CMD', False)
		return not force_cmd and 'hg' in globals() and self.version_match()

	def version_match(self):
		return version not in self.OLD_VERSIONS

	def _get_repo(self):
		return hg.repository(ui.ui(), path=self.location)

	@property
	def repo(self):
		if not hasattr(self, '_repo'):
			self._repo = self._get_repo()
		return self._repo

	def _get_excluded(self):
		"""
		Return all files that hg knows about, but haven't been added,
		deleted, or removed or have an unknown status.
		"""
		modified, added, removed, deleted, unknown = self.repo.status()[:5]
		return removed + deleted + unknown

	def find_files(self):
		"""
		Use the Mercurial library to recursively find versioned files in dirname.
		"""
		excluded = self._get_excluded()
		rev = None
		match = cmdutil.match(self.repo, [], {}, default='relglob')
		match.bad = lambda x, y: False
		return (abs
			for abs in self.repo[rev].walk(match)
			if (rev or abs in self.repo.dirstate)
			and abs not in excluded
			)

class LegacyLibraryManager(LibraryManager):
	def version_match(self):
		return version in self.OLD_VERSIONS

	def find_files(self):
		excluded = self._get_excluded()
		from mercurial import util
		node = None
		walker = cmdutil.walk(self.repo, [], {}, node=node,
			badmatch=util.always, default='relglob')
		return (abs
			for src, abs, rel, exact in walker
			if src != 'b' and (node or abs in repo.dirstate)
			and abs not in excluded
			)

def hg_file_finder(dirname="."):
	"""
	Find the files in ``dirname`` under Mercurial version control
	according to the setuptools spec (see
	http://peak.telecommunity.com/DevCenter/setuptools#adding-support-for-other-revision-control-systems
	).
	"""
	import distutils.log
	dirname = dirname or '.'
	for mgr in HGRepoManager.get_valid_managers(dirname):
		try:
			return mgr.find_files()
		except BaseException, e:
			distutils.log.warn("Error in %s: %s", mgr, e)
	return []
<|endoftext|>


<commit_before>from kivy.clock import Clock

import time

from defines import *

import random as rand_m

import ai_genome as aig_m
import ai_factory as f_m
import human_player as h_m
import players_mgr as pm_m
import rules as r_m
import game as g_m
import audio as a_m

def play_speech(part_num):
    a_m.instance.demo(part_num)

def sim_press(button):
    button.sim_press()
    Clock.schedule_once(button.sim_release, 0.2)

class Demo():
    def __init__(self, app, size):
        self.app = app
        self.size = size
        self.interrupted = False
        self.speed_factor = 0.65
        #self.speed_factor = 1.5

        # TODO Save settings
        # for settings demo

        # TODO Intercept Input

        self.script = self.rules_script()

    def start(self):
        a_m.instance.start_demo()
        self.play()

    def play(self, dt=None):
        try:
            sleep_time = self.script.next() / self.speed_factor

        except StopIteration:
            self.finish()
            return

        if self.interrupted:
            self.finish()
            return

        if sleep_time != None:
            sleep_time = (.8 + .4 * rand_m.random()) * sleep_time
            Clock.schedule_once(self.play, sleep_time)

    def interrupt(self):
        self.interrupted = True

    def finish(self):
        a_m.instance.finish_demo()
        self.app.finish_demo()

    def rules_script(self):
        play_speech("intersections")

        # We're already on the menu screen
        app = self.app
        ms = app.menu_screen

        yield(1)
        sim_press(ms.ids.new_game_id)

        yield(.2)

        app.show_new_game_screen()
        yield(.1)

        ss = app.setup_screen
        # TODO: Select white player type
        ss.ids.white_type_id.val = "Computer"
        # TODO: Select computer player somehow?
        ss.ids.wpl_id.val = "PentAI"

        yield(1)

        yield(1)
        sim_press(ss.ids.start_game_id)

        yield(.2)

        # Use most recent human player name
        pmgr = pm_m.PlayersMgr()
        human = pmgr.get_recent_player_names("Human", 1)[0]
        p1 = h_m.HumanPlayer(human)

        aif = f_m.AIFactory()
        genome = aig_m.AIGenome("PentAI")
        genome.use_openings_book = False
        p2 = aif.create_player(genome)

        # Create a game
        r = r_m.Rules(13, "standard")
        game = g_m.Game(r, p1, p2)

        # And start it...

        # demo flag: Disable prompting of players
        size = self.app.menu_screen.size
        self.app.start_game(game, size, demo=True)
        yield(1.2) # Compensating for .7 wait at start?!

        ps = self.app.pente_screen

        def mm(x,y):
            game.make_move((x,y))
            self.app.pente_screen.perform(0)
            self.app.pente_screen.refresh_all()

        play_speech("black_first")
        yield(2)

        play_speech("centre_first")
        yield(1.5)
        mm(3,4)
        yield(1)

        mm(6,8)
        yield(.5)
        mm(4,4)
        yield(.5)

        mm(6,7)
        yield(.5)
        mm(5,8)
        yield(.5)
        play_speech("line_5_wins")

        mm(6,9)
        yield(.5)
        mm(8,3)
        yield(.5)

        mm(6,10)
        yield(4)

        # Diagonal white win
        app.pente_screen.set_review_mode(False)
        game.go_to_the_beginning()
        yield(2)

        mm(6, 6)
        yield(.5)
        mm(5, 5)
        yield(.5)

        mm(4, 6)
        yield(.5)
        mm(7, 3)
        yield(.5)

        play_speech("diagonal_wins")

        mm(7, 5)
        yield(.5)
        mm(9, 1)
        yield(.5)

        mm(5, 6)
        yield(.5)
        mm(6, 4)
        yield(.5)

        mm(8, 6)
        yield(.8)
        mm(8, 2)
        yield(3.5)

        # Captures
        app.pente_screen.set_review_mode(False)
        game.go_to_the_beginning()
        yield(1)

        mm(6, 6)
        yield(.5)
        mm(6, 7)
        yield(.5)

        play_speech("pair_captures")

        mm(6, 5)
        yield(1.5)
        mm(6, 4)
        yield(2.5)

        mm(5, 3)
        yield(.5)
        mm(7, 5)
        yield(1)

        play_speech("diag_capt")
        yield(1.5)

        mm(8, 6)
        yield(2.5)
        mm(6, 6)
        yield(1)

        # Non captures
        ##############
        game.go_to_the_beginning()
        play_speech("non_capt")
        yield(2)

        # Length 1
        mm(0, 0)
        yield(.5)
        play_speech("single_stone")

        mm(0, 1)
        yield(1)
        mm(0, 2)
        yield(1)

        # Length 3
        mm(2, 1)
        yield(.5)
        mm(2, 0)
        yield(.5)
        play_speech("3_or_more")

        mm(2, 3)
        yield(.5)
        mm(8, 4)
        yield(.5)

        mm(2, 2)
        yield(1)
        mm(2, 4)
        yield(2)

        # Place inside the border
        mm(4, 1)
        yield(.5)
        mm(4, 0)
        yield(.5)

        play_speech("trigger_capt")

        mm(4, 10)
        yield(.5)
        mm(4, 3)
        yield(2)

        mm(4, 2) # Black places a piece inside, doesn't get taken
        yield(3)
        mm(6, 6)
        yield(1)

        # Gap
        play_speech("no_gaps")

        mm(6, 3)
        yield(.5)
        mm(6, 0)
        yield(.5)

        mm(6, 1)
        yield(1)
        mm(6, 4)
        yield(3)

        # Double capture
        mm(7, 6)
        yield(.5)

        play_speech("two_pairs")
        mm(5, 6)
        yield(.5)
        mm(7, 9)
        yield(.5)
        mm(5, 7)
        yield(.5)
        mm(0, 12)
        yield(.5)
        mm(6, 8)
        yield(.5)
        mm(4, 6)
        yield(3)

        # 5 Pairs win the game
        game.go_to_the_beginning()
        play_speech("capt_win")
        yield(1)

        # 1
        mm(0, 1)
        yield(.3)
        mm(0, 0)
        yield(.3)

        mm(0, 2)
        yield(.3)
        mm(0, 3)
        yield(.3)

        # 2
        mm(2, 1)
        yield(.3)
        mm(2, 0)
        yield(.3)

        mm(2, 2)
        yield(.3)
        mm(2, 3)
        yield(.3)

        # 3
        mm(4, 2)
        yield(.3)
        mm(4, 3)
        yield(.3)

        mm(4, 1)
        yield(.3)
        mm(4, 0)
        yield(.3)

        # 4
        mm(7, 1)
        yield(.3)
        mm(6, 0)
        yield(.3)

        mm(8, 2)
        yield(.3)
        mm(9, 3)
        yield(.3)

        # 5
        mm(2, 10)
        yield(.3)
        mm(0, 12)
        yield(.3)

        mm(1, 11)
        yield(2)
        mm(3, 9)
        yield(0.5)
        play_speech("capt_no_win")
        yield(5)

        # Demonstrate review mode
        play_speech("review")

        # Click go to beginning
        beginning_button = ps.panel_buttons.ids.beginning_id
        sim_press(beginning_button)

        yield(.3)

        game.go_to_the_beginning()
        yield(.7)

        # Click forward a few times
        forward_button = ps.panel_buttons.ids.forward_id
        for i in range(8):
            sim_press(forward_button)
            yield(.2)

            game.go_forwards_one()
            yield(.5)

        yield(.2)
        play_speech("enjoy")

        yield(4)

        ########

<commit_msg>Allow parts of the demo to be skipped.<commit_after>from kivy.clock import Clock

import time

from defines import *

import random as rand_m

import ai_genome as aig_m
import ai_factory as f_m
import human_player as h_m
import players_mgr as pm_m
import rules as r_m
import game as g_m
import audio as a_m

def play_speech(part_num):
    a_m.instance.demo(part_num)

def sim_press(button):
    button.sim_press()
    Clock.schedule_once(button.sim_release, 0.2)

class Demo():
    def __init__(self, app, size):
        self.app = app
        self.size = size
        self.interrupted = False
        self.speed_factor = 0.65

        # TODO Save settings
        # for settings demo

        self.script_list = [self.rules_script1, self.rules_script2,
                self.rules_script3, self.rules_script4, self.rules_script5]
        self.script = None

    def start(self):
        a_m.instance.start_demo()
        self.play()

    def play(self, dt=None):
        if self.script is None:
            if len(self.script_list) == 0:
                self.finish()
                return
            self.script = self.script_list[0]()
            del self.script_list[0]
        try:
            sleep_time = self.script.next() / self.speed_factor
        except StopIteration:
            self.script = None
            sleep_time = 0

        if self.interrupted:
            self.script = None
            self.interrupted = False
            sleep_time = 0
            a_m.instance.finish_demo()

        if sleep_time != None:
            sleep_time = (.8 + .4 * rand_m.random()) * sleep_time
            Clock.schedule_once(self.play, sleep_time)

    def interrupt(self):
        self.interrupted = True

    def finish(self):
        a_m.instance.finish_demo()
        self.app.finish_demo()

    def rules_script1(self):
        play_speech("intersections")

        # We're already on the menu screen
        app = self.app
        ms = app.menu_screen

        yield(1)
        sim_press(ms.ids.new_game_id)

        yield(.2)

        app.show_new_game_screen()
        yield(.1)

        ss = app.setup_screen
        # TODO: Select white player type
        ss.ids.white_type_id.val = "Computer"
        # TODO: Select computer player somehow?
        ss.ids.wpl_id.val = "PentAI"

        yield(1)

        yield(1)
        sim_press(ss.ids.start_game_id)

    def mm(self, x,y):
        self.game.make_move((x,y))
        self.app.pente_screen.perform(0)
        self.app.pente_screen.refresh_all()

    def rules_script2(s):
        # Use most recent human player name
        pmgr = pm_m.PlayersMgr()
        human = pmgr.get_recent_player_names("Human", 1)[0]
        p1 = h_m.HumanPlayer(human)

        aif = f_m.AIFactory()
        genome = aig_m.AIGenome("PentAI")
        genome.use_openings_book = False
        p2 = aif.create_player(genome)

        # Create a game
        r = r_m.Rules(13, "standard")
        s.game = g_m.Game(r, p1, p2)

        # And start it...

        # demo flag: Disable prompting of players
        size = s.app.menu_screen.size
        s.app.start_game(s.game, size, demo=True)
        s.ps = s.app.pente_screen
        yield(1.2) # Compensating for .7 wait at start?!

        play_speech("black_first")
        yield(2)

        play_speech("centre_first")
        yield(1.5)
        s.mm(3,4)
        yield(1)

        s.mm(6,8)
        yield(.5)
        s.mm(4,4)
        yield(.5)

        s.mm(6,7)
        yield(.5)
        s.mm(5,8)
        yield(.5)
        play_speech("line_5_wins")

        s.mm(6,9)
        yield(.5)
        s.mm(8,3)
        yield(.5)

        s.mm(6,10)
        yield(4)

        # Diagonal white win
        s.app.pente_screen.set_review_mode(False)
        s.game.go_to_the_beginning()
        yield(2)

        s.mm(6, 6)
        yield(.5)
        s.mm(5, 5)
        yield(.5)

        s.mm(4, 6)
        yield(.5)
        s.mm(7, 3)
        yield(.5)

        play_speech("diagonal_wins")

        s.mm(7, 5)
        yield(.5)
        s.mm(9, 1)
        yield(.5)

        s.mm(5, 6)
        yield(.5)
        s.mm(6, 4)
        yield(.5)

        s.mm(8, 6)
        yield(.8)
        s.mm(8, 2)
        yield(3.5)

    def rules_script3(s):
        # Captures
        s.app.pente_screen.set_review_mode(False)
        s.game.go_to_the_beginning()
        yield(1)

        s.mm(6, 6)
        yield(.5)
        s.mm(6, 7)
        yield(.5)

        play_speech("pair_captures")

        s.mm(6, 5)
        yield(1.5)
        s.mm(6, 4)
        yield(2.5)

        s.mm(5, 3)
        yield(.5)
        s.mm(7, 5)
        yield(1)

        play_speech("diag_capt")
        yield(1.5)

        s.mm(8, 6)
        yield(2.5)
        s.mm(6, 6)
        yield(1)

    def rules_script4(s):
        # Non captures
        ##############
        s.game.go_to_the_beginning()
        play_speech("non_capt")
        yield(2)

        # Length 1
        s.mm(0, 0)
        yield(.5)
        play_speech("single_stone")

        s.mm(0, 1)
        yield(1)
        s.mm(0, 2)
        yield(1)

        # Length 3
        s.mm(2, 1)
        yield(.5)
        s.mm(2, 0)
        yield(.5)
        play_speech("3_or_more")

        s.mm(2, 3)
        yield(.5)
        s.mm(8, 4)
        yield(.5)

        s.mm(2, 2)
        yield(1)
        s.mm(2, 4)
        yield(2)

        # Place inside the border
        s.mm(4, 1)
        yield(.5)
        s.mm(4, 0)
        yield(.5)

        play_speech("trigger_capt")

        s.mm(4, 10)
        yield(.5)
        s.mm(4, 3)
        yield(2)

        s.mm(4, 2) # Black places a piece inside, doesn't get taken
        yield(3)
        s.mm(6, 6)
        yield(1)

        # Gap
        play_speech("no_gaps")

        s.mm(6, 3)
        yield(.5)
        s.mm(6, 0)
        yield(.5)

        s.mm(6, 1)
        yield(1)
        s.mm(6, 4)
        yield(3)

        # Double capture
        s.mm(7, 6)
        yield(.5)

        play_speech("two_pairs")
        s.mm(5, 6)
        yield(.5)
        s.mm(7, 9)
        yield(.5)
        s.mm(5, 7)
        yield(.5)
        s.mm(0, 12)
        yield(.5)
        s.mm(6, 8)
        yield(.5)
        s.mm(4, 6)
        yield(3)

    def rules_script5(s):
        # 5 Pairs win the game
        s.game.go_to_the_beginning()
        play_speech("capt_win")
        yield(1)

        # 1
        s.mm(0, 1)
        yield(.3)
        s.mm(0, 0)
        yield(.3)

        s.mm(0, 2)
        yield(.3)
        s.mm(0, 3)
        yield(.3)

        # 2
        s.mm(2, 1)
        yield(.3)
        s.mm(2, 0)
        yield(.3)

        s.mm(2, 2)
        yield(.3)
        s.mm(2, 3)
        yield(.3)

        # 3
        s.mm(4, 2)
        yield(.3)
        s.mm(4, 3)
        yield(.3)

        s.mm(4, 1)
        yield(.3)
        s.mm(4, 0)
        yield(.3)

        # 4
        s.mm(7, 1)
        yield(.3)
        s.mm(6, 0)
        yield(.3)

        s.mm(8, 2)
        yield(.3)
        s.mm(9, 3)
        yield(.3)

        # 5
        s.mm(2, 10)
        yield(.3)
        s.mm(0, 12)
        yield(.3)

        s.mm(1, 11)
        yield(2)
        s.mm(3, 9)
        yield(0.5)
        play_speech("capt_no_win")
        yield(5)

        # Demonstrate review mode
        play_speech("review")

        # Click go to beginning
        beginning_button = s.ps.panel_buttons.ids.beginning_id
        sim_press(beginning_button)

        yield(.3)

        s.game.go_to_the_beginning()
        yield(.7)

        # Click forward a few times
        forward_button = s.ps.panel_buttons.ids.forward_id
        for i in range(8):
            sim_press(forward_button)
            yield(.2)

            s.game.go_forwards_one()
            yield(.5)

        yield(.2)
        play_speech("enjoy")

        yield(4)

        ########

<|endoftext|>