<commit_before># -*- coding: utf-8 -*-
"""
This module deals with bad text, and aims to turn it into less-bad text.

The interesting function in it is fix_bad_unicode, which corrects for two ugly
things that unaware programs can do to Unicode text; see its documentation for
details.
"""
import re

# Start with an inventory of "gremlins", which are characters from all over
# Unicode that Windows has instead assigned to the control characters
# 0x80-0x9F. We might encounter them in their Unicode forms and have to figure
# out what they were originally.

CP1252_GREMLINS = u''.join([
    # from http://www.microsoft.com/typography/unicode/1252.htm
    # adapted from http://effbot.org/zone/unicode-gremlins.htm
    u"\u20AC", # EURO SIGN
    u"\u201A", # SINGLE LOW-9 QUOTATION MARK
    u"\u0192", # LATIN SMALL LETTER F WITH HOOK
    u"\u201E", # DOUBLE LOW-9 QUOTATION MARK
    u"\u2020", # DAGGER
    u"\u2021", # DOUBLE DAGGER
    u"\u02C6", # MODIFIER LETTER CIRCUMFLEX ACCENT
    u"\u2030", # PER MILLE SIGN
    u"\u0160", # LATIN CAPITAL LETTER S WITH CARON
    u"\u2039", # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
    u"\u0152", # LATIN CAPITAL LIGATURE OE
    u"\u017D", # LATIN CAPITAL LETTER Z WITH CARON
    u"\u2022", # BULLET
    u"\u02DC", # SMALL TILDE
    u"\u0161", # LATIN SMALL LETTER S WITH CARON
    u"\u0153", # LATIN SMALL LIGATURE OE
    u"\u017E", # LATIN SMALL LETTER Z WITH CARON
    u"\u0178", # LATIN CAPITAL LETTER Y WITH DIAERESIS
])

# We've separated out these characters because they are actually punctuation
# that could occur after, say, an accented letter. They appear in combinations
# that could be intentional and meaningful, or could be misinterpretations of
# other Unicode characters in UTF-8. So we treat them with caution, and only
# convert them in one situation where they are very unilkely to be intentional.

CP1252_MORE_GREMLINS = CP1252_GREMLINS + (u''.join([
    u"\u2026", # HORIZONTAL ELLIPSIS
    u"\u2018", # LEFT SINGLE QUOTATION MARK
    u"\u2019", # RIGHT SINGLE QUOTATION MARK
    u"\u201C", # LEFT DOUBLE QUOTATION MARK
    u"\u201D", # RIGHT DOUBLE QUOTATION MARK
    u"\u2013", # EN DASH
    u"\u2014", # EM DASH
    u"\u2122", # TRADE MARK SIGN
    u"\u203A", # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
]))

# PAIRS_START contains the Latin-1 characters that are the first bytes of all
# possible two-byte UTF-8 characters.
PAIRS_START = u''.join(unichr(x) for x in xrange(0xc2, 0xe0))

# PAIRS_SAFE_START contains Latin-1 characters that are the first bytes of
# *very common* UTF-8 characters. We'll allow converting these when they appear
# next to one of the more obscure gremlins.
PAIRS_SAFE_START = u''.join(unichr(x) for x in xrange(0xc3, 0xca))

# PAIRS_REST contains Latin-1 characters that are valid second bytes of UTF-8
# characters.
PAIRS_REST = u''.join(unichr(x) for x in xrange(0x80, 0xc0))

# TRIPLES_START cointains Latin-1 characters that are valid first bytes of
# three-byte UTF-8 characters.
TRIPLES_START = u''.join(unichr(x) for x in xrange(0xe1, 0xf0))

# TRIPLES_REST contains the valid second and third bytes.
TRIPLES_REST = u''.join(unichr(x) for x in xrange(0x80, 0xc0))

# TRIPLES_HIGH_SECOND contains the valid second bytes that can appear after the
# byte 0xe0; any lower bytes than that would be invalid UTF-8.
TRIPLES_HIGH_SECOND = u''.join(unichr(x) for x in xrange(0xa0, 0xc0))

# Make a list of regexes representing sequences that we want to correct.
BAD_UNICODE_SEQUENCES = [
    u'[%s][%s]' % (PAIRS_START, PAIRS_REST),
    u'[%s][%s]' % (PAIRS_SAFE_START, CP1252_GREMLINS),
    u'\xc3[%s]' % (PAIRS_REST + CP1252_MORE_GREMLINS),
    u'[%s][%s][%s]' % (TRIPLES_START, TRIPLES_REST, TRIPLES_REST),
    u'\xe0[%s][%s]' % (TRIPLES_HIGH_SECOND, TRIPLES_REST),
    u'\xe2[%s][%s]' % (TRIPLES_REST + CP1252_GREMLINS,
        TRIPLES_REST + CP1252_MORE_GREMLINS),
]

# Join them all together into one big ugly regex, and compile it.
BAD_UNICODE_REGEX = u'(' + (u'|'.join(BAD_UNICODE_SEQUENCES)) + u')'
BAD_UNICODE_RE = re.compile(BAD_UNICODE_REGEX)

def fix_bad_unicode(text):
    u"""
    Something you will find all over the place, in real-world text, is text
    that's mistakenly encoded as utf-8, decoded in some ugly format like
    latin-1 or even Windows codepage 1252, and encoded as utf-8 again.

    This causes your perfectly good Unicode-aware code to end up with garbage
    text because someone else (or maybe "someone else") made a mistake.

    This function looks for the evidence of that having happened and fixes it.
    It searches for the nonsense character sequences that are incorrect latin-1
    representations of all UTF-8 characters in the Basic Multilingual Plane,
    and replaces them with the Unicode character they were clearly meant to
    represent.

    Do not ever run binary data through this function.

        >>> print fix_bad_unicode(u'Ãºnico')
        único

        >>> print fix_bad_unicode(u'This text is fine already :þ')
        This text is fine already :þ

    Because these characters often come from Microsoft products, we also allow
    for the possibility that we get not just Unicode characters 128-255, but
    also Windows's conflicting idea of what characters 128-160 are. However,
    because some pairs of these characters are actually useful, we only correct
    them in sets of three or more.

        >>> print fix_bad_unicode(u'This â€” should be an em dash')
        This — should be an em dash

    We might have to deal with both Windows characters and raw control
    characters at the same time, especially when dealing with characters like
    \x81 that have no mapping in Windows.

        >>> print fix_bad_unicode(u'This text is sad â\x81”..')
        This text is sad ⁔..

    This function even fixes multiple levels of badness:

        >>> print fix_bad_unicode(u'what the f\xc3\x83\xc2\x85\xc3\x82\xc2\xb1ck')
        what the fűck
    """
    # Astute observers will recognize that this makes certain character
    # sequences impossible to encode. This function takes various steps to make
    # sure that it's not destroying meaningful sequences of characters. But we
    # don't know how language will be used in the future, so this code is not
    # necessarily future-proof.
    #
    # For example: If, in the future, the Euro collapses, and Germany and the
    # UK then form their own monetary union and introduce a currency called the
    # Deutschpound (Ð£), this function will be erroneous.
    #
    # Particularly astute observers will notice that this function would also
    # erroneously encode its own documentation and test cases.

    # Make sure we're dealing with Unicode. Decode it from utf-8 if not.
    if isinstance(text, str):
        remaining = text.decode('utf-8', 'replace')
    else:
        remaining = text

    # Collect chunks of text with Unicode glitches fixed. If there were no
    # glitches in the first place, great, there will only be one chunk.
    chunks = []
    while remaining:
        match = BAD_UNICODE_RE.search(remaining)
        if match:
            before = remaining[0:match.start()]
            to_fix = remaining[match.start():match.end()]
            try:
                # We found some tell-tale nonsense! First get the bytes that
                # result from encoding them as latin-1.
                encoded = to_fix.encode('latin-1')
            except UnicodeEncodeError:
                # As we've seen, some nonsense characters you come across
                # aren't even in latin-1. They've been run through a Microsoft
                # product, so they're instead in Windows codepage 1252. That's
                # where you get stuff like the euro and trademark sign.
                encoded = recode_from_windows(to_fix).encode('latin-1')

            # Now that we've identified the nonsense and gotten the bytes out
            # of it, decode those bytes as UTF-8 to get the character they were
            # probably supposed to be.
            fixed = encoded.decode('utf-8')
            chunks.extend([before, fixed])
            remaining = remaining[match.end():]
        else:
            chunks.append(remaining)
            remaining = ''
    result = u''.join(chunks)

    # Check the result to make sure we have no glitches left. If we do, then
    # the text was probably incorrectly encoded *twice*, so we run the function
    # again recursively.
    if BAD_UNICODE_RE.search(result):
        return fix_bad_unicode(result)
    return result

def recode_from_windows(text):
    """
    Take the high-unicode "gremlin" characters that show up as a result of
    decoding Windows CP1252, and replace them with their equivalent characters
    between 0x80 and 0x9F, which is what they would be if decoded as Latin-1.
    """
    chars = []
    for char in text:
        if char in CP1252_MORE_GREMLINS:
            chars.append(char.encode('cp1252').decode('latin-1'))
        else:
            chars.append(char)
    return u''.join(chars)
<commit_msg>Rewrite fixit.py to be more informed and safer.<commit_after># -*- coding: utf-8 -*-

import codecs
import unicodedata

def fix_bad_unicode(text):
    u"""
    Something you will find all over the place, in real-world text, is text
    that's mistakenly encoded as utf-8, decoded in some ugly format like
    latin-1 or even Windows codepage 1252, and encoded as utf-8 again.

    This causes your perfectly good Unicode-aware code to end up with garbage
    text because someone else (or maybe "someone else") made a mistake.

    This function looks for the evidence of that having happened and fixes it.
    It searches for the nonsense character sequences that are incorrect latin-1
    representations of all UTF-8 characters in the Basic Multilingual Plane,
    and replaces them with the Unicode character they were clearly meant to
    represent.

    The input to the function must be Unicode. It's not going to try to
    auto-decode bytes for you -- then it would just create the problems it's
    supposed to fix.

        >>> print fix_bad_unicode(u'Ãºnico')
        único

        >>> print fix_bad_unicode(u'This text is fine already :þ')
        This text is fine already :þ

    Because these characters often come from Microsoft products, we also allow
    for the possibility that we get not just Unicode characters 128-255, but
    also Windows's conflicting idea of what characters 128-160 are. However,
    because some pairs of these characters are actually useful, we only correct
    them in sets of three or more.

        >>> print fix_bad_unicode(u'This â€” should be an em dash')
        This — should be an em dash

    We might have to deal with both Windows characters and raw control
    characters at the same time, especially when dealing with characters like
    \x81 that have no mapping in Windows.

        >>> print fix_bad_unicode(u'This text is sad .â\x81”.')
        This text is sad .⁔.

    This function even fixes multiple levels of badness:

        >>> wtf = u'\xc3\xa0\xc2\xb2\xc2\xa0_\xc3\xa0\xc2\xb2\xc2\xa0'
        >>> print fix_bad_unicode(wtf)
        ಠ_ಠ

    However, it has safeguards against sequences of letters and punctuation
    that can occur in valid text:

        >>> print fix_bad_unicode(u'“I’m not such a fan of Charlotte Brontë…”')
        “I’m not such a fan of Charlotte Brontë…”

        >>> print fix_bad_unicode(u'ÅHÅ™, the new couch from IKEA')
        ÅHÅ™, the new couch from IKEA

    """
    if not isinstance(text, unicode):
        raise TypeError("This isn't even decoded into Unicode yet. "
                        "Decode it first.")

    maxord = max(ord(char) for char in text)
    tried_fixing = None
    if maxord < 128:
        # Hooray! It's ASCII!
        return text
    elif maxord < 256:
        tried_fixing = reinterpret_latin1(text)
    elif all(ord(char) in WINDOWS_1252_CODEPOINTS for char in text):
        tried_fixing = reinterpret_windows1252(text)
    else:
        # We can't imagine how this would be anything but valid text.
        return text

    if (text_badness(tried_fixing) + len(tried_fixing) <
        text_badness(text) + len(text)):
        return fix_bad_unicode(tried_fixing)
    else:
        return text

def decode_utf8_as_latin1(bytestr):
    """
    If you *know* you have some mistakenly double-encoded text stored
    as bytes, you can simply read it correctly with this codec.

    This version assumes the intermediate step encodes the text as
    Latin-1. If it has Windows-1252 characters in it, use
    `reinterpret_windows1252` instead.
    """
    wrongtext = bytestr.decode('utf-8', 'replace')
    return reinterpret_latin1(wrongtext)

def reinterpret_latin1(wrongtext):
    newbytes = wrongtext.encode('latin-1', 'replace')
    return newbytes.decode('utf-8', 'replace')

def decode_utf8_as_windows1252(bytestr):
    """
    If you *know* you have some mistakenly double-encoded text stored
    as bytes, you can simply read it correctly with this codec.
    """
    wrongtext = bytestr.decode('utf-8', 'replace')
    return reinterpret_windows1252(wrongtext)

def reinterpret_windows1252(wrongtext):
    altered_bytes = []
    for char in wrongtext:
        if ord(char) in WINDOWS_1252_GREMLINS:
            altered_bytes.append(char.encode('WINDOWS_1252'))
        else:
            altered_bytes.append(char.encode('latin-1', 'replace'))
    return ''.join(altered_bytes).decode('utf-8', 'replace')

def please_dont_encode(text):
    """
    We're making codecs that can decode really bad encodings. There is no good
    reason anyone would want to deliberately *produce* those encodings, so the
    codecs do not work in the other direction.
    """
    raise UnicodeError("You really don't want to encode into this codec.")

@codecs.register
def codec_finder(name):
    """
    Register our bad-Unicode codecs with the Python codecs library.
    """
    if name == 'utf8_as_latin1':
        return codecs.CodecInfo(please_dont_encode, decode_utf8_as_latin1)
    elif name == 'utf8_as_windows1252':
        return codecs.CodecInfo(please_dont_encode,
            decode_utf8_as_windows1252)

def text_badness(text):
    u'''
    Look for red flags that text is encoded incorrectly:

    Obvious problems:
    - The replacement character \ufffd, indicating a decoding error
    - Unassigned or private-use Unicode characters

    Very weird things:
    - Adjacent letters from two different scripts
    - Letters in scripts that are very rarely used on computers (and
      therefore, someone who is using them will probably get Unicode right)
    - Improbable control characters

    Moderately weird things:
    - Improbable single-byte characters
    - Letters in somewhat rare scripts
    '''
    assert isinstance(text, unicode)
    errors = 0
    very_weird_things = 0
    weird_things = 0
    prev_letter_script = None
    for pos in xrange(len(text)):
        char = text[pos]
        index = ord(char)
        if index < 256:
            # Deal quickly with the first 256 characters.
            weird_things += SINGLE_BYTE_WEIRDNESS[index]
            if SINGLE_BYTE_LETTERS[index]:
                prev_letter_script = 'latin'
            else:
                prev_letter_script = None
        else:
            category = unicodedata.category(char)
            if category == 'Co':
                # Unassigned or private use
                errors += 1
            elif index == 0xfffd:
                # Replacement character
                errors += 1

            if category.startswith('L'):
                # It's a letter. What kind of letter? This is typically found
                # in the first word of the letter's Unicode name.
                name = unicodedata.name(char)
                freq, script = SCRIPT_TABLE[name.split()[0]]
                if prev_letter_script:
                    if script != prev_letter_script:
                        very_weird_things += 1
                    if freq == 1:
                        weird_things += 2
                    elif freq == 0:
                        very_weird_things += 1
            else:
                prev_letter_script = None

    return 100 * errors + 10 * very_weird_things + weird_things

#######################################################################
# The rest of this file is esoteric info about characters, scripts, and their
# frequencies.
#
# Start with an inventory of "gremlins", which are characters from all over
# Unicode that Windows has instead assigned to the control characters
# 0x80-0x9F. We might encounter them in their Unicode forms and have to figure
# out what they were originally.

WINDOWS_1252_GREMLINS = [
    # from http://www.microsoft.com/typography/unicode/1252.htm
    # adapted from http://effbot.org/zone/unicode-gremlins.htm
    0x0152,  # LATIN CAPITAL LIGATURE OE
    0x0153,  # LATIN SMALL LIGATURE OE
    0x0160,  # LATIN CAPITAL LETTER S WITH CARON
    0x0161,  # LATIN SMALL LETTER S WITH CARON
    0x0178,  # LATIN CAPITAL LETTER Y WITH DIAERESIS
    0x017E,  # LATIN SMALL LETTER Z WITH CARON
    0x017D,  # LATIN CAPITAL LETTER Z WITH CARON
    0x0192,  # LATIN SMALL LETTER F WITH HOOK
    0x02C6,  # MODIFIER LETTER CIRCUMFLEX ACCENT
    0x02DC,  # SMALL TILDE
    0x2013,  # EN DASH
    0x2014,  # EM DASH
    0x201A,  # SINGLE LOW-9 QUOTATION MARK
    0x201C,  # LEFT DOUBLE QUOTATION MARK
    0x201D,  # RIGHT DOUBLE QUOTATION MARK
    0x201E,  # DOUBLE LOW-9 QUOTATION MARK
    0x2018,  # LEFT SINGLE QUOTATION MARK
    0x2019,  # RIGHT SINGLE QUOTATION MARK
    0x2020,  # DAGGER
    0x2021,  # DOUBLE DAGGER
    0x2022,  # BULLET
    0x2026,  # HORIZONTAL ELLIPSIS
    0x2030,  # PER MILLE SIGN
    0x2039,  # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
    0x203A,  # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
    0x20AC,  # EURO SIGN
    0x2122,  # TRADE MARK SIGN
]

WINDOWS_1252_CODEPOINTS = range(256) + WINDOWS_1252_GREMLINS

# Rank the characters typically represented by a single byte -- that is, in
# Latin-1 or Windows-1252 -- by how weird it would be to see them in running
# text.
#
#   0 = not weird at all
#   1 = rare punctuation or rare letter that someone could certainly
#       have a good reason to use. All Windows-1252 gremlins are at least
#       weirdness 1.
#   2 = things that probably don't appear next to letters or other
#       symbols, such as math or currency symbols
#   3 = obscure symbols that nobody would go out of their way to use
#       (includes symbols that were replaced in ISO-8859-15)
#   4 = why would you use this?
#   5 = unprintable control character

SINGLE_BYTE_WEIRDNESS = (
#   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5,  # 0x00
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,  # 0x10
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x20
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x30
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x40
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x50
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x60
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,  # 0x70
    2, 5, 1, 4, 1, 1, 3, 3, 4, 3, 1, 1, 1, 5, 1, 5,  # 0x80
    5, 1, 1, 1, 1, 3, 1, 1, 4, 1, 1, 1, 1, 5, 1, 1,  # 0x90
    1, 0, 2, 2, 3, 2, 4, 2, 4, 2, 2, 0, 3, 1, 1, 4,  # 0xa0
    2, 2, 3, 3, 4, 3, 3, 2, 4, 4, 4, 0, 3, 3, 3, 0,  # 0xb0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xc0
    1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xd0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xe0
    1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xf0
)

# Pre-cache the Unicode data saying which of these first 256 characters are
# letters. We'll need it often.
SINGLE_BYTE_LETTERS = [
    unicodedata.category(unichr(i)).startswith('L')
    for i in xrange(256)
]

# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# you're probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from base64 import b64encode
from hashlib import sha1
import os
import socket
import ssl

from ws4py import WS_KEY, WS_VERSION
from ws4py.exc import HandshakeError
from ws4py.websocket import WebSocket
from ws4py.compat import urlsplit

__all__ = ['WebSocketBaseClient']

class WebSocketBaseClient(WebSocket):
    def __init__(self, url, protocols=None, extensions=None, heartbeat_freq=None, ssl_options=None):
        """
        A websocket client that implements :rfc:`6455` and provides a simple
        interface to communicate with a websocket server.

        This class works on its own but will block if not run in
        its own thread.

        When an instance of this class is created, a :py:mod:`socket`
        is created. If the connection is a TCP socket,
        the nagle's algorithm is disabled.

        The address of the server will be extracted from the given
        websocket url.

        The websocket key is randomly generated, reset the
        `key` attribute if you want to provide yours.

        For instance to create a TCP client:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws://localhost/ws')

        Here is an example for a TCP client over SSL:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('wss://localhost/ws')

        Finally an example of a Unix-domain connection:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')

        Note that in this case, the initial Upgrade request
        will be sent to ``/``. You may need to change this
        by setting the resource explicitely before connecting:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')
           >>> ws.resource = '/ws'
           >>> ws.connect()

        """
        self.url = url
        self.host = None
        self.scheme = None
        self.port = None
        self.unix_socket_path = None
        self.resource = None
        self.ssl_options = ssl_options or {}

        self._parse_url()

        if self.unix_socket_path:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
        else:
            # Let's handle IPv4 and IPv6 addresses
            # Simplified from CherryPy's code
            try:
                family, socktype, proto, canonname, sa = socket.getaddrinfo(self.host, self.port,
                                                                            socket.AF_UNSPEC,
                                                                            socket.SOCK_STREAM,
                                                                            0, socket.AI_PASSIVE)[0]
            except socket.gaierror:
                family = socket.AF_INET
                if self.host.startswith('::'):
                    family = socket.AF_INET6

                socktype = socket.SOCK_STREAM
                proto = 0
                canonname = ""
                sa = (self.host, self.port, 0, 0)

            sock = socket.socket(family, socktype, proto)
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            if hasattr(socket, 'AF_INET6') and family == socket.AF_INET6 and \
              self.host.startswith('::'):
                try:
                    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
                except (AttributeError, socket.error):
                    pass

        WebSocket.__init__(self, sock, protocols=protocols,
                           extensions=extensions,
                           heartbeat_freq=heartbeat_freq)

        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))

    # Adpated from: https://github.com/liris/websocket-client/blob/master/websocket.py#L105
    def _parse_url(self):
        """
        Parses a URL which must have one of the following forms:

        - ws://host[:port][path]
        - wss://host[:port][path]
        - ws+unix:///path/to/my.socket

        In the first two cases, the ``host`` and ``port``
        attributes will be set to the parsed values. If no port
        is explicitely provided, it will be either 80 or 443
        based on the scheme. Also, the ``resource`` attribute is
        set to the path segment of the URL (alongside any querystring).

        In addition, if the scheme is ``ws+unix``, the
        ``unix_socket_path`` attribute is set to the path to
        the Unix socket while the ``resource`` attribute is
        set to ``/``.
        """
        # Python 2.6.1 and below don't parse ws or wss urls properly. netloc is empty.
        # See: https://github.com/Lawouach/WebSocket-for-Python/issues/59
        scheme, url = self.url.split(":", 1)

        parsed = urlsplit(url, scheme="http")
        if parsed.hostname:
            self.host = parsed.hostname
        elif '+unix' in scheme:
            self.host = 'localhost'
        else:
            raise ValueError("Invalid hostname from: %s", self.url)

        if parsed.port:
            self.port = parsed.port

        if scheme == "ws":
            if not self.port:
                self.port = 80
        elif scheme == "wss":
            if not self.port:
                self.port = 443
        elif scheme in ('ws+unix', 'wss+unix'):
            pass
        else:
            raise ValueError("Invalid scheme: %s" % scheme)

        if parsed.path:
            resource = parsed.path
        else:
            resource = "/"

        if '+unix' in scheme:
            self.unix_socket_path = resource
            resource = '/'

        if parsed.query:
            resource += "?" + parsed.query

        self.scheme = scheme
        self.resource = resource

    @property
    def bind_addr(self):
        """
        Returns the Unix socket path if or a tuple
        ``(host, port)`` depending on the initial
        URL's scheme.
        """
        return self.unix_socket_path or (self.host, self.port)

    def close(self, code=1000, reason=''):
        """
        Initiate the closing handshake with the server.
        """
        if not self.client_terminated:
            self.client_terminated = True
            self._write(self.stream.close(code=code, reason=reason).single(mask=True))

    def connect(self):
        """
        Connects this websocket and starts the upgrade handshake
        with the remote endpoint.
        """
        if self.scheme == "wss":
            # default port is now 443; upgrade self.sender to send ssl
            self.sock = ssl.wrap_socket(self.sock, **self.ssl_options)

        self.sock.connect(self.bind_addr)

        self._write(self.handshake_request)

        response = b''
        doubleCLRF = b'\r\n\r\n'
        while True:
            bytes = self.sock.recv(128)
            if not bytes:
                break
            response += bytes
            if doubleCLRF in response:
                break

        if not response:
            self.close_connection()
            raise HandshakeError("Invalid response")

        headers, _, body = response.partition(doubleCLRF)
        response_line, _, headers = headers.partition(b'\r\n')

        try:
            self.process_response_line(response_line)
            self.protocols, self.extensions = self.process_handshake_header(headers)
        except HandshakeError:
            self.close_connection()
            raise

        self.handshake_ok()
        if body:
            self.process(body)

    @property
    def handshake_headers(self):
        """
        List of headers appropriate for the upgrade
        handshake.
        """
        headers = [
            ('Host', self.host),
            ('Connection', 'Upgrade'),
            ('Upgrade', 'websocket'),
            ('Sec-WebSocket-Key', self.key),
            ('Origin', self.url),
            ('Sec-WebSocket-Version', str(max(WS_VERSION)))
            ]

        if self.protocols:
            headers.append(('Sec-WebSocket-Protocol', ','.join(self.protocols)))

        return headers

    @property
    def handshake_request(self):
        """
        Prepare the request to be sent for the upgrade handshake.
        """
        headers = self.handshake_headers
        request = [b"GET %s HTTP/1.1" % self.resource]
        for header, value in headers:
            request.append(b"%s: %s" % (header, value))
        request.append(b'\r\n')

        return b'\r\n'.join(request)

    def process_response_line(self, response_line):
        """
        Ensure that we received a HTTP `101` status code in
        response to our request and if not raises :exc:`HandshakeError`.
        """
        protocol, code, status = response_line.split(b' ', 2)
        if code != b'101':
            raise HandshakeError("Invalid response status: %s %s" % (code, status))

    def process_handshake_header(self, headers):
        """
        Read the upgrade handshake's response headers and
        validate them against :rfc:`6455`.
        """
        protocols = []
        extensions = []

        headers = headers.strip()

        for header_line in headers.split(b'\r\n'):
            header, value = header_line.split(b':', 1)
            header = header.strip().lower()
            value = value.strip().lower()

            if header == 'upgrade' and value != 'websocket':
                raise HandshakeError("Invalid Upgrade header: %s" % value)

            elif header == 'connection' and value != 'upgrade':
                raise HandshakeError("Invalid Connection header: %s" % value)

            elif header == 'sec-websocket-accept':
                match = b64encode(sha1(self.key + WS_KEY).digest())
                if value != match.lower():
                    raise HandshakeError("Invalid challenge response: %s" % value)

            elif header == 'sec-websocket-protocol':
                protocols = ','.join(value)

            elif header == 'sec-websocket-extensions':
                extensions = ','.join(value)

        return protocols, extensions
<commit_msg>User AF_INET for socket.getaddrinfo<commit_after># -*- coding: utf-8 -*-
from base64 import b64encode
from hashlib import sha1
import os
import socket
import ssl

from ws4py import WS_KEY, WS_VERSION
from ws4py.exc import HandshakeError
from ws4py.websocket import WebSocket
from ws4py.compat import urlsplit

__all__ = ['WebSocketBaseClient']

class WebSocketBaseClient(WebSocket):
    def __init__(self, url, protocols=None, extensions=None, heartbeat_freq=None, ssl_options=None):
        """
        A websocket client that implements :rfc:`6455` and provides a simple
        interface to communicate with a websocket server.

        This class works on its own but will block if not run in
        its own thread.

        When an instance of this class is created, a :py:mod:`socket`
        is created. If the connection is a TCP socket,
        the nagle's algorithm is disabled.

        The address of the server will be extracted from the given
        websocket url.

        The websocket key is randomly generated, reset the
        `key` attribute if you want to provide yours.

        For instance to create a TCP client:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws://localhost/ws')

        Here is an example for a TCP client over SSL:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('wss://localhost/ws')

        Finally an example of a Unix-domain connection:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')

        Note that in this case, the initial Upgrade request
        will be sent to ``/``. You may need to change this
        by setting the resource explicitely before connecting:

        .. code-block:: python

           >>> from websocket.client import WebSocketBaseClient
           >>> ws = WebSocketBaseClient('ws+unix:///tmp/my.sock')
           >>> ws.resource = '/ws'
           >>> ws.connect()

        """
        self.url = url
        self.host = None
        self.scheme = None
        self.port = None
        self.unix_socket_path = None
        self.resource = None
        self.ssl_options = ssl_options or {}

        self._parse_url()

        if self.unix_socket_path:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
        else:
            # Let's handle IPv4 and IPv6 addresses
            # Simplified from CherryPy's code
            try:
                family, socktype, proto, canonname, sa = socket.getaddrinfo(self.host, self.port,
                                                                            socket.AF_INET,
                                                                            socket.SOCK_STREAM,
                                                                            0, socket.AI_PASSIVE)[0]
            except socket.gaierror:
                family = socket.AF_INET
                if self.host.startswith('::'):
                    family = socket.AF_INET6

                socktype = socket.SOCK_STREAM
                proto = 0
                canonname = ""
                sa = (self.host, self.port, 0, 0)

            sock = socket.socket(family, socktype, proto)
            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            if hasattr(socket, 'AF_INET6') and family == socket.AF_INET6 and \
              self.host.startswith('::'):
                try:
                    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
                except (AttributeError, socket.error):
                    pass

        WebSocket.__init__(self, sock, protocols=protocols,
                           extensions=extensions,
                           heartbeat_freq=heartbeat_freq)

        self.stream.always_mask = True
        self.stream.expect_masking = False
        self.key = b64encode(os.urandom(16))

    # Adpated from: https://github.com/liris/websocket-client/blob/master/websocket.py#L105
    def _parse_url(self):
        """
        Parses a URL which must have one of the following forms:

        - ws://host[:port][path]
        - wss://host[:port][path]
        - ws+unix:///path/to/my.socket

        In the first two cases, the ``host`` and ``port``
        attributes will be set to the parsed values. If no port
        is explicitely provided, it will be either 80 or 443
        based on the scheme. Also, the ``resource`` attribute is
        set to the path segment of the URL (alongside any querystring).

        In addition, if the scheme is ``ws+unix``, the
        ``unix_socket_path`` attribute is set to the path to
        the Unix socket while the ``resource`` attribute is
        set to ``/``.
        """
        # Python 2.6.1 and below don't parse ws or wss urls properly. netloc is empty.
        # See: https://github.com/Lawouach/WebSocket-for-Python/issues/59
        scheme, url = self.url.split(":", 1)

        parsed = urlsplit(url, scheme="http")
        if parsed.hostname:
            self.host = parsed.hostname
        elif '+unix' in scheme:
            self.host = 'localhost'
        else:
            raise ValueError("Invalid hostname from: %s", self.url)

        if parsed.port:
            self.port = parsed.port

        if scheme == "ws":
            if not self.port:
                self.port = 80
        elif scheme == "wss":
            if not self.port:
                self.port = 443
        elif scheme in ('ws+unix', 'wss+unix'):
            pass
        else:
            raise ValueError("Invalid scheme: %s" % scheme)

        if parsed.path:
            resource = parsed.path
        else:
            resource = "/"

        if '+unix' in scheme:
            self.unix_socket_path = resource
            resource = '/'

        if parsed.query:
            resource += "?" + parsed.query

        self.scheme = scheme
        self.resource = resource

    @property
    def bind_addr(self):
        """
        Returns the Unix socket path if or a tuple
        ``(host, port)`` depending on the initial
        URL's scheme.
        """
        return self.unix_socket_path or (self.host, self.port)

    def close(self, code=1000, reason=''):
        """
        Initiate the closing handshake with the server.
        """
        if not self.client_terminated:
            self.client_terminated = True
            self._write(self.stream.close(code=code, reason=reason).single(mask=True))

    def connect(self):
        """
        Connects this websocket and starts the upgrade handshake
        with the remote endpoint.
        """
        if self.scheme == "wss":
            # default port is now 443; upgrade self.sender to send ssl
            self.sock = ssl.wrap_socket(self.sock, **self.ssl_options)

        self.sock.connect(self.bind_addr)

        self._write(self.handshake_request)

        response = b''
        doubleCLRF = b'\r\n\r\n'
        while True:
            bytes = self.sock.recv(128)
            if not bytes:
                break
            response += bytes
            if doubleCLRF in response:
                break

        if not response:
            self.close_connection()
            raise HandshakeError("Invalid response")

        headers, _, body = response.partition(doubleCLRF)
        response_line, _, headers = headers.partition(b'\r\n')

        try:
            self.process_response_line(response_line)
            self.protocols, self.extensions = self.process_handshake_header(headers)
        except HandshakeError:
            self.close_connection()
            raise

        self.handshake_ok()
        if body:
            self.process(body)

    @property
    def handshake_headers(self):
        """
        List of headers appropriate for the upgrade
        handshake.
        """
        headers = [
            ('Host', self.host),
            ('Connection', 'Upgrade'),
            ('Upgrade', 'websocket'),
            ('Sec-WebSocket-Key', self.key),
            ('Origin', self.url),
            ('Sec-WebSocket-Version', str(max(WS_VERSION)))
            ]

        if self.protocols:
            headers.append(('Sec-WebSocket-Protocol', ','.join(self.protocols)))

        return headers

    @property
    def handshake_request(self):
        """
        Prepare the request to be sent for the upgrade handshake.
        """
        headers = self.handshake_headers
        request = [b"GET %s HTTP/1.1" % self.resource]
        for header, value in headers:
            request.append(b"%s: %s" % (header, value))
        request.append(b'\r\n')

        return b'\r\n'.join(request)

    def process_response_line(self, response_line):
        """
        Ensure that we received a HTTP `101` status code in
        response to our request and if not raises :exc:`HandshakeError`.
        """
        protocol, code, status = response_line.split(b' ', 2)
        if code != b'101':
            raise HandshakeError("Invalid response status: %s %s" % (code, status))

    def process_handshake_header(self, headers):
        """
        Read the upgrade handshake's response headers and
        validate them against :rfc:`6455`.
        """
        protocols = []
        extensions = []

        headers = headers.strip()

        for header_line in headers.split(b'\r\n'):
            header, value = header_line.split(b':', 1)
            header = header.strip().lower()
            value = value.strip().lower()

            if header == 'upgrade' and value != 'websocket':
                raise HandshakeError("Invalid Upgrade header: %s" % value)

            elif header == 'connection' and value != 'upgrade':
                raise HandshakeError("Invalid Connection header: %s" % value)

            elif header == 'sec-websocket-accept':
                match = b64encode(sha1(self.key + WS_KEY).digest())
                if value != match.lower():
                    raise HandshakeError("Invalid challenge response: %s" % value)

            elif header == 'sec-websocket-protocol':
                protocols = ','.join(value)

            elif header == 'sec-websocket-extensions':
                extensions = ','.join(value)

        return protocols, extensions
<|endoftext|>


<commit_before>""" Setup file.
"""
import os
from setuptools import setup, find_packages

here = os.path.abspath(os.path.dirname(__file__))

with open(os.path.join(here, 'README.rst')) as f:
    README = f.read()

setup(name='corniceapp',
    version=0.1,
    description='corniceapp',
    long_description=README,
    classifiers=[
        "Programming Language :: Python",
        "Framework :: Pylons",
        "Topic :: Internet :: WWW/HTTP",
        "Topic :: Internet :: WWW/HTTP :: WSGI :: Application"
    ],
    keywords="web services",
    author='',
    author_email='',
    url='',
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    install_requires=[
        'cornice',
        'PasteScript',
        'waitress',
        'sqlalchemy',
        'MySQL-python',
        'zope.sqlalchemy',
        'WebError',
    ],
    entry_points = """\
    [paste.app_factory]
    main = corniceapp:main
    """,
    paster_plugins=['pyramid'],
)
<commit_msg>add sh as a dependency<commit_after>""" Setup file.
"""
import os
from setuptools import setup, find_packages

here = os.path.abspath(os.path.dirname(__file__))

with open(os.path.join(here, 'README.rst')) as f:
    README = f.read()

setup(name='corniceapp',
    version=0.1,
    description='corniceapp',
    long_description=README,
    classifiers=[
        "Programming Language :: Python",
        "Framework :: Pylons",
        "Topic :: Internet :: WWW/HTTP",
        "Topic :: Internet :: WWW/HTTP :: WSGI :: Application"
    ],
    keywords="web services",
    author='',
    author_email='',
    url='',
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    install_requires=[
        'cornice',
        'PasteScript',
        'waitress',
        'sqlalchemy',
        'MySQL-python',
        'zope.sqlalchemy',
        'WebError',
        'sh',
    ],
    entry_points = """\
    [paste.app_factory]
    main = corniceapp:main
    """,
    paster_plugins=['pyramid'],
)
<|endoftext|>


<commit_before>"""
A nose plugin that re-runs test suite on filesystem event.
"""

VERSION = (0, 9, 0, 'dev')

__version__ = '.'.join((str(each) for each in VERSION[:4]))

def get_version():
    """
    Returns shorter version (digit parts only) as string.
    """
    return '.'.join((str(each) for each in VERSION[:4]))

<commit_msg>Freezying v0.9.0<commit_after>"""
A nose plugin that re-runs test suite on filesystem event.
"""

VERSION = (0, 9, 0)

__version__ = '.'.join((str(each) for each in VERSION[:4]))

def get_version():
    """
    Returns shorter version (digit parts only) as string.
    """
    return '.'.join((str(each) for each in VERSION[:4]))

<|endoftext|>


<commit_before>__author__ = 'Johannes Gehrs (jgehrs@gmail.com)'

import re
import copy

from wtforms.validators import Length, NumberRange, Email, EqualTo, IPAddress, \
    Regexp, URL, AnyOf, Optional, InputRequired, MacAddress, UUID, NoneOf
try:
    from wtforms.validators import DataRequired
except ImportError:
    # wtforms < 2.x
    from wtforms.validators import Required as DataRequired

from wtforms.widgets import TextInput as _TextInput, PasswordInput as _PasswordInput, \
    CheckboxInput as _CheckboxInput, Select as _Select, TextArea as _TextArea, \
    ListWidget as _ListWidget, HiddenInput as _HiddenInput, RadioInput as _RadioInput, \
    FileInput as _FileInput, Input

from wtforms.fields import StringField as _StringField, BooleanField as _BooleanField, \
    DecimalField as _DecimalField, IntegerField as _IntegerField, \
    FloatField as _FloatField, PasswordField as _PasswordField, \
    SelectField as _SelectField, TextAreaField as _TextAreaField, \
    RadioField as _RadioField, DateField as _DateField, \
    DateTimeField as _DateTimeField, FileField as _FileField

def parsley_kwargs(field, kwargs):
    """
    Return new *kwargs* for *widget*.

    Generate *kwargs* from the validators present for the widget.

    Note that the regex validation relies on the eegex pattern being compatible with
    both ECMA script and Python. The regex is not converted in any way.
    It's possible to simply supply your own "parsley-regexp" keyword to the field
    to explicitly provide the ECMA script regex.
    See http://flask.pocoo.org/docs/patterns/wtforms/#forms-in-templates

    Note that the WTForms url vaidator probably is a bit more liberal than the parsley
    one. Do check if the behaviour suits your needs.
    """
    new_kwargs = copy.deepcopy(kwargs)

    if isinstance(field, DateField) or isinstance(field, DateTimeField):
        _date_kwargs(new_kwargs, field)
    if isinstance(field, IntegerField):
        _integer_kwargs(new_kwargs)
    if isinstance(field, DecimalField) or isinstance(field, FloatField):
        _number_kwargs(new_kwargs)

    for vali in field.validators:
        if isinstance(vali, Email):
            _email_kwargs(new_kwargs)
        if isinstance(vali, EqualTo):
            _equal_to_kwargs(new_kwargs, vali)
        if isinstance(vali, IPAddress):
            _ip_address_kwargs(new_kwargs)
        if isinstance(vali, Length):
            _length_kwargs(new_kwargs, vali)
        if isinstance(vali, NumberRange):
            _number_range_kwargs(new_kwargs, vali)
        if isinstance(vali, DataRequired) or isinstance(vali, InputRequired):
            _input_required_kwargs(new_kwargs)
            _trigger_kwargs(new_kwargs, u'key')
        if isinstance(vali, Regexp) and not 'data_regexp' in new_kwargs:
            _regexp_kwargs(new_kwargs, vali)
        if isinstance(vali, URL):
            _url_kwargs(new_kwargs)
        if isinstance(vali, AnyOf):
            _anyof_kwargs(new_kwargs, vali)
        if isinstance(vali, MacAddress):
            _mac_address_kwargs(new_kwargs)
        if isinstance(vali, UUID):
            _uuid_kwargs(new_kwargs)
        if isinstance(vali, NoneOf):
            _none_of_kwargs(new_kwargs, vali)
        if isinstance(vali, Optional):
            pass

        if not 'data_trigger' in new_kwargs:
            _trigger_kwargs(new_kwargs)
        if not 'parsley-error-message' in new_kwargs \
                and not isinstance(vali, Optional) \
                and vali.message is not None:
            _message_kwargs(new_kwargs, message=vali.message)

    return new_kwargs

def _email_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = u'email'

def _equal_to_kwargs(kwargs, vali):
    kwargs[u'data-parsley-equalto'] = u'#' + vali.fieldname

def _ip_address_kwargs(kwargs):
    # Regexp from http://stackoverflow.com/a/4460645
    kwargs[u'data-parsley-pattern'] =\
        r'^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$'

def _length_kwargs(kwargs, vali):
    default_number = -1

    if vali.max != default_number and vali.min != default_number:
        kwargs[u'data-parsley-length'] = u'[' + str(vali.min) + u',' + str(vali.max) + u']'
    else:
        if vali.max == default_number:
            kwargs[u'data-parsley-minlength'] = str(vali.min)
        if vali.min == default_number:
            kwargs[u'data-parsley-maxlength'] = str(vali.max)

def _number_range_kwargs(kwargs, vali):
    kwargs[u'data-parsley-range'] = u'[' + str(vali.min) + u',' + str(vali.max) + u']'

def _input_required_kwargs(kwargs):
    kwargs[u'data-parsley-required'] = u'true'

def _regexp_kwargs(kwargs, vali):
    # Apparently, this is the best way to check for RegexObject Type
    # It's needed because WTForms allows compiled regexps to be passed to the validator
    RegexObject = type(re.compile(''))
    if isinstance(vali.regex, RegexObject):
        regex_string = vali.regex.pattern
    else:
        regex_string = vali.regex
    kwargs[u'data-parsley-pattern'] = regex_string

def _url_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = u'url'

def _string_seq_delimiter(vali, kwargs):
    # We normally use a comma as the delimiter - looks clean and it's parsley's default.
    # If the strings for which we check contain a comma, we cannot use it as a delimiter.
    default_delimiter = u','
    fallback_delimiter = u';;;'
    delimiter = default_delimiter
    for value in vali.values:
        if value.find(',') != -1:
            delimiter = fallback_delimiter
            break
    if delimiter != default_delimiter:
        kwargs[u'data-parsley-inlist-delimiter'] = delimiter
    return delimiter

def _anyof_kwargs(kwargs, vali):
    delimiter = _string_seq_delimiter(vali, kwargs)
    kwargs[u'data-parsley-inlist'] = delimiter.join(vali.values)

def _mac_addresss_kwargs(kwargs):
    kwargs[u'data-parsley-pattern'] = '^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'

def _uuid_kwargs(kwargs):
    kwargs[u'data-parsley-pattern'] = '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$'

def _none_of_kwargs(kwargs, vali):
    delimiter = _string_seq_delimiter(vali, kwargs)
    #data-parsley-noneof is a custom validator, it can be found in scripts/parsley-noneof.js
    kwargs[u'data-parsley-noneof'] = delimiter.join(vali.values)

def _trigger_kwargs(kwargs, trigger=u'change'):
    kwargs[u'data-parsley-trigger'] = trigger

def _message_kwargs(kwargs, message):
    kwargs[u'data-parsley-error-message'] = message

def _date_kwargs(kwargs, field):
    kwargs[u'data-parsley-datefield'] = field.format

def _integer_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = "integer"

def _number_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = "number"

class ParsleyInputMixin(Input):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(ParsleyInputMixin, self).__call__(field, **kwargs)

class TextInput(_TextInput, ParsleyInputMixin):
    pass

class PasswordInput(_PasswordInput, ParsleyInputMixin):
    pass

class HiddenInput(_HiddenInput, ParsleyInputMixin):
    pass

class TextArea(_TextArea, ParsleyInputMixin):
    pass

class CheckboxInput(_CheckboxInput, ParsleyInputMixin):
    pass

class RadioInput(_RadioInput):
    def __init__(self, parsley_options):
        self.parsley_options = parsley_options

    def __call__(self, field, **kwargs):
        kwargs.update(self.parsley_options)
        return super(RadioInput, self).__call__(field, **kwargs)

class Select(_Select):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(Select, self).__call__(field, **kwargs)

class ListWidget(_ListWidget):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(ListWidget, self).__call__(field, **kwargs)

def FileInput(_FileInput, ParsleyInputMixin):
    pass

class StringField(_StringField):
    def __init__(self, *args, **kwargs):
        super(StringField, self).__init__(widget=TextInput(), *args, **kwargs)

class IntegerField(_IntegerField):
    def __init__(self, *args, **kwargs):
        super(IntegerField, self).__init__(widget=TextInput(), *args, **kwargs)

class RadioField(_RadioField):
    def __init__(self, *args, **kwargs):
        super(RadioField, self).__init__(widget=_ListWidget(), *args, **kwargs)
        widget_kwargs = parsley_kwargs(self, {})
        self.option_widget = RadioInput(widget_kwargs)

class BooleanField(_BooleanField):
    def __init__(self, *args, **kwargs):
        super(BooleanField, self).__init__(widget=CheckboxInput(), *args, **kwargs)

class DecimalField(_DecimalField):
    def __init__(self, *args, **kwargs):
        super(DecimalField, self).__init__(widget=TextInput(), *args, **kwargs)

class FloatField(_FloatField):
    def __init__(self, *args, **kwargs):
        super(FloatField, self).__init__(widget=TextInput(), *args, **kwargs)

class PasswordField(_PasswordField):
    def __init__(self, *args, **kwargs):
        super(PasswordField, self).__init__(widget=PasswordInput(), *args, **kwargs)

class HiddenField(_PasswordField):
    def __init__(self, *args, **kwargs):
        super(HiddenField, self).__init__(widget=HiddenInput(), *args, **kwargs)

class TextAreaField(_TextAreaField):
    def __init__(self, *args, **kwargs):
        super(TextAreaField, self).__init__(widget=TextArea(), *args, **kwargs)

class SelectField(_SelectField):
    def __init__(self, *args, **kwargs):
        super(SelectField, self).__init__(widget=Select(), *args, **kwargs)

class DateTimeField(_DateTimeField):
    def __init__(self, *args, **kwargs):
        super(DateTimeField, self).__init__(widget=TextInput(), *args, **kwargs)

class DateField(_DateField):
    def __init__(self, *args, **kwargs):
        super(DateField, self).__init__(widget=TextInput(), *args, **kwargs)

class FileField(_FileField):
    def __init__(self, *args, **kwargs):
        super(FileField, self).__init__(widget=FileInput(), *args, **kwargs)

<commit_msg>Added support for SelectMultipleField<commit_after>__author__ = 'Johannes Gehrs (jgehrs@gmail.com)'

import re
import copy

from wtforms.validators import Length, NumberRange, Email, EqualTo, IPAddress, \
    Regexp, URL, AnyOf, Optional, InputRequired, MacAddress, UUID, NoneOf
try:
    from wtforms.validators import DataRequired
except ImportError:
    # wtforms < 2.x
    from wtforms.validators import Required as DataRequired

from wtforms.widgets import TextInput as _TextInput, PasswordInput as _PasswordInput, \
    CheckboxInput as _CheckboxInput, Select as _Select, TextArea as _TextArea, \
    ListWidget as _ListWidget, HiddenInput as _HiddenInput, RadioInput as _RadioInput, \
    FileInput as _FileInput, Input

from wtforms.fields import StringField as _StringField, BooleanField as _BooleanField, \
    DecimalField as _DecimalField, IntegerField as _IntegerField, \
    FloatField as _FloatField, PasswordField as _PasswordField, \
    SelectField as _SelectField, TextAreaField as _TextAreaField, \
    RadioField as _RadioField, DateField as _DateField, \
    DateTimeField as _DateTimeField, FileField as _FileField, \
    SelectMultipleField as _SelectMultipleField

def parsley_kwargs(field, kwargs):
    """
    Return new *kwargs* for *widget*.

    Generate *kwargs* from the validators present for the widget.

    Note that the regex validation relies on the eegex pattern being compatible with
    both ECMA script and Python. The regex is not converted in any way.
    It's possible to simply supply your own "parsley-regexp" keyword to the field
    to explicitly provide the ECMA script regex.
    See http://flask.pocoo.org/docs/patterns/wtforms/#forms-in-templates

    Note that the WTForms url vaidator probably is a bit more liberal than the parsley
    one. Do check if the behaviour suits your needs.
    """
    new_kwargs = copy.deepcopy(kwargs)

    if isinstance(field, DateField) or isinstance(field, DateTimeField):
        _date_kwargs(new_kwargs, field)
    if isinstance(field, IntegerField):
        _integer_kwargs(new_kwargs)
    if isinstance(field, DecimalField) or isinstance(field, FloatField):
        _number_kwargs(new_kwargs)

    for vali in field.validators:
        if isinstance(vali, Email):
            _email_kwargs(new_kwargs)
        if isinstance(vali, EqualTo):
            _equal_to_kwargs(new_kwargs, vali)
        if isinstance(vali, IPAddress):
            _ip_address_kwargs(new_kwargs)
        if isinstance(vali, Length):
            _length_kwargs(new_kwargs, vali)
        if isinstance(vali, NumberRange):
            _number_range_kwargs(new_kwargs, vali)
        if isinstance(vali, DataRequired) or isinstance(vali, InputRequired):
            _input_required_kwargs(new_kwargs)
            _trigger_kwargs(new_kwargs, u'key')
        if isinstance(vali, Regexp) and not 'data_regexp' in new_kwargs:
            _regexp_kwargs(new_kwargs, vali)
        if isinstance(vali, URL):
            _url_kwargs(new_kwargs)
        if isinstance(vali, AnyOf):
            _anyof_kwargs(new_kwargs, vali)
        if isinstance(vali, MacAddress):
            _mac_address_kwargs(new_kwargs)
        if isinstance(vali, UUID):
            _uuid_kwargs(new_kwargs)
        if isinstance(vali, NoneOf):
            _none_of_kwargs(new_kwargs, vali)
        if isinstance(vali, Optional):
            pass

        if not 'data_trigger' in new_kwargs:
            _trigger_kwargs(new_kwargs)
        if not 'parsley-error-message' in new_kwargs \
                and not isinstance(vali, Optional) \
                and vali.message is not None:
            _message_kwargs(new_kwargs, message=vali.message)

    return new_kwargs

def _email_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = u'email'

def _equal_to_kwargs(kwargs, vali):
    kwargs[u'data-parsley-equalto'] = u'#' + vali.fieldname

def _ip_address_kwargs(kwargs):
    # Regexp from http://stackoverflow.com/a/4460645
    kwargs[u'data-parsley-pattern'] =\
        r'^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$'

def _length_kwargs(kwargs, vali):
    default_number = -1

    if vali.max != default_number and vali.min != default_number:
        kwargs[u'data-parsley-length'] = u'[' + str(vali.min) + u',' + str(vali.max) + u']'
    else:
        if vali.max == default_number:
            kwargs[u'data-parsley-minlength'] = str(vali.min)
        if vali.min == default_number:
            kwargs[u'data-parsley-maxlength'] = str(vali.max)

def _number_range_kwargs(kwargs, vali):
    kwargs[u'data-parsley-range'] = u'[' + str(vali.min) + u',' + str(vali.max) + u']'

def _input_required_kwargs(kwargs):
    kwargs[u'data-parsley-required'] = u'true'

def _regexp_kwargs(kwargs, vali):
    # Apparently, this is the best way to check for RegexObject Type
    # It's needed because WTForms allows compiled regexps to be passed to the validator
    RegexObject = type(re.compile(''))
    if isinstance(vali.regex, RegexObject):
        regex_string = vali.regex.pattern
    else:
        regex_string = vali.regex
    kwargs[u'data-parsley-pattern'] = regex_string

def _url_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = u'url'

def _string_seq_delimiter(vali, kwargs):
    # We normally use a comma as the delimiter - looks clean and it's parsley's default.
    # If the strings for which we check contain a comma, we cannot use it as a delimiter.
    default_delimiter = u','
    fallback_delimiter = u';;;'
    delimiter = default_delimiter
    for value in vali.values:
        if value.find(',') != -1:
            delimiter = fallback_delimiter
            break
    if delimiter != default_delimiter:
        kwargs[u'data-parsley-inlist-delimiter'] = delimiter
    return delimiter

def _anyof_kwargs(kwargs, vali):
    delimiter = _string_seq_delimiter(vali, kwargs)
    kwargs[u'data-parsley-inlist'] = delimiter.join(vali.values)

def _mac_addresss_kwargs(kwargs):
    kwargs[u'data-parsley-pattern'] = '^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'

def _uuid_kwargs(kwargs):
    kwargs[u'data-parsley-pattern'] = '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$'

def _none_of_kwargs(kwargs, vali):
    delimiter = _string_seq_delimiter(vali, kwargs)
    #data-parsley-noneof is a custom validator, it can be found in scripts/parsley-noneof.js
    kwargs[u'data-parsley-noneof'] = delimiter.join(vali.values)

def _trigger_kwargs(kwargs, trigger=u'change'):
    kwargs[u'data-parsley-trigger'] = trigger

def _message_kwargs(kwargs, message):
    kwargs[u'data-parsley-error-message'] = message

def _date_kwargs(kwargs, field):
    kwargs[u'data-parsley-datefield'] = field.format

def _integer_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = "integer"

def _number_kwargs(kwargs):
    kwargs[u'data-parsley-type'] = "number"

class ParsleyInputMixin(Input):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(ParsleyInputMixin, self).__call__(field, **kwargs)

class TextInput(_TextInput, ParsleyInputMixin):
    pass

class PasswordInput(_PasswordInput, ParsleyInputMixin):
    pass

class HiddenInput(_HiddenInput, ParsleyInputMixin):
    pass

class TextArea(_TextArea, ParsleyInputMixin):
    pass

class CheckboxInput(_CheckboxInput, ParsleyInputMixin):
    pass

class RadioInput(_RadioInput):
    def __init__(self, parsley_options):
        self.parsley_options = parsley_options

    def __call__(self, field, **kwargs):
        kwargs.update(self.parsley_options)
        return super(RadioInput, self).__call__(field, **kwargs)

class Select(_Select):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(Select, self).__call__(field, **kwargs)

class ListWidget(_ListWidget):
    def __call__(self, field, **kwargs):
        kwargs = parsley_kwargs(field, kwargs)
        return super(ListWidget, self).__call__(field, **kwargs)

def FileInput(_FileInput, ParsleyInputMixin):
    pass

class StringField(_StringField):
    def __init__(self, *args, **kwargs):
        super(StringField, self).__init__(widget=TextInput(), *args, **kwargs)

class IntegerField(_IntegerField):
    def __init__(self, *args, **kwargs):
        super(IntegerField, self).__init__(widget=TextInput(), *args, **kwargs)

class RadioField(_RadioField):
    def __init__(self, *args, **kwargs):
        super(RadioField, self).__init__(widget=_ListWidget(), *args, **kwargs)
        widget_kwargs = parsley_kwargs(self, {})
        self.option_widget = RadioInput(widget_kwargs)

class BooleanField(_BooleanField):
    def __init__(self, *args, **kwargs):
        super(BooleanField, self).__init__(widget=CheckboxInput(), *args, **kwargs)

class DecimalField(_DecimalField):
    def __init__(self, *args, **kwargs):
        super(DecimalField, self).__init__(widget=TextInput(), *args, **kwargs)

class FloatField(_FloatField):
    def __init__(self, *args, **kwargs):
        super(FloatField, self).__init__(widget=TextInput(), *args, **kwargs)

class PasswordField(_PasswordField):
    def __init__(self, *args, **kwargs):
        super(PasswordField, self).__init__(widget=PasswordInput(), *args, **kwargs)

class HiddenField(_PasswordField):
    def __init__(self, *args, **kwargs):
        super(HiddenField, self).__init__(widget=HiddenInput(), *args, **kwargs)

class TextAreaField(_TextAreaField):
    def __init__(self, *args, **kwargs):
        super(TextAreaField, self).__init__(widget=TextArea(), *args, **kwargs)

class SelectField(_SelectField):
    def __init__(self, *args, **kwargs):
        super(SelectField, self).__init__(widget=Select(), *args, **kwargs)

class DateTimeField(_DateTimeField):
    def __init__(self, *args, **kwargs):
        super(DateTimeField, self).__init__(widget=TextInput(), *args, **kwargs)

class DateField(_DateField):
    def __init__(self, *args, **kwargs):
        super(DateField, self).__init__(widget=TextInput(), *args, **kwargs)

class FileField(_FileField):
    def __init__(self, *args, **kwargs):
        super(FileField, self).__init__(widget=FileInput(), *args, **kwargs)

class SelectMultipleField(_SelectMultipleField):
    def __init__(self, *args, **kwargs):
        super(SelectMultipleField, self).__init__(widget=Select(), *args, **kwargs)

<|endoftext|>


<commit_before>from django import forms
from .models import DeviceToken

class CertFileUploadForm(forms.Form):
    cert_file = forms.FileField()
    target = forms.ChoiceField(choices=((0, 'Develop'), (1, 'Distribute')), required=True, widget=forms.RadioSelect)

class NotificationSendForm(forms.Form):

    target = forms.ChoiceField(choices=((0, 'Develop'), (1, 'Distribute')), required=True, widget=forms.RadioSelect)
    device_token = forms.ModelMultipleChoiceField(label='Device Token',
                                                  queryset=DeviceToken.objects.all().values_list('device_token',
                                                                                flat=True)
                                                  )
    title = forms.CharField(required=True)
    subtitle = forms.CharField()
    body = forms.CharField()
    sound = forms.CharField(initial='default', required=True)
    badge = forms.IntegerField(initial=1, required=True)
    content_available = forms.BooleanField(initial=False)
    mutable_content = forms.BooleanField(initial=False)
    extra = forms.CharField(widget=forms.Textarea)
<commit_msg>Add initial notification's target #19<commit_after>from django import forms
from .models import DeviceToken

class CertFileUploadForm(forms.Form):
    cert_file = forms.FileField()
    target = forms.ChoiceField(choices=((0, 'Develop'), (1, 'Distribute')), required=True, widget=forms.RadioSelect)

class NotificationSendForm(forms.Form):

    target = forms.ChoiceField(choices=((0, 'Develop'), (1, 'Distribute')),
                               required=True,
                               widget=forms.RadioSelect,
                               initial=0)
    device_token = forms.ModelMultipleChoiceField(label='Device Token',
                                                  queryset=DeviceToken.objects.all().values_list('device_token',
                                                                                flat=True)
                                                  )
    title = forms.CharField(required=True)
    subtitle = forms.CharField()
    body = forms.CharField()
    sound = forms.CharField(initial='default', required=True)
    badge = forms.IntegerField(initial=1, required=True)
    content_available = forms.BooleanField(initial=False)
    mutable_content = forms.BooleanField(initial=False)
    extra = forms.CharField(widget=forms.Textarea)
<|endoftext|>


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

import riak
import memcache
import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.autoreload

from pandas import read_json

from .utils import pandas_to_dict, df_generate

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')
        dashboard = myBucket.get('dashboard').data

        self.render('index.html', dashboard=dashboard)

class DashboardHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, slug):

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')
        get_bucket = myBucket.get('dashboard').data

        dashboard = {}
        for d in get_bucket:
            if d['slug'] == slug:
                dashboard['slug'] = slug

                # GET ELEMENT
                _e = []
                for dash_element in d['element']:
                    element = myBucket.get('element').data
                    for e in element:
                        if dash_element == e['slug']:
                            try:
                                e['_type'] = e['type'].split('_')[1]
                            except:
                                e['_type'] = None
                            _e.append(e)
                    dashboard = _e

        self.render('dashboard.html', dashboard=dashboard)

class ProcessHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, slug):
        mc = memcache.Client(['127.0.0.1:11211'], debug=0)
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining')

        columns = json.loads(myBucket.get('{}-columns'.format(slug)).data)
        fields = columns
        if self.get_argument('fields', None):
            fields = self.get_argument('fields').split(',')

        filters = [i[0] for i in self.request.arguments.iteritems()
                   if len(i[0].split('filter__')) > 1]

        fields_json = json.dumps(fields)
        filters_json = json.dumps(filters)
        if mc.get(str(slug)) and\
                mc.get('{}-columns'.format(slug)) == fields_json and\
                mc.get('{}-fulters'.format(slug)) == filters_json:
            self.write(mc.get(str(slug)))
            self.finish()

        mc.set('{}-columns'.format(slug), fields_json)
        mc.set('{}-filters'.format(slug), filters_json)

        df = read_json(myBucket.get(slug).data)

        read = df[fields]
        if len(filters) >= 1:
            for f in filters:
                read = read.query(df_generate(df, self.get_argument, f))
        convert = pandas_to_dict(read)

        write = json.dumps({'columns': fields, 'json': convert})
        mc.set(str(slug), write)
        self.write(write)
        self.finish()
<commit_msg>Fix filters_json generate, add key/value on cache key<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json

import riak
import memcache
import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.autoreload

from pandas import read_json

from .utils import pandas_to_dict, df_generate

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')
        dashboard = myBucket.get('dashboard').data

        self.render('index.html', dashboard=dashboard)

class DashboardHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, slug):

        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining-admin')
        get_bucket = myBucket.get('dashboard').data

        dashboard = {}
        for d in get_bucket:
            if d['slug'] == slug:
                dashboard['slug'] = slug

                # GET ELEMENT
                _e = []
                for dash_element in d['element']:
                    element = myBucket.get('element').data
                    for e in element:
                        if dash_element == e['slug']:
                            try:
                                e['_type'] = e['type'].split('_')[1]
                            except:
                                e['_type'] = None
                            _e.append(e)
                    dashboard = _e

        self.render('dashboard.html', dashboard=dashboard)

class ProcessHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, slug):
        mc = memcache.Client(['127.0.0.1:11211'], debug=0)
        myClient = riak.RiakClient(protocol='http',
                                   http_port=8098,
                                   host='127.0.0.1')
        myBucket = myClient.bucket('openmining')

        columns = json.loads(myBucket.get('{}-columns'.format(slug)).data)
        fields = columns
        if self.get_argument('fields', None):
            fields = self.get_argument('fields').split(',')

        filters = [i[0] for i in self.request.arguments.iteritems()
                   if len(i[0].split('filter__')) > 1]

        fields_json = json.dumps(fields)
        filters_json = json.dumps({f: self.get_argument(f) for f in filters})
        if mc.get(str(slug)) and\
                mc.get('{}-columns'.format(slug)) == fields_json and\
                mc.get('{}-fulters'.format(slug)) == filters_json:
            self.write(mc.get(str(slug)))
            self.finish()

        mc.set('{}-columns'.format(slug), fields_json)
        mc.set('{}-filters'.format(slug), filters_json)

        df = read_json(myBucket.get(slug).data)

        read = df[fields]
        if len(filters) >= 1:
            for f in filters:
                read = read.query(df_generate(df, self.get_argument, f))
        convert = pandas_to_dict(read)

        write = json.dumps({'columns': fields, 'json': convert})
        mc.set(str(slug), write)
        self.write(write)
        self.finish()
<|endoftext|>


<commit_before>from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.syndication.views import feed

from notification.models import *
from notification.decorators import basic_auth_required, simple_basic_auth_callback
from notification.feeds import NoticeUserFeed

@basic_auth_required(realm='Notices Feed', callback_func=simple_basic_auth_callback)
def feed_for_user(request):
    """
    An atom feed for all unarchived :model:`notification.Notice`s for a user.
    """
    url = "feed/%s" % request.user.username
    return feed(request, url, {
        "feed": NoticeUserFeed,
    })

@login_required
def notices(request):
    """
    The main notices index view.

    Template: :template:`notification/notices.html`

    Context:

        notices
            A list of :model:`notification.Notice` objects that are not archived
            and to be displayed on the site.

        notice_types
            A list of all :model:`notification.NoticeType` objects.

        notice_settings
            A dictionary containing ``column_headers`` for each ``NOTICE_MEDIA``
            and ``rows`` containing a list of dictionaries: ``notice_type``, a
            :model:`notification.NoticeType` object and ``cells``, a list of
            tuples whose first value is suitable for use in forms and the second
            value is ``True`` or ``False`` depending on a ``request.POST``
            variable called ``form_label``, whose valid value is ``on``.
    """
    notice_types = NoticeType.objects.all()
    notices = Notice.objects.notices_for(request.user, on_site=True)
    settings_table = []
    for notice_type in NoticeType.objects.all():
        settings_row = []
        for medium_id, medium_display in NOTICE_MEDIA:
            form_label = "%s_%s" % (notice_type.label, medium_id)
            setting = get_notification_setting(request.user, notice_type, medium_id)
            if request.method == "POST":
                if request.POST.get(form_label) == "on":
                    setting.send = True
                else:
                    setting.send = False
                setting.save()
            settings_row.append((form_label, setting.send))
        settings_table.append({"notice_type": notice_type, "cells": settings_row})

    notice_settings = {
        "column_headers": [medium_display for medium_id, medium_display in NOTICE_MEDIA],
        "rows": settings_table,
    }

    return render_to_response("notification/notices.html", {
        "notices": notices,
        "notice_types": notice_types,
        "notice_settings": notice_settings,
    }, context_instance=RequestContext(request))

@login_required
def single(request, id, mark_seen=True):
    """
    Detail view for a single :model:`notification.Notice`.

    Template: :template:`notification/single.html`

    Context:

        notice
            The :model:`notification.Notice` being viewed

    Optional arguments:

        mark_seen
            If ``True``, mark the notice as seen if it isn't
            already.  Do nothing if ``False``.  Default: ``True``.
    """
    notice = get_object_or_404(Notice, id=id)
    if request.user == notice.user:
        if mark_seen and notice.unseen:
            notice.unseen = False
            notice.save()
        return render_to_response("notification/single.html", {
            "notice": notice,
        }, context_instance=RequestContext(request))
    raise Http404

@login_required
def archive(request, noticeid=None, next_page=None):
    """
    Archive a :model:`notices.Notice` if the requesting user is the
    recipient or if the user is a superuser.  Returns a
    ``HttpResponseRedirect`` when complete.

    Optional arguments:

        noticeid
            The ID of the :model:`notices.Notice` to be archived.

        next_page
            The page to redirect to when done.
    """
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.archive()
            else:   # you can archive other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def delete(request, noticeid=None, next_page=None):
    """
    Delete a :model:`notices.Notice` if the requesting user is the recipient
    or if the user is a superuser.  Returns a ``HttpResponseRedirect`` when
    complete.

    Optional arguments:

        noticeid
            The ID of the :model:`notices.Notice` to be archived.

        next_page
            The page to redirect to when done.
    """
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.delete()
            else:   # you can delete other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def mark_all_seen(request):
    """
    Mark all unseen notices for the requesting user as seen.  Returns a
    ``HttpResponseRedirect`` when complete.
    """

    for notice in Notice.objects.notices_for(request.user, unseen=True):
        notice.unseen = False
        notice.save()
    return HttpResponseRedirect(reverse("notification_notices"))
    <commit_msg>Updated a few outdated references to notice.user<commit_after>from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.syndication.views import feed

from notification.models import *
from notification.decorators import basic_auth_required, simple_basic_auth_callback
from notification.feeds import NoticeUserFeed

@basic_auth_required(realm='Notices Feed', callback_func=simple_basic_auth_callback)
def feed_for_user(request):
    """
    An atom feed for all unarchived :model:`notification.Notice`s for a user.
    """
    url = "feed/%s" % request.user.username
    return feed(request, url, {
        "feed": NoticeUserFeed,
    })

@login_required
def notices(request):
    """
    The main notices index view.

    Template: :template:`notification/notices.html`

    Context:

        notices
            A list of :model:`notification.Notice` objects that are not archived
            and to be displayed on the site.

        notice_types
            A list of all :model:`notification.NoticeType` objects.

        notice_settings
            A dictionary containing ``column_headers`` for each ``NOTICE_MEDIA``
            and ``rows`` containing a list of dictionaries: ``notice_type``, a
            :model:`notification.NoticeType` object and ``cells``, a list of
            tuples whose first value is suitable for use in forms and the second
            value is ``True`` or ``False`` depending on a ``request.POST``
            variable called ``form_label``, whose valid value is ``on``.
    """
    notice_types = NoticeType.objects.all()
    notices = Notice.objects.notices_for(request.user, on_site=True)
    settings_table = []
    for notice_type in NoticeType.objects.all():
        settings_row = []
        for medium_id, medium_display in NOTICE_MEDIA:
            form_label = "%s_%s" % (notice_type.label, medium_id)
            setting = get_notification_setting(request.user, notice_type, medium_id)
            if request.method == "POST":
                if request.POST.get(form_label) == "on":
                    setting.send = True
                else:
                    setting.send = False
                setting.save()
            settings_row.append((form_label, setting.send))
        settings_table.append({"notice_type": notice_type, "cells": settings_row})

    notice_settings = {
        "column_headers": [medium_display for medium_id, medium_display in NOTICE_MEDIA],
        "rows": settings_table,
    }

    return render_to_response("notification/notices.html", {
        "notices": notices,
        "notice_types": notice_types,
        "notice_settings": notice_settings,
    }, context_instance=RequestContext(request))

@login_required
def single(request, id, mark_seen=True):
    """
    Detail view for a single :model:`notification.Notice`.

    Template: :template:`notification/single.html`

    Context:

        notice
            The :model:`notification.Notice` being viewed

    Optional arguments:

        mark_seen
            If ``True``, mark the notice as seen if it isn't
            already.  Do nothing if ``False``.  Default: ``True``.
    """
    notice = get_object_or_404(Notice, id=id)
    if request.user == notice.recipient:
        if mark_seen and notice.unseen:
            notice.unseen = False
            notice.save()
        return render_to_response("notification/single.html", {
            "notice": notice,
        }, context_instance=RequestContext(request))
    raise Http404

@login_required
def archive(request, noticeid=None, next_page=None):
    """
    Archive a :model:`notices.Notice` if the requesting user is the
    recipient or if the user is a superuser.  Returns a
    ``HttpResponseRedirect`` when complete.

    Optional arguments:

        noticeid
            The ID of the :model:`notices.Notice` to be archived.

        next_page
            The page to redirect to when done.
    """
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.recipient or request.user.is_superuser:
                notice.archive()
            else:   # you can archive other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def delete(request, noticeid=None, next_page=None):
    """
    Delete a :model:`notices.Notice` if the requesting user is the recipient
    or if the user is a superuser.  Returns a ``HttpResponseRedirect`` when
    complete.

    Optional arguments:

        noticeid
            The ID of the :model:`notices.Notice` to be archived.

        next_page
            The page to redirect to when done.
    """
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.recipient or request.user.is_superuser:
                notice.delete()
            else:   # you can delete other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def mark_all_seen(request):
    """
    Mark all unseen notices for the requesting user as seen.  Returns a
    ``HttpResponseRedirect`` when complete.
    """

    for notice in Notice.objects.notices_for(request.user, unseen=True):
        notice.unseen = False
        notice.save()
    return HttpResponseRedirect(reverse("notification_notices"))
    <|endoftext|>


<commit_before>from django.views.generic import TemplateView, FormView
from django.contrib.messages import add_message
from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse

import stored_messages

class IndexView(FormView):
    template_name = 'notification/homepage.html'
    form_class = AuthenticationForm
    success_url = '/'

    def get_context_data(self, **kwargs):
        add_message(self.request, stored_messages.STORED_INFO, 'You visited the homepage')
        return super(IndexView, self).get_context_data(**kwargs)

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(IndexView, self).form_valid(form)

class MessagesView(TemplateView):
    template_name = 'notification/messages.html'

    def get_context_data(self, **kwargs):
        add_message(self.request, stored_messages.STORED_INFO,
                    'You visited the notifications page')
        return super(MessagesView, self).get_context_data(**kwargs)
<commit_msg>do not add message on message view<commit_after>from django.views.generic import TemplateView, FormView
from django.contrib.messages import add_message
from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse

import stored_messages

class IndexView(FormView):
    template_name = 'notification/homepage.html'
    form_class = AuthenticationForm
    success_url = '/'

    def get_context_data(self, **kwargs):
        add_message(self.request, stored_messages.STORED_INFO, 'You visited the homepage')
        return super(IndexView, self).get_context_data(**kwargs)

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(IndexView, self).form_valid(form)

class MessagesView(TemplateView):
    template_name = 'notification/messages.html'

    def get_context_data(self, **kwargs):
        return super(MessagesView, self).get_context_data(**kwargs)
<|endoftext|>


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

"""
Receive Geo location data from the Gps2Udp Android application
and forward them to the stdout line by line.
"""

import getopt
import os.path
import socket
import sys

DEFAULT_PORT = 5000

def usage(exitcode = 1):
    """
    Show usage info and exit.
    """
    argv0 = os.path.basename(sys.argv[0])
    print 'Usage: {0} [options]'.format(argv0)
    print '  Options:'
    print '    --port=N   UDP port number to listen. Default is 5000.'
    sys.exit(exitcode)

def main():
    """
    Entry point.
    """
    try:
        cmd_opts, cmd_args = getopt.getopt(
            sys.argv[1:], '', ['port=', 'quiet'])
    except getopt.GetoptError as exc:
        print str(exc)
        usage
    cmd_opts = dict(cmd_opts)
    port = int(cmd_opts.get('--port', str(DEFAULT_PORT)))
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('', port))
    while True:
        data, _addr = sock.recvfrom(100)
        try:
            tokens = data.split(' ')
            _time = int(tokens[0])
        except Exception:
            continue
        sys.stdout.write(data)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit(1)
<commit_msg>pyserver: make output unbuffered<commit_after>#!/usr/bin/env python

"""
Receive Geo location data from the Gps2Udp Android application
and forward them to the stdout line by line.
"""

import getopt
import os.path
import socket
import sys

DEFAULT_PORT = 5000

def usage(exitcode = 1):
    """
    Show usage info and exit.
    """
    argv0 = os.path.basename(sys.argv[0])
    print 'Usage: {0} [options]'.format(argv0)
    print '  Options:'
    print '    --port=N   UDP port number to listen. Default is 5000.'
    sys.exit(exitcode)

def main():
    """
    Entry point.
    """
    try:
        cmd_opts, cmd_args = getopt.getopt(
            sys.argv[1:], '', ['port=', 'quiet'])
    except getopt.GetoptError as exc:
        print str(exc)
        usage
    cmd_opts = dict(cmd_opts)
    port = int(cmd_opts.get('--port', str(DEFAULT_PORT)))
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('', port))
    while True:
        data, _addr = sock.recvfrom(100)
        try:
            tokens = data.split(' ')
            _time = int(tokens[0])
        except Exception:
            continue
        sys.stdout.write(data)
        sys.stdout.flush()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit(1)
<|endoftext|>


<commit_before>from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.syndication.views import feed

from notification.models import *
from notification.decorators import basic_auth_required, simple_basic_auth_callback
from notification.feeds import NoticeUserFeed

@basic_auth_required(realm='Notices Feed', callback_func=simple_basic_auth_callback)
def feed_for_user(request):
    url = "feed/%s" % request.user.username
    return feed(request, url, {
        "feed": NoticeUserFeed,
    })

@login_required
def notices(request):
    notice_types = NoticeType.objects.all()
    notices = Notice.objects.notices_for(request.user, on_site=True)
    settings_table = []
    for notice_type in NoticeType.objects.all():
        settings_row = []
        for medium_id, medium_display in NOTICE_MEDIA:
            form_label = "%s_%s" % (notice_type.label, medium_id)
            setting = get_notification_setting(request.user, notice_type, medium_id)
            if request.method == "POST":
                if request.POST.get(form_label) == "on":
                    setting.send = True
                else:
                    setting.send = False
                setting.save()
            settings_row.append((form_label, setting.send))
        settings_table.append({"notice_type": notice_type, "cells": settings_row})

    notice_settings = {
        "column_headers": [medium_display for medium_id, medium_display in NOTICE_MEDIA],
        "rows": settings_table,
    }

    return render_to_response("notification/notices.html", {
        "notices": notices,
        "notice_types": notice_types,
        "notice_settings": notice_settings,
    }, context_instance=RequestContext(request))

@login_required
def single(request, id):
    notice = get_object_or_404(Notice, id=id)
    if request.user == notice.user:
        return render_to_response("notification/single.html", {
            "notice": notice,
        }, context_instance=RequestContext(request))
    raise Http404

@login_required
def archive(request, noticeid=None, next_page=None):
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.archive()
            else:   # you can archive other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def delete(request, noticeid=None, next_page=None):
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.delete()
            else:   # you can delete other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def mark_all_seen(request):
    for notice in Notice.objects.notices_for(request.user, unseen=True):
        notice.unseen = False
        notice.save()
    return HttpResponseRedirect(reverse("notification_notices"))
    <commit_msg>Mark all notifications as seen with one query.<commit_after>from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.syndication.views import feed

from notification.models import *
from notification.decorators import basic_auth_required, simple_basic_auth_callback
from notification.feeds import NoticeUserFeed

@basic_auth_required(realm='Notices Feed', callback_func=simple_basic_auth_callback)
def feed_for_user(request):
    url = "feed/%s" % request.user.username
    return feed(request, url, {
        "feed": NoticeUserFeed,
    })

@login_required
def notices(request):
    notice_types = NoticeType.objects.all()
    notices = Notice.objects.notices_for(request.user, on_site=True)
    settings_table = []
    for notice_type in NoticeType.objects.all():
        settings_row = []
        for medium_id, medium_display in NOTICE_MEDIA:
            form_label = "%s_%s" % (notice_type.label, medium_id)
            setting = get_notification_setting(request.user, notice_type, medium_id)
            if request.method == "POST":
                if request.POST.get(form_label) == "on":
                    setting.send = True
                else:
                    setting.send = False
                setting.save()
            settings_row.append((form_label, setting.send))
        settings_table.append({"notice_type": notice_type, "cells": settings_row})

    notice_settings = {
        "column_headers": [medium_display for medium_id, medium_display in NOTICE_MEDIA],
        "rows": settings_table,
    }

    return render_to_response("notification/notices.html", {
        "notices": notices,
        "notice_types": notice_types,
        "notice_settings": notice_settings,
    }, context_instance=RequestContext(request))

@login_required
def single(request, id):
    notice = get_object_or_404(Notice, id=id)
    if request.user == notice.user:
        return render_to_response("notification/single.html", {
            "notice": notice,
        }, context_instance=RequestContext(request))
    raise Http404

@login_required
def archive(request, noticeid=None, next_page=None):
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.archive()
            else:   # you can archive other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def delete(request, noticeid=None, next_page=None):
    if noticeid:
        try:
            notice = Notice.objects.get(id=noticeid)
            if request.user == notice.user or request.user.is_superuser:
                notice.delete()
            else:   # you can delete other users' notices
                    # only if you are superuser.
                return HttpResponseRedirect(next_page)
        except Notice.DoesNotExist:
            return HttpResponseRedirect(next_page)
    return HttpResponseRedirect(next_page)

@login_required
def mark_all_seen(request):
    Notice.objects.notices_for(request.user, unseen=True).update(unseen=False)
    return HttpResponseRedirect(reverse("notification_notices"))
    <|endoftext|>