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

XML_NS = u'http://www.w3.org/XML/1998/namespace'
XML_PREFIX = u'xml'

XMLNS_NS = u'http://www.w3.org/2000/xmlns/'
XMLNS_PREFIX = u'xmlns'

XHTML1_NS = u'http://www.w3.org/1999/xhtml'
XHTML1_PREFIX = u'xhtml'

###########################################################
# Atom (RFC 4287, RFC 4685)
###########################################################
ATOM10_PREFIX = u'atom'
ATOMPUB_PREFIX = u'app'
THR_PREFIX = u'thr'

ATOM10_NS = u'http://www.w3.org/2005/Atom'
ATOMPUB_NS = u'http://purl.org/atom/app#'
THR_NS = u'http://purl.org/syndication/thread/1.0'

atom_as_attr = {ATOM10_NS: ['feed', 'id', 'title', 'updated', 'published', 'icon', 'logo', 'generator',
                            'rights', 'subtitle', 'content', 'summary', 'name', 'uri', 'email'],
                ATOMPUB_NS: ['edited', 'accept'],
                THR_NS: ['in-reply-to', 'total']}

atom_as_list = {ATOM10_NS: ['author', 'contributor', 'category', 'link', 'entry'],
                ATOMPUB_NS: ['collection', 'workspace', 'categories']}

atom_attribute_of_element = {None: ['type', 'term', 'href', 'rel', 'scheme', 'label',
                                    'title', 'length', 'hreflang' 'src', 'ref'],
                             THR_NS: ['count']}

###########################################################
# Dublin Core
###########################################################
DC_NS = u'http://purl.org/dc/elements/1.1/'
DC_PREFIX = u'dc'

dc_as_attr = {DC_NS: ['author', 'coverage', 'creator',
                      'date', 'description', 'format', 'identifier',
                      'language', 'publisher', 'relation', 'rights',
                      'source', 'subject', 'title', 'type']}

###########################################################
# Open Document Format
###########################################################
ODF_META_NS = u'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'
ODF_META_PREFIX = u'meta'

ODF_OFFICE_NS = u'urn:oasis:names:tc:opendocument:xmlns:office:1.0'
ODF_OFFICE_PREFIX = u'office'

ODF_TEXT_NS = u'urn:oasis:names:tc:opendocument:xmlns:text:1.0'
ODF_TEXT_PREFIX = u'text'

ODF_TABLE_NS = u'urn:oasis:names:tc:opendocument:xmlns:table:1.0 '
ODF_TABLE_PREFIX = u'table'

ODF_DRAWING_NS = u'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'
ODF_DRAWING_PREFIX = u'drawing'

ODF_PRESENTATION_NS = u'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'
ODF_PRESENTATION_PREFIX = u'presentation'

odf_meta_as_attr = {ODF_META_NS: ['document-statistic', 'creation-date']}
odf_meta_as_list = {ODF_META_NS: ['keyword']}

odf_office_as_attr = {ODF_OFFICE_NS: ['meta']}
odf_office_as_attr.update(odf_meta_as_attr)
odf_office_as_attr.update(dc_as_attr)

###########################################################
# XHTML
###########################################################
XHTML10_NS = u'http://www.w3.org/1999/xhtml'
XHTML10_PREFIX = u'xhtml'

xhtml_as_attr = {XHTML10_NS: ['html', 'head', 'body', 'title']}
xhtml_as_list = {XHTML10_NS: ['meta', 'link', 'script']}
xhtml_attribute_of_element = {None: ['content', 'name', 'lang']}

###########################################################
# XMPP/Jabber
###########################################################

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_CLIENT_NS = u'jabber:client'
XMPP_CLIENT_PREFIX = u'client'

xmpp_client_as_attr = {XMPP_CLIENT_NS: ['message', 'subject', 'body', 'thread', 'presence', 'iq']}
xmpp_client_as_list = {XMPP_CLIENT_NS: ['error']}
xmpp_client_attribute_of_element = {None: ['from', 'id', 'to', 'type', 'show', 'status', 'priority']}

# see http://www.xmpp.org/extensions/xep-0004.html
XMPP_DATA_FORM_NS = u'jabber:x:data'
XMPP_DATA_FORM_PREFIX = u'xdata'

# see http://www.xmpp.org/extensions/xep-0060.html
XMPP_PUBSUB_NS = u'http://jabber.org/protocol/pubsub'
XMPP_PUBSUB_PREFIX = u'pubsub'

xmpp_pubsub_as_attr = {XMPP_PUBSUB_NS: ['pubsub', 'create']}
xmpp_pubsub_as_list = {XMPP_PUBSUB_NS: ['configure', 'subscribe', 'options', 'affiliations',
                                        'items', 'publish', 'retract', 'subscription',
                                        'subscriptions', 'unsubscribe', 'subscribe-options']}
xmpp_pubsub_attribute_of_element = {None: ['subid']}

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_STREAM_NS = u'http://etherx.jabber.org/streams'
XMPP_STREAM_PREFIX = u'stream'

# see http://www.xmpp.org/extensions/xep-0078.html
XMPP_AUTH_NS = u'jabber:iq:auth'
XMPP_AUTH_PREFIX = u'auth'

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_SASL_NS = u'urn:ietf:params:xml:ns:xmpp-sasl'
XMPP_SASL_PREFIX = u'sasl'

XMPP_TLS_NS = u'urn:ietf:params:xml:ns:xmpp-tls'
XMPP_TLS_PREFIX = u'starttls'

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_STANZA_ERROR_NS = u'urn:ietf:params:xml:ns:xmpp-stanzas'
XMPP_STANZA_ERROR_PREFIX = None

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_BIND_NS = u'urn:ietf:params:xml:ns:xmpp-bind'
XMPP_BIND_PREFIX = u'bind'

xmpp_bind_as_attr = {XMPP_BIND_NS: ['bind', 'resource', 'jid']}

# see http://www.xmpp.org/rfcs/rfc3921.html
XMPP_SESSION_NS = u'urn:ietf:params:xml:ns:xmpp-session'
XMPP_SESSION_PREFIX = u'session'

# see http://www.xmpp.org/extensions/xep-0030.html
XMPP_DISCO_ITEMS_NS = u'http://jabber.org/protocol/disco#items'
XMPP_DISCO_ITEMS_PREFIX = u'disco'

# see http://www.xmpp.org/extensions/xep-0030.html
XMPP_DISCO_INFO_NS = u'http://jabber.org/protocol/disco#info'
XMPP_DISCO_INFO_PREFIX = u'info'

XMPP_ROSTER_NS = u'jabber:iq:roster'
XMPP_ROSTER_PREIX = u'roster'

# see http://www.xmpp.org/extensions/xep-0071.html
XMPP_XHTML_IM_NS = u'http://jabber.org/protocol/xhtml-im'
XMPP_XHTML_IM_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0022.html
XMPP_EVENT_NS = u'jabber:x:event'
XMPP_EVENT_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0012.html
XMPP_LAST_NS = u'jabber:iq:last'
XMPP_LAST_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0095.html
XMPP_SI_NS = u'http://jabber.org/protocol/si'
XMPP_SI_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0096.html
XMPP_SI_FILE_TRANSFER_NS = u'http://jabber.org/protocol/si/profile/file-transfer'
XMPP_SI_FILE_TRANSFER_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0020.html
XMPP_FEATURE_NEG_NS = u'http://jabber.org/protocol/feature-neg'
XMPP_FEATURE_NEG_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0066.html
XMPP_OOB_NS = u'jabber:iq:oob'
XMPP_OOB_PPREFIX = None
XMPP_XOOB_NS = u'jabber:x:oob'
XMPP_XOOB_PPREFIX = None

# see http://www.xmpp.org/extensions/xep-0065.html
XMPP_BYTESTREAMS_NS = u'http://jabber.org/protocol/bytestreams'
XMPP_BYTESTREAMS_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0092.html
XMPP_VERSION_NS = u'jabber:iq:version'
XMPP_VERSION_PREFIX = None

xmpp_as_attr = {}
xmpp_as_attr.update(xmpp_client_as_attr)
xmpp_as_attr.update(xmpp_pubsub_as_attr)
xmpp_as_attr.update(xmpp_bind_as_attr)

xmpp_as_list = {}
xmpp_as_list.update(xmpp_client_as_list)
xmpp_as_list.update(xmpp_pubsub_as_list)

xmpp_attribute_of_element = {}
xmpp_attribute_of_element.update(xmpp_client_attribute_of_element)
xmpp_attribute_of_element.update(xmpp_pubsub_attribute_of_element)

###########################################################
# RDF
###########################################################

RDF_PREFIX = u'rdf'
RDF_NS = u'http://www.w3.org/1999/02/22-rdf-syntax-ns#'

RDF_IMDB_PREFIX = u'imdb'
RDF_IMDB_NS = u'http://www.csd.abdn.ac.uk/~ggrimnes/dev/imdb/IMDB#'

###########################################################
# LLUP http://dev.llup.org/
###########################################################
LLUP_NS = u"http://www.x2x2x.org/llup"
LLUP_PREFIX = u'llup'
<commit_msg>Added more XMPP ns decl<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

XML_NS = u'http://www.w3.org/XML/1998/namespace'
XML_PREFIX = u'xml'

XMLNS_NS = u'http://www.w3.org/2000/xmlns/'
XMLNS_PREFIX = u'xmlns'

XHTML1_NS = u'http://www.w3.org/1999/xhtml'
XHTML1_PREFIX = u'xhtml'

###########################################################
# Atom (RFC 4287, RFC 4685)
###########################################################
ATOM10_PREFIX = u'atom'
ATOMPUB_PREFIX = u'app'
THR_PREFIX = u'thr'

ATOM10_NS = u'http://www.w3.org/2005/Atom'
ATOMPUB_NS = u'http://purl.org/atom/app#'
THR_NS = u'http://purl.org/syndication/thread/1.0'

atom_as_attr = {ATOM10_NS: ['feed', 'id', 'title', 'updated', 'published', 'icon', 'logo', 'generator',
                            'rights', 'subtitle', 'content', 'summary', 'name', 'uri', 'email'],
                ATOMPUB_NS: ['edited', 'accept'],
                THR_NS: ['in-reply-to', 'total']}

atom_as_list = {ATOM10_NS: ['author', 'contributor', 'category', 'link', 'entry'],
                ATOMPUB_NS: ['collection', 'workspace', 'categories']}

atom_attribute_of_element = {None: ['type', 'term', 'href', 'rel', 'scheme', 'label',
                                    'title', 'length', 'hreflang' 'src', 'ref'],
                             THR_NS: ['count']}

###########################################################
# Dublin Core
###########################################################
DC_NS = u'http://purl.org/dc/elements/1.1/'
DC_PREFIX = u'dc'

dc_as_attr = {DC_NS: ['author', 'coverage', 'creator',
                      'date', 'description', 'format', 'identifier',
                      'language', 'publisher', 'relation', 'rights',
                      'source', 'subject', 'title', 'type']}

###########################################################
# Open Document Format
###########################################################
ODF_META_NS = u'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'
ODF_META_PREFIX = u'meta'

ODF_OFFICE_NS = u'urn:oasis:names:tc:opendocument:xmlns:office:1.0'
ODF_OFFICE_PREFIX = u'office'

ODF_TEXT_NS = u'urn:oasis:names:tc:opendocument:xmlns:text:1.0'
ODF_TEXT_PREFIX = u'text'

ODF_TABLE_NS = u'urn:oasis:names:tc:opendocument:xmlns:table:1.0 '
ODF_TABLE_PREFIX = u'table'

ODF_DRAWING_NS = u'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'
ODF_DRAWING_PREFIX = u'drawing'

ODF_PRESENTATION_NS = u'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'
ODF_PRESENTATION_PREFIX = u'presentation'

odf_meta_as_attr = {ODF_META_NS: ['document-statistic', 'creation-date']}
odf_meta_as_list = {ODF_META_NS: ['keyword']}

odf_office_as_attr = {ODF_OFFICE_NS: ['meta']}
odf_office_as_attr.update(odf_meta_as_attr)
odf_office_as_attr.update(dc_as_attr)

###########################################################
# XHTML
###########################################################
XHTML10_NS = u'http://www.w3.org/1999/xhtml'
XHTML10_PREFIX = u'xhtml'

xhtml_as_attr = {XHTML10_NS: ['html', 'head', 'body', 'title']}
xhtml_as_list = {XHTML10_NS: ['meta', 'link', 'script']}
xhtml_attribute_of_element = {None: ['content', 'name', 'lang']}

###########################################################
# XMPP/Jabber
###########################################################

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_CLIENT_NS = u'jabber:client'
XMPP_CLIENT_PREFIX = u'client'

xmpp_client_as_attr = {XMPP_CLIENT_NS: ['message', 'subject', 'body', 'thread', 'presence', 'iq']}
xmpp_client_as_list = {XMPP_CLIENT_NS: ['error']}
xmpp_client_attribute_of_element = {None: ['from', 'id', 'to', 'type', 'show', 'status', 'priority']}

# see http://www.xmpp.org/extensions/xep-0004.html
XMPP_DATA_FORM_NS = u'jabber:x:data'
XMPP_DATA_FORM_PREFIX = u'xdata'

# see http://www.xmpp.org/extensions/xep-0060.html
XMPP_PUBSUB_NS = u'http://jabber.org/protocol/pubsub'
XMPP_PUBSUB_PREFIX = u'pubsub'

XMPP_PUBSUB_OWNER_NS = u'http://jabber.org/protocol/pubsub#owner'
XMPP_PUBSUB_OWNER_PREFIX = u'pubsub'

XMPP_PUBSUB_NODE_CONFIG_NS = u'http://jabber.org/protocol/pubsub#node_config'
XMPP_PUBSUB_NODE_CONFIG_PREFIX = u'pubsub'

XMPP_PUBSUB_EVENT_NS = u'http://jabber.org/protocol/pubsub#event'
XMPP_PUBSUB_EVENT_PREFIX = u'pubsub'

xmpp_pubsub_as_attr = {XMPP_PUBSUB_NS: ['pubsub', 'create']}
xmpp_pubsub_as_list = {XMPP_PUBSUB_NS: ['configure', 'subscribe', 'options', 'affiliations',
                                        'items', 'publish', 'retract', 'subscription',
                                        'subscriptions', 'unsubscribe', 'subscribe-options']}
xmpp_pubsub_attribute_of_element = {None: ['subid']}

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_STREAM_NS = u'http://etherx.jabber.org/streams'
XMPP_STREAM_PREFIX = u'stream'

# see http://www.xmpp.org/extensions/xep-0078.html
XMPP_AUTH_NS = u'jabber:iq:auth'
XMPP_AUTH_PREFIX = u'auth'

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_SASL_NS = u'urn:ietf:params:xml:ns:xmpp-sasl'
XMPP_SASL_PREFIX = u'sasl'

XMPP_TLS_NS = u'urn:ietf:params:xml:ns:xmpp-tls'
XMPP_TLS_PREFIX = u'starttls'

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_STANZA_ERROR_NS = u'urn:ietf:params:xml:ns:xmpp-stanzas'
XMPP_STANZA_ERROR_PREFIX = None

# see http://www.xmpp.org/rfcs/rfc3920.html
XMPP_BIND_NS = u'urn:ietf:params:xml:ns:xmpp-bind'
XMPP_BIND_PREFIX = u'bind'

xmpp_bind_as_attr = {XMPP_BIND_NS: ['bind', 'resource', 'jid']}

# see http://www.xmpp.org/rfcs/rfc3921.html
XMPP_SESSION_NS = u'urn:ietf:params:xml:ns:xmpp-session'
XMPP_SESSION_PREFIX = u'session'

# see http://www.xmpp.org/extensions/xep-0030.html
XMPP_DISCO_ITEMS_NS = u'http://jabber.org/protocol/disco#items'
XMPP_DISCO_ITEMS_PREFIX = u'disco'

# see http://www.xmpp.org/extensions/xep-0030.html
XMPP_DISCO_INFO_NS = u'http://jabber.org/protocol/disco#info'
XMPP_DISCO_INFO_PREFIX = u'info'

XMPP_ROSTER_NS = u'jabber:iq:roster'
XMPP_ROSTER_PREIX = u'roster'

# see http://www.xmpp.org/extensions/xep-0071.html
XMPP_XHTML_IM_NS = u'http://jabber.org/protocol/xhtml-im'
XMPP_XHTML_IM_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0022.html
XMPP_EVENT_NS = u'jabber:x:event'
XMPP_EVENT_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0012.html
XMPP_LAST_NS = u'jabber:iq:last'
XMPP_LAST_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0095.html
XMPP_SI_NS = u'http://jabber.org/protocol/si'
XMPP_SI_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0096.html
XMPP_SI_FILE_TRANSFER_NS = u'http://jabber.org/protocol/si/profile/file-transfer'
XMPP_SI_FILE_TRANSFER_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0020.html
XMPP_FEATURE_NEG_NS = u'http://jabber.org/protocol/feature-neg'
XMPP_FEATURE_NEG_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0066.html
XMPP_OOB_NS = u'jabber:iq:oob'
XMPP_OOB_PPREFIX = None
XMPP_XOOB_NS = u'jabber:x:oob'
XMPP_XOOB_PPREFIX = None

# see http://www.xmpp.org/extensions/xep-0065.html
XMPP_BYTESTREAMS_NS = u'http://jabber.org/protocol/bytestreams'
XMPP_BYTESTREAMS_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0092.html
XMPP_VERSION_NS = u'jabber:iq:version'
XMPP_VERSION_PREFIX = None

# see http://www.xmpp.org/extensions/xep-0054.html
XMPP_VCARD_NS = u'vcard-temp'
XMPP_VCARD_PREFIX = u'vcard'

xmpp_as_attr = {}
xmpp_as_attr.update(xmpp_client_as_attr)
xmpp_as_attr.update(xmpp_pubsub_as_attr)
xmpp_as_attr.update(xmpp_bind_as_attr)

xmpp_as_list = {}
xmpp_as_list.update(xmpp_client_as_list)
xmpp_as_list.update(xmpp_pubsub_as_list)

xmpp_attribute_of_element = {}
xmpp_attribute_of_element.update(xmpp_client_attribute_of_element)
xmpp_attribute_of_element.update(xmpp_pubsub_attribute_of_element)

###########################################################
# RDF
###########################################################

RDF_PREFIX = u'rdf'
RDF_NS = u'http://www.w3.org/1999/02/22-rdf-syntax-ns#'

RDF_IMDB_PREFIX = u'imdb'
RDF_IMDB_NS = u'http://www.csd.abdn.ac.uk/~ggrimnes/dev/imdb/IMDB#'

###########################################################
# LLUP http://dev.llup.org/
###########################################################
LLUP_NS = u"http://www.x2x2x.org/llup"
LLUP_PREFIX = u'llup'

<|endoftext|>


<commit_before>from . import fields, utils
from abc import ABCMeta

class MetaModel(ABCMeta):

    def __new__(mcs, model_name, base, attrs):
        cls = super().__new__(mcs, model_name, base, attrs)
        cls._fields = {}
        # Pre-generated DB keys (they're constant)
        cls._unique_keys = {}
        cls._unique_fields = {}
        cls._required_fields = {}
        cls._standalone_proxy = {}
        cls._standalone_auto = {}
        cls._scripts = {}

        field_attrs = ((k, v) for k, v in attrs.items()
                         if isinstance(v, fields.BaseField))

        for name, field in field_attrs:
            field.name, field.model_name = name, model_name
            cls._fields[name] = field
            if isinstance(field, fields.PrimaryKey):
                cls.pk = name

            if field.unique:
                cls._unique_fields[name] = field
                cls._unique_keys[name] = cls.qualified(name)
            elif field.standalone:
                if field.auto:
                    cls._standalone_auto[name] = field
                else:
                    cls._standalone_proxy[name] = field
            else:
                pass

            if field.required:
                cls._required_fields[name] = field

        # TODO: Wat do?
        # E   AttributeError: type object 'BaseModel' has no attribute 'redis'

        # # We can register those now and change the connection later
        # if cls._unique_fields:
        #     cls._scripts['unique'] = cls.__redis__.register_script(
        #                                             utils.SCRIPTS['unique'])

        return cls

class BaseModel(metaclass=MetaModel):

    _field_sep = ':'

    def __init__(self, **ka):
        self.__redis__ = self.redis
        self.__context_depth__ = 0
        if ka:
            # Will only search by one pair
            if len(ka) > 1:
                raise ValueError('Attempted to search by multiple fields;'
                                 'use get_by for that')
            field, value = ka.popitem()
            if field not in self._unique_fields:
                raise TypeError('Attempted to get by non-unique'
                                ' field {!r}'.format(field))
            self._data = self._get_unique(field, value)

    def __enter__(self):
        if not self.__context_depth__:
            pipe = self.__redis__.pipeline()
            self.redis = pipe.__enter__()
        self.__context_depth__ += 1
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        # Must be set at the beginning of this method
        self.__context_depth__ -= 1
        if not self.__context_depth__:
            self.redis.execute()
            self.redis.__exit__(exc_type, exc_value, traceback)
            self.redis = self.__redis__

    @classmethod
    def qualified(cls, *args, pk=None):
        parts = [cls.__name__]
        if pk is not None:
            parts.append(pk)
        parts.extend(args)
        return cls._field_sep.join(parts)

    @classmethod
    def new(cls, **ka):
        if cls._required_fields.keys() - ka.keys():
            raise Exception # TODO
        if cls.pk not in ka:
            raise Exception('No PK') # TODO

        # def _test_uniqueness(pipe):
        #     pipe.multi()
        #     for k, v in ka.items():
        #         try:
        #             key = cls._unique_keys[k]
        #         except KeyError:
        #             continue
        #         else:
        #             pipe.hexists(key, v)

        # res = cls.__redis__.transaction(_test_uniqueness, *cls._unique_keys)
        # # Not unique
        # if any(res):
        #     raise Exception # TODO

        # for key, value in cls._unique_keys.items():
        #
        # TODO: Check and set through EVALSHA<commit_msg>Fix the metaclass<commit_after>from . import fields, utils
from abc import ABCMeta

class MetaModel(ABCMeta):

    def __new__(mcs, model_name, base, attrs):
        cls = super().__new__(mcs, model_name, base, attrs)
        cls._fields = {}
        # Pre-generated DB keys (they're constant)
        cls._unique_keys = {}
        cls._unique_fields = {}
        cls._required_fields = {}
        cls._standalone_proxy = {}
        cls._standalone_auto = {}
        cls._scripts = {}

        field_attrs = ((k, v) for k, v in attrs.items()
                         if isinstance(v, fields.BaseField))

        for name, field in field_attrs:
            field.name, field.model_name = name, model_name
            cls._fields[name] = field
            if isinstance(field, fields.PrimaryKey):
                cls.pk = name

            if field.unique:
                cls._unique_fields[name] = field
                cls._unique_keys[name] = cls.qualified(name)
            elif field.standalone:
                if field.auto:
                    cls._standalone_auto[name] = field
                else:
                    cls._standalone_proxy[name] = field
            else:
                pass

            if field.required:
                cls._required_fields[name] = field

        try:
            cls.__redis__ = cls.redis
        except AttributeError:
            # Base model class, ignore it
            pass
        else:
            # We can register those now and change the connection later
            if cls._unique_fields:
                cls._scripts['unique'] = cls.__redis__.register_script(
                                                        utils.SCRIPTS['unique'])

        return cls

class BaseModel(metaclass=MetaModel):

    _field_sep = ':'

    def __init__(self, **ka):
        self.__context_depth__ = 0
        if ka:
            # Will only search by one pair
            if len(ka) > 1:
                raise ValueError('Attempted to search by multiple fields;'
                                 'use get_by for that')
            field, value = ka.popitem()
            if field not in self._unique_fields:
                raise TypeError('Attempted to get by non-unique'
                                ' field {!r}'.format(field))
            self._data = self._get_unique(field, value)

    def __enter__(self):
        if not self.__context_depth__:
            pipe = self.__redis__.pipeline()
            self.redis = pipe.__enter__()
        self.__context_depth__ += 1
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        # Must be set at the beginning of this method
        self.__context_depth__ -= 1
        if not self.__context_depth__:
            self.redis.execute()
            self.redis.__exit__(exc_type, exc_value, traceback)
            self.redis = self.__redis__

    @classmethod
    def qualified(cls, *args, pk=None):
        parts = [cls.__name__]
        if pk is not None:
            parts.append(pk)
        parts.extend(args)
        return cls._field_sep.join(parts)

    @classmethod
    def new(cls, **ka):
        if cls._required_fields.keys() - ka.keys():
            raise Exception # TODO
        if cls.pk not in ka:
            raise Exception('No PK') # TODO

        # def _test_uniqueness(pipe):
        #     pipe.multi()
        #     for k, v in ka.items():
        #         try:
        #             key = cls._unique_keys[k]
        #         except KeyError:
        #             continue
        #         else:
        #             pipe.hexists(key, v)

        # res = cls.__redis__.transaction(_test_uniqueness, *cls._unique_keys)
        # # Not unique
        # if any(res):
        #     raise Exception # TODO

        # for key, value in cls._unique_keys.items():
        #
        # TODO: Check and set through EVALSHA<|endoftext|>


<commit_before>#!/usr/bin/env python
# coding: utf8
import os
import requests
import humanize
from PIL import Image #http://stackoverflow.com/questions/32772596/pip-install-pil-fails
from StringIO import StringIO

class Media(object):
    def __init__(self, url):
        self.url = url
        self.basename = os.path.basename(self.url)
        self.name, self.extension = os.path.splitext(self.basename)
        self.media_type = self._get_media_type(self.extension)

    def _get_media_type(self, extension):
        extension = extension.lower()
        media_type_lookup = {
            '.jpg': 'Photo',
            '.mp4': 'Video',
        }
        return media_type_lookup[extension]

    def download(self):
        r = requests.get(self.url)
        self.content = r.content

    def save(self, location):
        # Create Folder
        folder, filename = os.path.split(location)
        if not os.path.exists(folder):
            os.mkdir(folder)
        # Save file
        if filename:
            return self.img.save(location)

    @property
    def img(self):
        self.download()
        return Image.open(StringIO(self.content))

    @property
    def size(self):
        self.download()
        size_bytes = len(r.content)
        return humanize.naturalsize(size_bytes)

    def __repr__(self):
        return '<Media - {0} [{1}]>'.format(self.basename, self.media_type)

if __name__ == '__main__':
    media = Media('http://hello.com/DC1111.jpg')
    print(media)
<commit_msg>Fix bug in media property size<commit_after>#!/usr/bin/env python
# coding: utf8
import os
import requests
import humanize
from PIL import Image #http://stackoverflow.com/questions/32772596/pip-install-pil-fails
from StringIO import StringIO

class Media(object):
    def __init__(self, url):
        self.url = url
        self.basename = os.path.basename(self.url)
        self.name, self.extension = os.path.splitext(self.basename)
        self.media_type = self._get_media_type(self.extension)

    def _get_media_type(self, extension):
        extension = extension.lower()
        media_type_lookup = {
            '.jpg': 'Photo',
            '.mp4': 'Video',
        }
        return media_type_lookup[extension]

    def download(self):
        r = requests.get(self.url)
        self.content = r.content

    def save(self, location):
        # Create Folder
        folder, filename = os.path.split(location)
        if not os.path.exists(folder):
            os.mkdir(folder)
        # Save file
        if filename:
            return self.img.save(location)

    @property
    def img(self):
        self.download()
        return Image.open(StringIO(self.content))

    @property
    def size(self):
        self.download()
        size_bytes = len(self.content)
        return humanize.naturalsize(size_bytes)

    def __repr__(self):
        return '<Media - {0} [{1}]>'.format(self.basename, self.media_type)

if __name__ == '__main__':
    media = Media('http://hello.com/DC1111.jpg')
    print(media)
<|endoftext|>


<commit_before>"""
hellofriend.py
Author: Ed Dennison
Credit:

Assignment:

Write and submit an interactive Python program that asks for the user's name and age,
then prints how much older Python is than the user (based on a simple comparison of
birth year). Python's first public release occurred in 1991. Something like this:

Please tell me your name: Guido
Please tell me your age: 16
Hello, Guido. Python is 8 years older than you are!

Note that the text: "Guido" and "16" are entered by the user running the program.
The final line ("Hello...") is generated dynamically when you run the program, based
on the name and age that the user enters.
"""
from datetime import datetime

nom = input("Please tell me your name: ")
age = input("Please tell me your age: ")
ageint = int(age)
pythonage = datetime.now().year - 1991
if (pythonage > ageint):
    agestr = str(pythonage - ageint) , "years older than you."
if (pythonage < ageint) :
    agestr = str(ageint-pythonage) , "years younger than you."
if (ageint == pythonage):
    agestr = "the same age as you."
print ("Hello, " + nom + ". Python is " + agestr)

<commit_msg>Updated from Brython Server: 1/10/2016 12:29:32 PM<commit_after>"""
hellofriend.py
Author: Ed Dennison
Credit:

Assignment:

Write and submit an interactive Python program that asks for the user's name and age,
then prints how much older Python is than the user (based on a simple comparison of
birth year). Python's first public release occurred in 1991. Something like this:

Please tell me your name: Guido
Please tell me your age: 16
Hello, Guido. Python is 8 years older than you are!

Note that the text: "Guido" and "16" are entered by the user running the program.
The final line ("Hello...") is generated dynamically when you run the program, based
on the name and age that the user enters.
"""
from datetime import datetime

nom = input("Please tell me your name: ")
age = input("Please tell me your age: ")
ageint = int(age)
pythonage = datetime.now().year - 1991
if (pythonage > ageint):
    agestr = str(pythonage - ageint) + " years older than you."
if (pythonage < ageint) :
    agestr = str(ageint-pythonage) +  " years younger than you."
if (ageint == pythonage):
    agestr = "the same age as you."
print ("Hello, " + nom + ". Python is " + agestr)

<|endoftext|>


<commit_before><commit_msg>[FIX] stock: error message typo<commit_after><|endoftext|>


<commit_before>
<commit_msg>Initial commit of server<commit_after>from twisted.internet.protocol.basic import LineReceiver
from twisted.internet.protocol import ServerFactory

class ParseData(object):
    def __init__(self):
        self.dispatch_dict = {'REGISTER': self.register, 'CHAT': self.chat, 'UNREGISTER': self.unregister }
        self.clients = {}

    def dispatch(self, cmd, contents, protocol):
        return dispatch_dict.get(cmd, self.errhandle)(contents, protocol)

    def register(self, contents, protocol):
        """
        REGISTER a new nick to this connection.
        Users cannot talk until they are registered.
        """
        nick = contents.split(':', 1)[0]
        if nick == '' or nick in self.clients:
            return self.errhandle('NICK:Nick already exists. Use another nick')

        self.clients[nick] = protocol
        protocol.nick = nick
        protocol.sendLine('OK:NICK:'+protocol.nick)

    def chat(self, contents, protocol):
        """
        CHAT is used to send data to every client connected to server
        """
        if protocol.nick is None:
            return self.errhandle('DATA:Unregistered user! register first.')

        for proto in clients.values():
            return self.send(protocol.nick, contents)

    def unregister(self, contents, protocol):
        """
        UNREGISTER causes the user to be unregistered and disconnected
        """

        if protocol.nick is not None and protocol.nick in self.clients:
            del self.clients[protocol.nick]

        protocol.transport.loseConnection()

    def send(self, nick, contents):
        protocol.sendLine('OK:DATA:'+nick+':'+contents)

    def errhandle(self, message, protocol=None):
        protocol.sendLine('ERR:'+message)

class ChatProtocol(LineReceiver):
    nick = None

    def lineReceived(self, line):
        cmd, data = line.split(':',1)
        self.factory.parser.dispatch(cmd, contents, self)

class ChatProtocolFactory(ServerFactory):
    protocol = ChatProtocol

    def __init__(self):
        self.parser = ParseData()

def main():
    """
    Creates reactor, and adds stuff for making connections
    """

    from twisted import reactor
    p = reactor.listenTCP(int(sys.argv[1]), ChatProtocolFactory(), interface='localhost')
    reactor.run()

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


<commit_before>from django.conf import settings

from zerver.lib.actions import do_change_is_admin
from zerver.lib.bulk_create import bulk_create_users
from zerver.models import Realm, UserProfile, email_to_username, get_client, \
    get_system_bot

from typing import Iterable, Optional, Set, Tuple

def create_internal_realm() -> None:
    internal_realm = Realm.objects.create(string_id=settings.SYSTEM_BOT_REALM)

    # Create the "website" and "API" clients:
    get_client("website")
    get_client("API")

    internal_realm_bots = [(bot['name'], bot['email_template'] % (settings.INTERNAL_BOT_DOMAIN,))
                           for bot in settings.INTERNAL_BOTS]
    create_users(internal_realm, internal_realm_bots, bot_type=UserProfile.DEFAULT_BOT)

    # Initialize the email gateway bot as an API Super User
    email_gateway_bot = get_system_bot(settings.EMAIL_GATEWAY_BOT)
    do_change_is_admin(email_gateway_bot, True, permission="api_super_user")

def create_users(realm: Realm, name_list: Iterable[Tuple[str, str]],
                 tos_version: Optional[str]=None,
                 bot_type: Optional[int]=None,
                 bot_owner: Optional[UserProfile]=None) -> None:
    user_set = set()  # type: Set[Tuple[str, str, str, bool]]
    for full_name, email in name_list:
        short_name = email_to_username(email)
        user_set.add((email, full_name, short_name, True))
    bulk_create_users(realm, user_set, bot_type=bot_type, bot_owner=bot_owner, tos_version=tos_version)
<commit_msg>server_initialization: Remove unnecessary type annotation.<commit_after>from django.conf import settings

from zerver.lib.actions import do_change_is_admin
from zerver.lib.bulk_create import bulk_create_users
from zerver.models import Realm, UserProfile, email_to_username, get_client, \
    get_system_bot

from typing import Iterable, Optional, Tuple

def create_internal_realm() -> None:
    internal_realm = Realm.objects.create(string_id=settings.SYSTEM_BOT_REALM)

    # Create the "website" and "API" clients:
    get_client("website")
    get_client("API")

    internal_realm_bots = [(bot['name'], bot['email_template'] % (settings.INTERNAL_BOT_DOMAIN,))
                           for bot in settings.INTERNAL_BOTS]
    create_users(internal_realm, internal_realm_bots, bot_type=UserProfile.DEFAULT_BOT)

    # Initialize the email gateway bot as an API Super User
    email_gateway_bot = get_system_bot(settings.EMAIL_GATEWAY_BOT)
    do_change_is_admin(email_gateway_bot, True, permission="api_super_user")

def create_users(realm: Realm, name_list: Iterable[Tuple[str, str]],
                 tos_version: Optional[str]=None,
                 bot_type: Optional[int]=None,
                 bot_owner: Optional[UserProfile]=None) -> None:
    user_set = set()
    for full_name, email in name_list:
        short_name = email_to_username(email)
        user_set.add((email, full_name, short_name, True))
    bulk_create_users(realm, user_set, bot_type=bot_type, bot_owner=bot_owner, tos_version=tos_version)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# client.py
#
# Copyright 2014 BitVault, Inc. dba Gem

import bitcoin

from .config import *
from wrappers import *
from errors import *
from developers import Developer, Developers
from users import User, Users
from applications import Application, Applications
from wallets import Wallet, Wallets
from accounts import Account, Accounts

from pprint import pprint as pp

class Client(object):

    def __init__(self, pb_client, network=DEFAULT_NETWORK):
        self.pb_client = pb_client
        try:
            self.network = NETWORK_MAP[network]
            bitcoin.SelectParams(self.network)
        except:
            raise UnknownNetworkError(network)
        self.context = self.pb_client.context
        self.resources = self.pb_client.resources
        self.developers = Developers(self.resources.developers, self)
        self.users = Users(self.resources.users, self)

    def authenticate(self, **kwargs):
        print u"client.authenticate() is DEPRECATED!"
        added = []
        if u'developer' in kwargs:
            added.append(self.authenticate_developer(**kwargs[u'developer']))
        if u'application' in kwargs:
            added.append(self.authenticate_application(**kwargs[u'application']))
        if u'device' in kwargs:
            added.append(self.authenticate_device(**kwargs[u'device']))
        if u'otp' in kwargs:
            added.append(self.authenticate_otp(**kwargs[u'otp']))
        if not added:
            raise ValueError(u"Supported authentication schemes are:\n{}".format(
                pp(client().schemes)))
        return added

    def authenticate_developer(self, email, privkey,
                               override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Developer'] and
            not override):
            raise ValueError(u"This object already has Gem-Developer authentication. To overwrite it call authenticate_developer with override=True.")

        if (not email or not privkey or
            not self.context.authorize(u'Gem-Developer', email=email, privkey=privkey)):
            raise ValueError("Usage: {}".format(
                self.context.schemes[u'Gem-Developer'][u'usage']))

        return self.developer if fetch else True

    def authenticate_application(self, app_url, api_token, instance_id,
                                 override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Application'] and
            not override):
            raise ValueError(u"This object already has Gem-Application authentication. To overwrite it call authenticate_application with override=True.")

        if (not app_url or not api_token or not instance_id or
            not self.context.authorize(u'Gem-Application',
                                       app_url=app_url,
                                       api_token=api_token,
                                       instance_id=instance_id)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-Application'][u'usage']))

        return self.application if fetch else True

    def authenticate_device(self, api_token, user_token, device_id, email=None,
                            user_url=None, override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Device'] and
            not override):
            raise ValueError(u"This object already has Gem-Device authentication. To overwrite it call authenticate_device with override=True.")

        if (not api_token or (not email and not user_url) or
            not user_token or not device_id or
            not self.context.authorize(u'Gem-Device',
                                       api_token=api_token,
                                       user_email=email,
                                       user_url=user_url,
                                       user_token=user_token,
                                       device_id=device_id)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-Device'][u'usage']))
        if fetch:
            user = self.user(email) if email else self.user()
            return user.refresh()
        else:
            return True

    def authenticate_otp(self, api_token, key, secret, override=True):
        if (u'credential' in self.context.schemes[u'Gem-OOB-OTP'] and
            not override):
            raise ValueError(u"This object already has Gem-OOB-OTP authentication. To overwrite it call authenticate_otp with override=True.")

        if (not api_token or not key or not secret or
            not self.context.authorize(u'Gem-OOB-OTP',
                                       api_token=api_token,
                                       key=key,
                                       secret=secret)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-OOB-OTP'][u'usage']))

        return True

    def begin_device_authorization(self, email, api_token, device_name,
                                   device_id):
        try:
            self.context.schemes[u'Gem-OOB-OTP'][u'credential'] = 'api_token="{}"'.format(api_token)
            reply = self.user(email).authorize_device({u'name': device_name,
                                                       u'device_id': device_id})
        except ResponseError as e:
            try:
                key = e.headers['WWW-Authenticate']['Gem-OOB-OTP'][u'key']
                return key
            except KeyError:
                if e.message == 'unauthorized':
                    raise OTPConflictError()
                else:
                    raise StandardError(e.message)
            except:
                raise e

    def complete_device_authorization(self, email, api_token, device_name,
                                      device_id, key, secret):
        try:
            self.authenticate_otp(api_token=api_token,
                                  key=key, secret=secret)

            r = self.user(email).authorize_device({u'name': device_name,
                                                   u'device_id': device_id})

        except ResponseError as e:
            try:
                new_key = e.headers['WWW-Authenticate']['Gem-OOB-OTP'][u'key']
                if new_key == key:
                    raise e
                else:
                    raise UnknownKeyError(new_key)
            except KeyError:
                raise e

        self.authenticate_device(api_token=api_token,
                                 user_url=r.url,
                                 user_token=r.user_token,
                                 device_id=device_id,
                                 override=True)

        return User(r, self)

    @property
    def developer(self):
        if not hasattr(self, u'_developer'):
            try:
                dev_resource = self.resources.developers.get()
                self._developer = Developer(dev_resource, self)
            except AttributeError as e:
                # TODO: Add AuthenticationError
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Developer'][u'usage']))

        return self._developer

    @property
    def application(self):
        if not hasattr(self, u'_application'):
            try:
                app_resource = self.resources.application(self.context.app_url).get()
                self._application = Application(app_resource, self)
            except AttributeError as e:
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Application'][u'usage']))

        return self._application

    def user(self, email=None):
        user_resource = False
        if not hasattr(self, '_user'):
            try:
                if email:
                    user_resource = self.resources.user_query({u'email': email})
                elif hasattr(self.context, u'user_url'):
                    user_resource = self.resources.user({u'url': self.context.user_url})
                else:
                    user_resource = self.resources.user_query({u'email': self.context.user_email})
            except AttributeError as e:
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Device'][u'usage']))

        elif email and (not hasattr(self._user, 'email') or
                        self._user.email != email):
            user_resource = self.resources.user_query({u'email': email})

        if user_resource:
            self._user = User(user_resource, self)
            # Fetch the user if we can. If not, we're probably just getting a
            # resource so we can do authorize_device.
            try:
                self._user.refresh()
            except:
                pass

        return self._user

    def wallet(self, url):
        # Not memoizing here, because a wallet is not a fundamental
        # part of a session, as a user or app would be.  Ditto account,
        # below.
        wallet_resource = self.resources.wallet(url).get()
        return Wallet(wallet_resource, self)

    def account(self, url):
        account_resource = self.resources.account(url)
        return Account(account_resource, self)
<commit_msg> when client.user is called with an email address, ALWAYS return a new user_resource with the email query parameter<commit_after># -*- coding: utf-8 -*-
# client.py
#
# Copyright 2014 BitVault, Inc. dba Gem

import bitcoin

from .config import *
from wrappers import *
from errors import *
from developers import Developer, Developers
from users import User, Users
from applications import Application, Applications
from wallets import Wallet, Wallets
from accounts import Account, Accounts

from pprint import pprint as pp

class Client(object):

    def __init__(self, pb_client, network=DEFAULT_NETWORK):
        self.pb_client = pb_client
        try:
            self.network = NETWORK_MAP[network]
            bitcoin.SelectParams(self.network)
        except:
            raise UnknownNetworkError(network)
        self.context = self.pb_client.context
        self.resources = self.pb_client.resources
        self.developers = Developers(self.resources.developers, self)
        self.users = Users(self.resources.users, self)

    def authenticate(self, **kwargs):
        print u"client.authenticate() is DEPRECATED!"
        added = []
        if u'developer' in kwargs:
            added.append(self.authenticate_developer(**kwargs[u'developer']))
        if u'application' in kwargs:
            added.append(self.authenticate_application(**kwargs[u'application']))
        if u'device' in kwargs:
            added.append(self.authenticate_device(**kwargs[u'device']))
        if u'otp' in kwargs:
            added.append(self.authenticate_otp(**kwargs[u'otp']))
        if not added:
            raise ValueError(u"Supported authentication schemes are:\n{}".format(
                pp(client().schemes)))
        return added

    def authenticate_developer(self, email, privkey,
                               override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Developer'] and
            not override):
            raise ValueError(u"This object already has Gem-Developer authentication. To overwrite it call authenticate_developer with override=True.")

        if (not email or not privkey or
            not self.context.authorize(u'Gem-Developer', email=email, privkey=privkey)):
            raise ValueError("Usage: {}".format(
                self.context.schemes[u'Gem-Developer'][u'usage']))

        return self.developer if fetch else True

    def authenticate_application(self, app_url, api_token, instance_id,
                                 override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Application'] and
            not override):
            raise ValueError(u"This object already has Gem-Application authentication. To overwrite it call authenticate_application with override=True.")

        if (not app_url or not api_token or not instance_id or
            not self.context.authorize(u'Gem-Application',
                                       app_url=app_url,
                                       api_token=api_token,
                                       instance_id=instance_id)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-Application'][u'usage']))

        return self.application if fetch else True

    def authenticate_device(self, api_token, user_token, device_id, email=None,
                            user_url=None, override=False, fetch=True):
        if (u'credential' in self.context.schemes[u'Gem-Device'] and
            not override):
            raise ValueError(u"This object already has Gem-Device authentication. To overwrite it call authenticate_device with override=True.")

        if (not api_token or (not email and not user_url) or
            not user_token or not device_id or
            not self.context.authorize(u'Gem-Device',
                                       api_token=api_token,
                                       user_email=email,
                                       user_url=user_url,
                                       user_token=user_token,
                                       device_id=device_id)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-Device'][u'usage']))
        if fetch:
            user = self.user(email) if email else self.user()
            return user.refresh()
        else:
            return True

    def authenticate_otp(self, api_token, key, secret, override=True):
        if (u'credential' in self.context.schemes[u'Gem-OOB-OTP'] and
            not override):
            raise ValueError(u"This object already has Gem-OOB-OTP authentication. To overwrite it call authenticate_otp with override=True.")

        if (not api_token or not key or not secret or
            not self.context.authorize(u'Gem-OOB-OTP',
                                       api_token=api_token,
                                       key=key,
                                       secret=secret)):
            raise ValueError(u"Usage: {}".format(
                self.context.schemes[u'Gem-OOB-OTP'][u'usage']))

        return True

    def begin_device_authorization(self, email, api_token, device_name,
                                   device_id):
        try:
            self.context.schemes[u'Gem-OOB-OTP'][u'credential'] = 'api_token="{}"'.format(api_token)
            reply = self.user(email).authorize_device({u'name': device_name,
                                                       u'device_id': device_id})
        except ResponseError as e:
            try:
                key = e.headers['WWW-Authenticate']['Gem-OOB-OTP'][u'key']
                return key
            except KeyError:
                if e.message == 'unauthorized':
                    raise OTPConflictError()
                else:
                    raise StandardError(e.message)
            except:
                raise e

    def complete_device_authorization(self, email, api_token, device_name,
                                      device_id, key, secret):
        try:
            self.authenticate_otp(api_token=api_token,
                                  key=key, secret=secret)

            r = self.user(email).authorize_device({u'name': device_name,
                                                   u'device_id': device_id})

        except ResponseError as e:
            try:
                new_key = e.headers['WWW-Authenticate']['Gem-OOB-OTP'][u'key']
                if new_key == key:
                    raise e
                else:
                    raise UnknownKeyError(new_key)
            except KeyError:
                raise e

        self.authenticate_device(api_token=api_token,
                                 user_url=r.url,
                                 user_token=r.user_token,
                                 device_id=device_id,
                                 override=True)

        return User(r, self)

    @property
    def developer(self):
        if not hasattr(self, u'_developer'):
            try:
                dev_resource = self.resources.developers.get()
                self._developer = Developer(dev_resource, self)
            except AttributeError as e:
                # TODO: Add AuthenticationError
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Developer'][u'usage']))

        return self._developer

    @property
    def application(self):
        if not hasattr(self, u'_application'):
            try:
                app_resource = self.resources.application(self.context.app_url).get()
                self._application = Application(app_resource, self)
            except AttributeError as e:
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Application'][u'usage']))

        return self._application

    def user(self, email=None):
        user_resource = False
        if not hasattr(self, '_user'):
            try:
                if email:
                    user_resource = self.resources.user_query({u'email': email})
                elif hasattr(self.context, u'user_url'):
                    user_resource = self.resources.user({u'url': self.context.user_url})
                else:
                    user_resource = self.resources.user_query({u'email': self.context.user_email})
            except AttributeError as e:
                raise AttributeError(
                    u"You must first authenticate this client with\n`{}`.".format(
                        self.context.schemes[u'Gem-Device'][u'usage']))

        elif email:
            user_resource = self.resources.user_query({u'email': email})

        if user_resource:
            self._user = User(user_resource, self)
            # Fetch the user if we can. If not, we're probably just getting a
            # resource so we can do authorize_device.
            try:
                self._user.refresh()
            except:
                pass

        return self._user

    def wallet(self, url):
        # Not memoizing here, because a wallet is not a fundamental
        # part of a session, as a user or app would be.  Ditto account,
        # below.
        wallet_resource = self.resources.wallet(url).get()
        return Wallet(wallet_resource, self)

    def account(self, url):
        account_resource = self.resources.account(url)
        return Account(account_resource, self)
<|endoftext|>


<commit_before>import re

from livestreamer.plugin import Plugin
from livestreamer.plugin.api import http
from livestreamer.stream import HLSStream

USER_AGENT = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 "
    "(KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"
)
HEADERS = {"User-Agent": USER_AGENT}
PLAYLIST_URL = "http://m.afreeca.com/live/stream/a/hls/broad_no/{0}"
CHANNEL_URL = "http://afbbs.afreeca.com:8080/api/video/get_bj_liveinfo.php"

_broadcast_re = re.compile(r".+\/(\d+)\.gif")
_url_re = re.compile("http(s)?://(\w+\.)?afreeca.com/(?P<username>\w+)")

class AfreecaTV(Plugin):
    @classmethod
    def can_handle_url(self, url):
        return _url_re.match(url)

    def _find_broadcast(self, username):
        res = http.get(CHANNEL_URL, headers=HEADERS, params=dict(szBjId=username))
        liveinfo = http.xml(res)
        thumb = liveinfo.findtext("thumb")
        if not thumb:
            return

        match = _broadcast_re.match(thumb)
        if match:
            return match.group(1)

    def _get_streams(self):
        match = _url_re.match(self.url)
        if not match:
            return

        username = match.group("username")
        broadcast = self._find_broadcast(username)
        if not broadcast:
            return

        playlist_url = PLAYLIST_URL.format(broadcast)
        return HLSStream.parse_variant_playlist(self.session, playlist_url,
                                                headers=HEADERS)

__plugin__ = AfreecaTV
<commit_msg>plugins.afreecatv: Fix weird connection issue.<commit_after>import re

from requests.adapters import HTTPAdapter

from livestreamer.plugin import Plugin
from livestreamer.plugin.api import http
from livestreamer.stream import HLSStream

USER_AGENT = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 "
    "(KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"
)
HEADERS = {"User-Agent": USER_AGENT}
PLAYLIST_URL = "http://m.afreeca.com/live/stream/a/hls/broad_no/{0}"
CHANNEL_URL = "http://afbbs.afreeca.com:8080/api/video/get_bj_liveinfo.php"

_broadcast_re = re.compile(r".+\/(\d+)\.gif")
_url_re = re.compile("http(s)?://(\w+\.)?afreeca.com/(?P<username>\w+)")

class RedirectAdapter(HTTPAdapter):
    """This adapter redirects connections on the socket level.

    This is done to keep the Host header the same but replace the
    actual server IP address used for the connection.
    """

    def __init__(self, *args, **kwargs):
        self.redirect_source = kwargs.pop("source")
        self.redirect_target = kwargs.pop("target")
        HTTPAdapter.__init__(self, *args, **kwargs)

    def get_connection(self, url, proxies=None):
        url = url.replace(self.redirect_source, self.redirect_target)
        return HTTPAdapter.get_connection(self, url, proxies=None)

class AfreecaTV(Plugin):
    @classmethod
    def can_handle_url(self, url):
        return _url_re.match(url)

    def _find_broadcast(self, username):
        res = http.get(CHANNEL_URL, headers=HEADERS, params=dict(szBjId=username))
        liveinfo = http.xml(res)
        thumb = liveinfo.findtext("thumb")
        if not thumb:
            return

        match = _broadcast_re.match(thumb)
        if match:
            return match.group(1)

    def _get_streams(self):
        match = _url_re.match(self.url)
        if not match:
            return

        username = match.group("username")
        broadcast = self._find_broadcast(username)
        if not broadcast:
            return

        playlist_url = PLAYLIST_URL.format(broadcast)
        return HLSStream.parse_variant_playlist(self.session, playlist_url,
                                                headers=HEADERS)

# Redirect 123.111.232.13 to 123.111.232.16
http.mount("http://123.111.232.13", RedirectAdapter(source="123.111.232.13",
                                                    target="123.111.232.16"))

__plugin__ = AfreecaTV
<|endoftext|>


<commit_before>"""
hellofriend.py
Author: <your name here>
Credit: <list sources used, if any>

Assignment:

Write and submit an interactive Python program that asks for the user's name and age,
then prints how much older Python is than the user (based on a simple comparison of
birth year). Python's first public release occurred in 1991. Something like this:

Please tell me your name: Guido
Please tell me your age: 16
Hello, Guido. Python is 8 years older than you are!

Note that the text: "Guido" and "16" are entered by the user running the program.
The final line ("Hello...") is generated dynamically when you run the program, based
on the name and age that the user enters.
"""
<commit_msg>Updated from Brython Server: 1/28/2016 2:23:17 PM<commit_after>"""
hellofriend.py
Author: <your name here>
Credit: <list sources used, if any>

Assignment:

Write and submit an interactive Python program that asks for the user's name and age,
then prints how much older Python is than the user (based on a simple comparison of
birth year). Python's first public release occurred in 1991. Something like this:

Please tell me your name: Guido
Please tell me your age: 16
Hello, Guido. Python is 8 years older than you are!

Note that the text: "Guido" and "16" are entered by the user running the program.
The final line ("Hello...") is generated dynamically when you run the program, based
on the name and age that the user enters.
"""
x = input("Hayden Hatfield")<|endoftext|>


<commit_before><commit_msg>[FIX] survey: Pass 'survey' when rendering 'nopages' template<commit_after><|endoftext|>


<commit_before>import time
import mraa

# Connect the Grove Air Quality Sensor to analog port A0
# SIG,NC,VCC,GND

get_sensor_value = True
air_sensor_value = 0
air_quality_sensor = mraa.Aio(0)

def main():
    while get_sensor_value:
        try:
            air_sensor_value = air_quality_sensor.readFloat()
            if air_sensor_value > 700:
                print "High pollution!"
            elif air_sensor_value > 300:
                print "Low pollution"
            else:
                print "Air is clean enough."

            print "Sensor value: " + air_sensor_value
            time.sleep(.5)
        except IOError:
            print "Can\'t read sensor. Stopping scanner."
            get_sensor_value = False

main()
<commit_msg>Fixed for real this time.<commit_after>import time
import mraa

# Connect the Grove Air Quality Sensor to analog port A0
# SIG,NC,VCC,GND

get_sensor_value = True
air_sensor_value = 0
air_quality_sensor = mraa.Aio(0)

def main():
    while get_sensor_value:
        try:
            air_sensor_value = air_quality_sensor.readFloat()
            if air_sensor_value > 700:
                print "High pollution!"
            elif air_sensor_value > 300:
                print "Low pollution"
            else:
                print "Air is clean enough."

            print "Sensor value: ", air_sensor_value
            time.sleep(.5)
        except KeyboardInterrupt:
            break
        except IOError:
            print "Can\'t read sensor."

main()
<|endoftext|>


<commit_before>"""bslint.bslint: provides entry point main()."""
__version__ = "0.4.4"

import os
import sys

import bslint
import bslint.constants as const

is_lexed_correctly = True
files = []

def main():
    print(const.TITLE_COLOUR + "BSLint: A linter for BrightScript. %s. \n" % __version__ + const.END_COLOUR)
    global is_lexed_correctly
    try:
        manifest_path = find_manifest()
    except FileNotFoundError:
        manifest_path = None
        print(const.ERROR_COLOUR + "No manifest file found" + const.END_COLOUR)

    try:
        bslintrc = read_bslintrc(manifest_path)
    except FileNotFoundError:
        print(const.ERROR_COLOUR + "No .bslintrc file found" + const.END_COLOUR)
        bslintrc = {"ignore": ""}

    if is_not_specific_path():
        pathname = os.getcwd()
        lint_all(pathname, bslintrc["ignore"])
    else:
        filename = sys.argv[1]
        if not os.path.exists(filename):
            is_lexed_correctly = False

        if os.path.isfile(filename):
            lint_specific(filename)
        else:
            lint_all(filename, bslintrc["ignore"])
    if is_lexed_correctly:
        print(const.PASS_COLOUR + 'All lexed correctly' + const.END_COLOUR)
        print("\n")

def lint_all(directory, directories_to_ignore):
    for dirName, subdirList, files in os.walk(directory):
        if not ignore_dir(get_relative_path(dirName, directory), directories_to_ignore):
            for file in files:
                if file.endswith(".brs") or file.endswith(".bs"):
                    filepath = os.path.join(dirName, file)
                    lint_specific(filepath)

def get_relative_path(dirName, directory):
    return dirName.replace(directory, '')

def ignore_dir(relative_directory_path, directories_to_ignore):
    for directory in directories_to_ignore:
        directory = add_slashes_to_dir(directory)
        relative_directory_path = add_slashes_to_dir(relative_directory_path)
        if relative_directory_path.startswith(directory):
            return True
    return False

def add_slashes_to_dir(directory):
    if not directory.startswith("/"):
        directory = "/" + directory
    if not directory.endswith("/"):
        directory += "/"
    return directory

def lint_specific(filename):
    filename = filename.replace(os.getcwd() + '/', '')
    if filename.endswith(".brs") or filename.endswith(".bs"):
        files.append(filename)
        file_reader = bslint.FileReader()
        read_file = file_reader.read_file(filename)
        lexer = bslint.Lexer()
        if read_file["invalid_encoding"]:
            print(read_file["invalid_encoding"])

        lex_result = lexer.lex(read_file['str_to_lex'])
        if lex_result["Status"] == "Error" or lex_result["Warnings"]:
            global is_lexed_correctly
            is_lexed_correctly = False
            print(const.FILE_COLOUR + filename + const.END_COLOUR)
            if lex_result["Status"] == "Error":
                for error in lex_result["Tokens"]:
                    print(const.ERROR_COLOUR + str(error) + const.END_COLOUR)
            for warning in lex_result["Warnings"]:
                print(const.WARNING_COLOUR + str(warning) + const.END_COLOUR)
            print("\n")
    else:
        is_lexed_correctly = False

def find_manifest():
    if is_not_specific_path():
        upper_dir = ""
    else:
        if os.path.isfile(sys.argv[1]):
            upper_dir = os.path.dirname(sys.argv[1])
        else:
            upper_dir = sys.argv[1]
    count = 0
    manifest_path_upper = os.path.join(upper_dir, "MANIFEST")
    manifest_path_lower = os.path.join(upper_dir, "manifest")
    while not os.path.exists(manifest_path_upper) and not os.path.exists(manifest_path_lower) and count < 5:
        upper_dir += "../"
        count += 1
    if count == 5:
        raise FileNotFoundError
    return upper_dir

def read_bslintrc(manifest_dir):
    if manifest_dir is not None:
        bslintrc = bslint.config_loader.read_json(os.path.join(manifest_dir, ".bslintrc"))
    else:
        raise FileNotFoundError
    return bslintrc

def runner(to_lex=None):
    global files
    files = []
    sys.argv = [sys.argv[0]]
    if to_lex is not None:
        sys.argv.append(os.path.join(os.getcwd(), to_lex))
    else:
        sys.argv.append(os.getcwd())
    main()
    return files

def is_not_specific_path():
    return len(sys.argv) == 1<commit_msg>Fixed some command line functionality, more tests to follow...<commit_after>"""bslint.bslint: provides entry point main()."""
__version__ = "0.4.4"

import os
import sys

import bslint
import bslint.constants as const

is_lexed_correctly = True
files = []

def main():
    print(const.TITLE_COLOUR + "BSLint: A linter for BrightScript. %s. \n" % __version__ + const.END_COLOUR)
    global is_lexed_correctly
    try:
        manifest_path = find_manifest()
    except FileNotFoundError:
        manifest_path = None
        print(const.ERROR_COLOUR + "No manifest file found" + const.END_COLOUR)

    try:
        bslintrc = read_bslintrc(manifest_path)
    except FileNotFoundError:
        print(const.ERROR_COLOUR + "No .bslintrc file found" + const.END_COLOUR)
        bslintrc = {"ignore": ""}

    if is_not_specific_path():
        pathname = os.getcwd()
        lint_all(pathname, bslintrc["ignore"], manifest_path)
    else:
        filename = sys.argv[1]
        if not os.path.exists(filename):
            is_lexed_correctly = False

        if os.path.isfile(filename):
            lint_specific(filename)
        else:
            lint_all(filename, bslintrc["ignore"], manifest_path)
    if is_lexed_correctly:
        print(const.PASS_COLOUR + 'All lexed correctly' + const.END_COLOUR)
        print("\n")

def lint_all(directory, directories_to_ignore, manifest_path):
    for dirName, subdirList, files in os.walk(directory):
        if not ignore_dir(get_relative_path(dirName, manifest_path), directories_to_ignore):
            for file in files:
                if file.endswith(".brs") or file.endswith(".bs"):
                    filepath = os.path.join(dirName, file)
                    lint_specific(filepath)

def get_relative_path(dirName, directory):
    directory = os.path.realpath(os.path.join(os.getcwd(), directory))
    return dirName.replace(directory, '')

def ignore_dir(relative_directory_path, directories_to_ignore):
    for directory in directories_to_ignore:
        directory = add_slashes_to_dir(directory)
        relative_directory_path = add_slashes_to_dir(relative_directory_path)

        if relative_directory_path.startswith(directory):
            return True
    return False

def add_slashes_to_dir(directory):
    if not directory.startswith("/"):
        directory = "/" + directory
    if not directory.endswith("/"):
        directory += "/"
    return directory

def lint_specific(filename):
    filename = filename.replace(os.getcwd() + '/', '')
    if filename.endswith(".brs") or filename.endswith(".bs"):
        files.append(filename)
        file_reader = bslint.FileReader()
        read_file = file_reader.read_file(filename)
        lexer = bslint.Lexer()
        if read_file["invalid_encoding"]:
            print(read_file["invalid_encoding"])
        lex_result = lexer.lex(read_file['str_to_lex'])
        if lex_result["Status"] == "Error" or lex_result["Warnings"]:
            global is_lexed_correctly
            is_lexed_correctly = False
            print(const.FILE_COLOUR + filename + const.END_COLOUR)
            if lex_result["Status"] == "Error":
                for error in lex_result["Tokens"]:
                    print(const.ERROR_COLOUR + str(error) + const.END_COLOUR)
            for warning in lex_result["Warnings"]:
                print(const.WARNING_COLOUR + str(warning) + const.END_COLOUR)
            print("\n")
    else:
        is_lexed_correctly = False

def find_manifest():
    if is_not_specific_path():
        upper_dir = ""
    else:
        if os.path.isfile(sys.argv[1]):
            upper_dir = os.path.dirname(sys.argv[1])
        else:
            upper_dir = sys.argv[1]
    count = 0
    while no_manifest_in_folder(upper_dir) and count < 5:
        upper_dir = os.path.join(upper_dir, "../")
        count += 1
    if count == 5:
        raise FileNotFoundError
    return upper_dir

def no_manifest_in_folder(upper_dir):
    return not os.path.exists(os.path.join(upper_dir, "MANIFEST")) and not os.path.exists(
        os.path.join(upper_dir, "manifest"))

def read_bslintrc(manifest_dir):
    if manifest_dir is not None:
        bslintrc = bslint.config_loader.read_json(os.path.join(manifest_dir, ".bslintrc"))
    else:
        raise FileNotFoundError
    return bslintrc

def runner(to_lex=None):
    global files
    files = []
    sys.argv = [sys.argv[0]]
    if to_lex is not None:
        sys.argv.append(os.path.join(os.getcwd(), to_lex))
    else:
        sys.argv.append(os.getcwd())
    main()
    return files

def is_not_specific_path():
    return len(sys.argv) == 1<|endoftext|>


<commit_before><commit_msg>tests<commit_after><|endoftext|>


<commit_before>import pandas as pd
import numpy as np
import scipy as sp

class Analysis:

    def __init__(self, price_df, income_df=None):
        self.price_df = price_df
        if income_df:
            self.income_df = income_df

        self.start_date = price_df.index[0]
        self.end_date = price_df.index[-1]

        self.return_df = self.return_data()

    def key_metrics(self):
        """ used to print a summary of the data of the analysis """

        print("\n--- Key Metrics of Analysis ---\n")

        print("Start Date = {date}".format(date=self.start_date))
        print("End Date = {date}".format(date=self.end_date))

        print("{asset} assets analysed\n".format(asset=len(self.price_df.columns)))

        for asset in self.price_df.columns:
            print(asset)
            print("Start Price: {price}".format(price=self.price_df.loc[self.start_date, asset]))
            print("End Price: {price}\n\n".format(price=self.price_df.loc[self.end_date, asset]))

            # add income and returns

    def return_data(self):
        """ create the returns dataframe in percent """

        return self.price_df.pct_change() * 100

    def covariance_matrix(self):
        """ covariance matrix """

        return self.return_df.cov()
<commit_msg>remove scipy import<commit_after>import pandas as pd
import numpy as np

class Analysis:

    def __init__(self, price_df, income_df=None):
        self.price_df = price_df
        if income_df:
            self.income_df = income_df

        self.start_date = price_df.index[0]
        self.end_date = price_df.index[-1]

        self.return_df = self.return_data()

    def key_metrics(self):
        """ used to print a summary of the data of the analysis """

        print("\n--- Key Metrics of Analysis ---\n")

        print("Start Date = {date}".format(date=self.start_date))
        print("End Date = {date}".format(date=self.end_date))

        print("{asset} assets analysed\n".format(asset=len(self.price_df.columns)))

        for asset in self.price_df.columns:
            print(asset)
            print("Start Price: {price}".format(price=self.price_df.loc[self.start_date, asset]))
            print("End Price: {price}\n\n".format(price=self.price_df.loc[self.end_date, asset]))

            # add income and returns

    def return_data(self):
        """ create the returns dataframe in percent """

        return self.price_df.pct_change() * 100

    def covariance_matrix(self):
        """ covariance matrix """

        return self.return_df.cov()
<|endoftext|>


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

'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
from mock.mock import MagicMock, call, patch
from stacks.utils.RMFTestCase import *

class TestSqoopServiceCheck(RMFTestCase):
  COMMON_SERVICES_PACKAGE_DIR = "SQOOP/1.4.4.2.0/package"
  STACK_VERSION = "2.0.6"

  def test_service_check_secured(self):
    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
                       classname = "SqoopServiceCheck",
                       command = "service_check",
                       config_file="secured.json",
                       hdp_stack_version = self.STACK_VERSION,
                       target = RMFTestCase.TARGET_COMMON_SERVICES
    )
    self.assertResourceCalled('Execute', '/usr/bin/kinit  -kt /etc/security/keytabs/smokeuser.headless.keytab ambari-qa@EXAMPLE.COM',
                              user = 'ambari-qa'
    )
    self.assertResourceCalled('Execute', 'sqoop version',
                              logoutput = True,
                              path = ['/usr/bin'],
                              user = 'ambari-qa',)
    self.assertNoMoreResources()

  def test_service_check_default(self):
    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
                       classname = "SqoopServiceCheck",
                       command = "service_check",
                       config_file="default.json",
                       hdp_stack_version = self.STACK_VERSION,
                       target = RMFTestCase.TARGET_COMMON_SERVICES
    )
    self.assertResourceCalled('Execute', 'sqoop version',
                              logoutput = True,
                              path = ['/usr/bin'],
                              user = 'ambari-qa',)
    self.assertNoMoreResources()

<commit_msg>AMBARI-10476. TestSqoopServiceCheck unit test fails due to AMBARI-10452 (rlevas)<commit_after>#!/usr/bin/env python

'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
from mock.mock import MagicMock, call, patch
from stacks.utils.RMFTestCase import *
from resource_management.libraries.functions import get_kinit_path

class TestSqoopServiceCheck(RMFTestCase):
  COMMON_SERVICES_PACKAGE_DIR = "SQOOP/1.4.4.2.0/package"
  STACK_VERSION = "2.0.6"

  def test_service_check_secured(self):
    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
                       classname = "SqoopServiceCheck",
                       command = "service_check",
                       config_file="secured.json",
                       hdp_stack_version = self.STACK_VERSION,
                       target = RMFTestCase.TARGET_COMMON_SERVICES
    )
    kinit_path_local = get_kinit_path()
    self.assertResourceCalled('Execute', kinit_path_local + '  -kt /etc/security/keytabs/smokeuser.headless.keytab ambari-qa@EXAMPLE.COM',
                              user = 'ambari-qa'
    )
    self.assertResourceCalled('Execute', 'sqoop version',
                              logoutput = True,
                              path = ['/usr/bin'],
                              user = 'ambari-qa',)
    self.assertNoMoreResources()

  def test_service_check_default(self):
    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
                       classname = "SqoopServiceCheck",
                       command = "service_check",
                       config_file="default.json",
                       hdp_stack_version = self.STACK_VERSION,
                       target = RMFTestCase.TARGET_COMMON_SERVICES
    )
    self.assertResourceCalled('Execute', 'sqoop version',
                              logoutput = True,
                              path = ['/usr/bin'],
                              user = 'ambari-qa',)
    self.assertNoMoreResources()

<|endoftext|>


<commit_before>import flask
import json
import collections
import random
import flask.ext.socketio as socketio
import time
import edgy
import database
import settings

class keydefaultdict(collections.defaultdict):
	"""collections.defaultdict except the key is passed to the default_factory

	I got this off Stack Overflow: http://stackoverflow.com/a/2912455/2002307
	"""
	def __missing__(self, key):
		if self.default_factory is None:
			raise KeyError(key)
		else:
			ret = self[key] = self.default_factory(key)
		return ret

def make_humane_gibberish(length):
	"""Generate a meaningless but human-friendly string.

	Characters are chosen so that no two characters are alike.
	Easily confused characters, such as '1' and 'l' are also excluded.
	"""
	result = ''
	for i in range(length):
		result += random.choice('ACEFHJKNPQRTVXY34869')
	return result

def time_current():
	"""Returns the number of second since the epoch."""
	return int(time.time())

def time_breakdown(t):
	"""Takes time as seconds-since epoch and breaks it down into human-friendly values."""
	t = max(0, t)
	return {
		'seconds': t % 60,
		'minutes': (t // 60) % 60,
		'hours': (t // 3600) % 24,
		'days': t // 86400
	}

class Whiteboard:
	"""Object representing a single whiteboard.

	This interfaces with the database on the backend.

		has_loaded :: whether the content have been loaded
		layers :: the list of actions that have been performed on the whiteboard
		timestamp :: the time at which the whiteboard was last modified
		permissions :: string, either 'open', 'presentation', or 'private'
		key :: string used to identify who has access to the whiteboard
		owner_key :: string used to identify who owns (created) the whiteboard
	"""
	def __init__(self, name):
		"""Initialise a whiteboard object

		Initially, the contents of the whiteboard has not been loaded.
		"""
		self.has_loaded = False
		self.layers = []
		self.timestamp = 0
		self.permissions = 'open'
		self.key = ''
		self.owner_key = ''
		self.name = name

	def ensure_loaded(self):
		"""Load the whiteboard's contents if they haven't been already"""
		if not self.has_loaded:
			self.load_everything()
			self.save_everything()

	def load_everything(self):
		"""Load all the data from the database"""
		data = database.load(self.name)
		if data:
			# Using get will allow backwards compatibility in the future
			self.key = data.get('key', '')
			self.owner_key = data.get('owner_key', '')
			self.layers = data.get('layers', [])
			self.timestamp = data.get('timestamp', time_current())
		self.has_loaded = True

	def save_everything(self):
		"""Save all the data to the database"""
		self.ensure_loaded()
		payload = {
			'layers': self.layers,
			'key': self.key,
			'owner_key': self.owner_key,
			'timestamp': self.timestamp
		}
		database.rewrite(self.name, payload)

	def update_time(self):
		"""Change the modification timestamp to the current time"""
		self.timestamp = time_current()

	def full_image(self):
		"""Returns a copy of the whiteboard contents, for sending to the cient"""
		self.ensure_loaded()
		self.update_time()
		return self.layers[:]

	def add_action(self, action):
		"""Add a paint action to the whiteboard"""
		self.ensure_loaded()
		self.update_time()
		self.layers.append(action)
		database.action_push(self.name, action, self.timestamp)

	def undo_action(self, action):
		"""Remove a paint action from the whiteboard"""
		self.ensure_loaded()
		self.update_time()
		self.layers = [i for i in self.layers if i['action_id'] != action]
		database.action_remove(self.name, action, self.timestamp)

	def make_protected(self):
		"""Set the whiteboard to be 'protected'

		Will regenerate keys even if the whiteboard is already protected"""
		self.ensure_loaded()
		self.permissions = 'protected'
		self.key = make_humane_gibberish(6)
		self.owner_key = make_humane_gibberish(30)
		self.save_everything()

	def make_private(self):
		"""Set the whiteboard to be 'private'

		Will regenerate keys even if the whiteboard is already private"""
		self.ensure_loaded()
		self.permissions = 'private'
		self.key = make_humane_gibberish(6)
		self.owner_key = make_humane_gibberish(30)
		self.save_everything()

	def unlock(self):
		"""Sets the whiteboard to be publically accessible (by those with the link)"""
		self.ensure_loaded()
		self.permissions = 'open'
		self.save_everything()

	def may_view(self, key):
		"""Checks if someone with the given key may view the whiteboard"""
		self.ensure_loaded()
		return self.permissions in ['open', 'protected'] or key in [self.key, self.owner_key]

	def may_edit(self, key):
		"""Checks if someone with the given key may edit the whiteboard"""
		self.ensure_loaded()
		return self.permissions == 'open' or key in [self.key, self.owner_key]

# Create a dictioary of whiteboards and load the whiteboard metadata

whiteboards = keydefaultdict(lambda name: Whiteboard(name))

for i in database.load_meta():
	whiteboards[i['name']].timestamp = i['timestamp']

# Create the flask server and the socket.io handler

app = flask.Flask(__name__)
app.debug = True

sock = socketio.SocketIO(app)

def make_board_id():
	"""Generates an unused board id"""
	attempts = 0
	board_id = make_humane_gibberish(4)
	# Every time a clash occurs, increase the length of the ID by one
	# in order to avoid problems with the birthday paradox.
	# Initially having the key to be small ensures that links remain human readable.
	while board_id in whiteboards:
		board_id = make_humane_gibberish(attempts + 4)
		attempts += 1
	return board_id

def make_board(permissions = 'open', board_id = None):
	"""Creates a new board with specifc permissions"""
	board_id = board_id or make_board_id()
	whiteboards[board_id]
	if permissions == 'protected':
		whiteboards[board_id].make_protected()
	if permissions == 'private':
		whiteboards[board_id].make_private()
	return (board_id, whiteboards[board_id].owner_key)

# Set up routing for the information pages (home, about, etc...)

@app.route('/')
def serve_index():
	return flask.render_template('index.tpl')

@app.route('/about')
def serve_about():
	return flask.render_template('about.tpl')

# URLs that create new whiteboards. They create a new whiteboard and
# then automatically redirect the user there.

@app.route('/docs')
def serve_docs():
	return flask.render_template('docs.tpl')

@app.route('/legal')
def serve_legal():
	return flask.render_template('legal.tpl')

@app.route('/new')
def server_board_new():
	board_id, key = make_board()
	return flask.redirect('/board/' + board_id)

@app.route('/new/protected')
def server_board_new_protected():
	board_id, key = make_board(permissions = 'protected')
	response = flask.make_response(flask.redirect('/board/' + board_id))
	response.set_cookie('key_' + board_id, key)
	return response

@app.route('/new/private')
def server_board_new_private():
	board_id, key = make_board(permissions = 'private')
	response = flask.make_response(flask.redirect('/board/' + board_id))
	response.set_cookie('key_' + board_id, key)
	return response

# Serves up a list of existant whiteboards.
# Used for debugging purposes only.
# TODO: Add a password to this page, don't let normal users see it.

@app.route('/listing')
def serve_listing():
	boards = []
	for i in whiteboards:
		time_diff = time_current() - whiteboards[i].timestamp
		timeparts = time_breakdown(time_diff)
		rec_str = '{days} days, {hours} hours, {minutes} minutes, {seconds} seconds'.format(**timeparts)
		boards.append({
			'name': i,
			'recency': 	rec_str
		})
	return flask.render_template('listing.tpl', boards = boards)

# Serve the board
# Both '/board/x' and '/b/x' are supported for convinience

@app.route('/board/<board_id>')
@app.route('/b/<board_id>')
def serve_board(board_id):
	board_id = board_id.upper()
	board = whiteboards[board_id]
	key = flask.request.cookies.get('key_' + board_id)
	if board.may_view(key):
		show_controls = board.may_edit(key)
		return flask.render_template(
			'whiteboard.tpl',
			board_id = board_id,
			show_controls = show_controls,
			permissions = board.permissions,
			feedback_form = settings.get('feedback_form')
		)
	else:
		flask.abort(403)

# Serve static files

@app.route('/static/<path:path>')
def serve_static(path):
	print('Serving static: ', path)
	return flask.send_from_directory('static', path)

# Load the paint action schema into a constant.

def load_schema(name):
	text = open('schemas/' + name + '.json').read()
	return json.loads(text)

SCHEMA_PAINT = load_schema('paint')

# Handle incomming paint event.

@sock.on('paint')
def socketio_paint(message):
	# print('paint', message)
	# Ensure the paint action is valid
	if edgy.check(SCHEMA_PAINT, message):
		bid = message['board_id'].upper()
		key = message['key']
		board = whiteboards[bid]
		# Ensure the user has the correct permissions
		if board.may_edit(key):
			# Add the action to the whiteboard
			board.add_action(message)
			# Transmit the action to all other clients
			data = {
				'board_id': bid,
				'actions': [
					message
				]
			}
			socketio.emit('paint', data, broadcast = True, room = bid)
	else:
		print('A paint action failed')
		print(message)

# Fired when the user joins the whiteboard.

@sock.on('full image')
def socketio_full_image(message):
	# print('full image', message)
	bid = message['board_id'].upper()
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user may see this board
	if board.may_view(key):
		socketio.join_room(bid)
		data = {
			'board_id': bid,
			'actions': board.full_image()
		}
		socketio.emit('paint', data)

# Fired when a user attempts to undo an action

@sock.on('undo')
def socketio_undo(message):
	bid = message['board_id'].upper()
	aid = message['action_id']
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user has permission to edit the board
	if board.may_edit(key):
		# Remove the action from the board
		board.undo_action(aid)
		# Tell other clients the action has been undone
		data = {
			'board_id': bid,
			'action_id': aid
		}
		socketio.emit('undo', data, broadcast = True, room = bid)

# Fired when a user attmpts to unlock a whiteboard

@sock.on('unlock')
def socketio_unlock(message):
	bid = message['board_id'].upper()
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user has permission to do so
	if board.may_edit(key):
		board.unlock()
		# Tells the other client that the board has been unlocked
		# this will cause the browsers to refresh the page
		socketio.emit('refresh', broadcast = True, room = bid)

# Run the server

if __name__ == '__main__':
	port = int(settings.get('port'))
	sock.run(app, host = '0.0.0.0', port = port)
<commit_msg>Moved an out-of-place comment<commit_after>import flask
import json
import collections
import random
import flask.ext.socketio as socketio
import time
import edgy
import database
import settings

class keydefaultdict(collections.defaultdict):
	"""collections.defaultdict except the key is passed to the default_factory

	I got this off Stack Overflow: http://stackoverflow.com/a/2912455/2002307
	"""
	def __missing__(self, key):
		if self.default_factory is None:
			raise KeyError(key)
		else:
			ret = self[key] = self.default_factory(key)
		return ret

def make_humane_gibberish(length):
	"""Generate a meaningless but human-friendly string.

	Characters are chosen so that no two characters are alike.
	Easily confused characters, such as '1' and 'l' are also excluded.
	"""
	result = ''
	for i in range(length):
		result += random.choice('ACEFHJKNPQRTVXY34869')
	return result

def time_current():
	"""Returns the number of second since the epoch."""
	return int(time.time())

def time_breakdown(t):
	"""Takes time as seconds-since epoch and breaks it down into human-friendly values."""
	t = max(0, t)
	return {
		'seconds': t % 60,
		'minutes': (t // 60) % 60,
		'hours': (t // 3600) % 24,
		'days': t // 86400
	}

class Whiteboard:
	"""Object representing a single whiteboard.

	This interfaces with the database on the backend.

		has_loaded :: whether the content have been loaded
		layers :: the list of actions that have been performed on the whiteboard
		timestamp :: the time at which the whiteboard was last modified
		permissions :: string, either 'open', 'presentation', or 'private'
		key :: string used to identify who has access to the whiteboard
		owner_key :: string used to identify who owns (created) the whiteboard
	"""
	def __init__(self, name):
		"""Initialise a whiteboard object

		Initially, the contents of the whiteboard has not been loaded.
		"""
		self.has_loaded = False
		self.layers = []
		self.timestamp = 0
		self.permissions = 'open'
		self.key = ''
		self.owner_key = ''
		self.name = name

	def ensure_loaded(self):
		"""Load the whiteboard's contents if they haven't been already"""
		if not self.has_loaded:
			self.load_everything()
			self.save_everything()

	def load_everything(self):
		"""Load all the data from the database"""
		data = database.load(self.name)
		if data:
			# Using get will allow backwards compatibility in the future
			self.key = data.get('key', '')
			self.owner_key = data.get('owner_key', '')
			self.layers = data.get('layers', [])
			self.timestamp = data.get('timestamp', time_current())
		self.has_loaded = True

	def save_everything(self):
		"""Save all the data to the database"""
		self.ensure_loaded()
		payload = {
			'layers': self.layers,
			'key': self.key,
			'owner_key': self.owner_key,
			'timestamp': self.timestamp
		}
		database.rewrite(self.name, payload)

	def update_time(self):
		"""Change the modification timestamp to the current time"""
		self.timestamp = time_current()

	def full_image(self):
		"""Returns a copy of the whiteboard contents, for sending to the cient"""
		self.ensure_loaded()
		self.update_time()
		return self.layers[:]

	def add_action(self, action):
		"""Add a paint action to the whiteboard"""
		self.ensure_loaded()
		self.update_time()
		self.layers.append(action)
		database.action_push(self.name, action, self.timestamp)

	def undo_action(self, action):
		"""Remove a paint action from the whiteboard"""
		self.ensure_loaded()
		self.update_time()
		self.layers = [i for i in self.layers if i['action_id'] != action]
		database.action_remove(self.name, action, self.timestamp)

	def make_protected(self):
		"""Set the whiteboard to be 'protected'

		Will regenerate keys even if the whiteboard is already protected"""
		self.ensure_loaded()
		self.permissions = 'protected'
		self.key = make_humane_gibberish(6)
		self.owner_key = make_humane_gibberish(30)
		self.save_everything()

	def make_private(self):
		"""Set the whiteboard to be 'private'

		Will regenerate keys even if the whiteboard is already private"""
		self.ensure_loaded()
		self.permissions = 'private'
		self.key = make_humane_gibberish(6)
		self.owner_key = make_humane_gibberish(30)
		self.save_everything()

	def unlock(self):
		"""Sets the whiteboard to be publically accessible (by those with the link)"""
		self.ensure_loaded()
		self.permissions = 'open'
		self.save_everything()

	def may_view(self, key):
		"""Checks if someone with the given key may view the whiteboard"""
		self.ensure_loaded()
		return self.permissions in ['open', 'protected'] or key in [self.key, self.owner_key]

	def may_edit(self, key):
		"""Checks if someone with the given key may edit the whiteboard"""
		self.ensure_loaded()
		return self.permissions == 'open' or key in [self.key, self.owner_key]

# Create a dictioary of whiteboards and load the whiteboard metadata

whiteboards = keydefaultdict(lambda name: Whiteboard(name))

for i in database.load_meta():
	whiteboards[i['name']].timestamp = i['timestamp']

# Create the flask server and the socket.io handler

app = flask.Flask(__name__)
app.debug = True

sock = socketio.SocketIO(app)

def make_board_id():
	"""Generates an unused board id"""
	attempts = 0
	board_id = make_humane_gibberish(4)
	# Every time a clash occurs, increase the length of the ID by one
	# in order to avoid problems with the birthday paradox.
	# Initially having the key to be small ensures that links remain human readable.
	while board_id in whiteboards:
		board_id = make_humane_gibberish(attempts + 4)
		attempts += 1
	return board_id

def make_board(permissions = 'open', board_id = None):
	"""Creates a new board with specifc permissions"""
	board_id = board_id or make_board_id()
	whiteboards[board_id]
	if permissions == 'protected':
		whiteboards[board_id].make_protected()
	if permissions == 'private':
		whiteboards[board_id].make_private()
	return (board_id, whiteboards[board_id].owner_key)

# Set up routing for the information pages (home, about, etc...)

@app.route('/')
def serve_index():
	return flask.render_template('index.tpl')

@app.route('/about')
def serve_about():
	return flask.render_template('about.tpl')

@app.route('/docs')
def serve_docs():
	return flask.render_template('docs.tpl')

@app.route('/legal')
def serve_legal():
	return flask.render_template('legal.tpl')

# URLs that create new whiteboards. They create a new whiteboard and
# then automatically redirect the user there.

@app.route('/new')
def server_board_new():
	board_id, key = make_board()
	return flask.redirect('/board/' + board_id)

@app.route('/new/protected')
def server_board_new_protected():
	board_id, key = make_board(permissions = 'protected')
	response = flask.make_response(flask.redirect('/board/' + board_id))
	response.set_cookie('key_' + board_id, key)
	return response

@app.route('/new/private')
def server_board_new_private():
	board_id, key = make_board(permissions = 'private')
	response = flask.make_response(flask.redirect('/board/' + board_id))
	response.set_cookie('key_' + board_id, key)
	return response

# Serves up a list of existant whiteboards.
# Used for debugging purposes only.
# TODO: Add a password to this page, don't let normal users see it.

@app.route('/listing')
def serve_listing():
	boards = []
	for i in whiteboards:
		time_diff = time_current() - whiteboards[i].timestamp
		timeparts = time_breakdown(time_diff)
		rec_str = '{days} days, {hours} hours, {minutes} minutes, {seconds} seconds'.format(**timeparts)
		boards.append({
			'name': i,
			'recency': 	rec_str
		})
	return flask.render_template('listing.tpl', boards = boards)

# Serve the board
# Both '/board/x' and '/b/x' are supported for convinience

@app.route('/board/<board_id>')
@app.route('/b/<board_id>')
def serve_board(board_id):
	board_id = board_id.upper()
	board = whiteboards[board_id]
	key = flask.request.cookies.get('key_' + board_id)
	if board.may_view(key):
		show_controls = board.may_edit(key)
		return flask.render_template(
			'whiteboard.tpl',
			board_id = board_id,
			show_controls = show_controls,
			permissions = board.permissions,
			feedback_form = settings.get('feedback_form')
		)
	else:
		flask.abort(403)

# Serve static files

@app.route('/static/<path:path>')
def serve_static(path):
	print('Serving static: ', path)
	return flask.send_from_directory('static', path)

# Load the paint action schema into a constant.

def load_schema(name):
	text = open('schemas/' + name + '.json').read()
	return json.loads(text)

SCHEMA_PAINT = load_schema('paint')

# Handle incomming paint event.

@sock.on('paint')
def socketio_paint(message):
	# print('paint', message)
	# Ensure the paint action is valid
	if edgy.check(SCHEMA_PAINT, message):
		bid = message['board_id'].upper()
		key = message['key']
		board = whiteboards[bid]
		# Ensure the user has the correct permissions
		if board.may_edit(key):
			# Add the action to the whiteboard
			board.add_action(message)
			# Transmit the action to all other clients
			data = {
				'board_id': bid,
				'actions': [
					message
				]
			}
			socketio.emit('paint', data, broadcast = True, room = bid)
	else:
		print('A paint action failed')
		print(message)

# Fired when the user joins the whiteboard.

@sock.on('full image')
def socketio_full_image(message):
	# print('full image', message)
	bid = message['board_id'].upper()
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user may see this board
	if board.may_view(key):
		socketio.join_room(bid)
		data = {
			'board_id': bid,
			'actions': board.full_image()
		}
		socketio.emit('paint', data)

# Fired when a user attempts to undo an action

@sock.on('undo')
def socketio_undo(message):
	bid = message['board_id'].upper()
	aid = message['action_id']
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user has permission to edit the board
	if board.may_edit(key):
		# Remove the action from the board
		board.undo_action(aid)
		# Tell other clients the action has been undone
		data = {
			'board_id': bid,
			'action_id': aid
		}
		socketio.emit('undo', data, broadcast = True, room = bid)

# Fired when a user attmpts to unlock a whiteboard

@sock.on('unlock')
def socketio_unlock(message):
	bid = message['board_id'].upper()
	key = message['key']
	board = whiteboards[bid]
	# Ensure the user has permission to do so
	if board.may_edit(key):
		board.unlock()
		# Tells the other client that the board has been unlocked
		# this will cause the browsers to refresh the page
		socketio.emit('refresh', broadcast = True, room = bid)

# Run the server

if __name__ == '__main__':
	port = int(settings.get('port'))
	sock.run(app, host = '0.0.0.0', port = port)
<|endoftext|>