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

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

__revision__ = "$Id$"

import fix

import re
import socket
import urllib2
import urlparse

class WebError(Exception):
    pass

urlRe = re.compile(r"(\w+://[^\])>\s]+)", re.I)

REFUSED = 'Connection refused.'
TIMED_OUT = 'Connection timed out.'
RESET_BY_PEER = 'Connection reset by peer.'

def getUrlFd(url):
    """Gets a file-like object for a url."""
    try:
        fd = urllib2.urlopen(url)
        return fd
    except socket.timeout, e:
        raise WebError, TIMED_OUT
    except socket.error, e:
        if e.args[0] == 111:
            raise WebError, REFUSED
        elif e.args[0] in (110, 10060):
            raise WebError, TIMED_OUT
        elif e.args[0] == 104:
            raise WebError, RESET_BY_PEER
        else:
            raise WebError, str(e)
    except (urllib2.HTTPError, urllib2.URLError), e:
        raise WebError, str(e)

def getUrl(url, size=None):
    """Gets a page.  Returns a string that is the page gotten."""
    fd = getUrlFd(url)
    try:
        if size is None:
            text = fd.read()
        else:
            text = fd.read(size)
    except socket.timeout, e:
        raise WebError, TIMED_OUT
    fd.close()
    return text

def getDomain(url):
    return urlparse.urlparse(url)[1]

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

<commit_msg>Updated slightly.<commit_after>#!/usr/bin/env python

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

__revision__ = "$Id$"

import fix

import re
import socket
import urllib2
import urlparse

class WebError(Exception):
    pass

urlRe = re.compile(r"(\w+://[^\])>\s]+)", re.I)

REFUSED = 'Connection refused.'
TIMED_OUT = 'Connection timed out.'
UNKNOWN_HOST = 'Unknown host.'
RESET_BY_PEER = 'Connection reset by peer.'

def strError(e):
    try:
        n = e.args[0]
    except Exception:
        return str(e)
    if n == 111:
        return REFUSED
    elif n in (110, 10060):
        return TIMED_OUT
    elif n == 104:
        return RESET_BY_PEER
    elif n == 8:
        return UNKNOWN_HOST
    else:
        return str(e)

def getUrlFd(url):
    """Gets a file-like object for a url."""
    try:
        fd = urllib2.urlopen(url)
        return fd
    except socket.timeout, e:
        raise WebError, TIMED_OUT
    except socket.error, e:
        raise WebError, strError(e)
    except urllib2.URLError, e:
        raise WebError, strError(e.reason)
    except urllib2.HTTPError, e:
        raise WebError, str(e)

def getUrl(url, size=None):
    """Gets a page.  Returns a string that is the page gotten."""
    fd = getUrlFd(url)
    try:
        if size is None:
            text = fd.read()
        else:
            text = fd.read(size)
    except socket.timeout, e:
        raise WebError, TIMED_OUT
    fd.close()
    return text

def getDomain(url):
    return urlparse.urlparse(url)[1]

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

<|endoftext|>


<commit_before># coding: utf-8
import os
import sys
import time
import socket
import webbrowser
from uuid import getnode as get_mac
from threading import Thread
from time import sleep

# Local
from client import PY2, FakeLamp
from pulser import Pulser
from optparse import OptionParser

WINDOWS = 'nt' == os.name

# Fill the 2<>3 gap
if PY2:
    from Queue import Queue
    from Tkinter import Tk, Canvas, Menu, mainloop, BitmapImage
    import tkMessageBox
    messagebox = tkMessageBox
else:
    from tkinter import Tk, Canvas, Menu, messagebox, mainloop, BitmapImage
    from queue import Queue

print('Running in ' + ('Python 2.7' if PY2 else 'Python 3.x') + ' mode.')

running = True

pulser = Pulser(primary=(0, 0, 255))

mac = repr(hex(get_mac()))[3:-1]

parser = OptionParser()
parser.add_option("-c", "--controller",
                  dest="controller",
                  help="controller hostname [default: %default]",
                  default="api.cilamp.se")
parser.add_option("-p", "--port",
                  dest="port",
                  help="controller port [default: %default]",
                  default=4040)
parser.add_option("-i", "--cimid",
                  dest="cimid",
                  help="Lamp ID [default: %default]",
                  default=mac)
parser.add_option("-l", "--log",
                  dest="logfile",
                  help="Log commands received to file",
                  default=None)
(options, args) = parser.parse_args()

print("--MANUAL--")
parser.print_help()
print("----------")

CIMID = options.cimid

def log(msg):
    if options.logfile:
        import datetime
        now = datetime.datetime.now()
        fullmsg = now.strftime("%Y-%M-%d %H:%M:%S") + " " + msg
        print(fullmsg)
        with open(options.logfile, 'a') as f:
            f.write(fullmsg + '\n')

# priority of ID:
# 1. command line
# 2. winlamp.id file
# 3. default (succinct MAC)
# (the OptionParser handles case 1 and 3;
# algo below hacks itself into 2!)
if CIMID == mac:
    idfile = 'winlamp.id'
    if os.path.exists('winlamp.id'):
        print(".id file found, using it.")
        with open(idfile) as f:
            CIMID = f.read().strip()

def command_handler(commandline):
    global pulser
    commandline = commandline.decode('utf8')
    log("received command '%s.'" % commandline)
    parts = commandline.split(' ')
    cmd = parts[0]
    if cmd == 'color':
        print("Static color mode.")
        assert len(parts) == 4
        rgb = tuple(map(int, parts[1:]))
        pulser = Pulser(primary=rgb)
    if cmd == 'pulse_1':
        print("Single pulsing color mode.")
        assert len(parts) == 5
        rgb = tuple(map(int, parts[1:4]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb, hz=hz)
    if cmd == 'pulse_2':
        print("Two color pulse mode.")
        assert len(parts) == 8
        rgb1 = tuple(map(int, parts[1:4]))
        rgb2 = tuple(map(int, parts[4:7]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb1, secondary=rgb2, hz=hz)

CONTROLLER_HOST = options.controller
CONTROLLER_PORT = int(options.port)
API_HOST = CONTROLLER_HOST
API_PORT = 8080
V1_LAMP_URL = 'https://%s/v1/%s/' % (API_HOST, CIMID)

def state_changed(new_state):
    print("Connection state changed to: " + new_state)

fakelamp = FakeLamp(CONTROLLER_HOST, CONTROLLER_PORT, CIMID,
                    command_handler, state_changed)
fakelamp.start()

curl_cmdline = 'curl -X POST -F "color=#FF0000" %s' % V1_LAMP_URL
manual = 'ID: %s\n\nMake lamp red:\n%s\n' % (CIMID, curl_cmdline)
print(manual)

master = Tk()

ox = 0
oy = 0

def lmb_down(ev):
    # Drag-to-move hack
    global ox, oy
    (ox, oy) = (ev.x, ev.y)

def lmb_move(ev):
    global ox, oy
    x = master.winfo_pointerx() - ox
    y = master.winfo_pointery() - oy
    master.geometry("+%d+%d" % (x, y))

winsize = 68
canvas = Canvas(master, width=winsize, height=winsize, highlightthickness=0,
                bd=0, relief='ridge')
i = canvas.create_rectangle(0, 0, winsize-1, winsize-1,
                            fill="blue", outline="black")

canvas.pack(padx=0, pady=0)
canvas.configure(bg="white")
canvas.bind("<Button-1>", lmb_down)
canvas.bind("<B1-Motion>", lmb_move)

bmpsize_px = 64  # Tribute to C64 :)
bmpdata = "0x99," * bmpsize_px ** 2
BITMAP = """
#define im_width %d
#define im_height %d
static char im_bits[] = {
%s
};
""" % (bmpsize_px, bmpsize_px, bmpdata)

bmp = BitmapImage(data=BITMAP)

j = canvas.create_image((winsize/2, winsize/2), image=bmp)

def setcolor(r, g, b):
    def byte2hex(b):
        return hex(256+b)[-2:]
    (re, gr, bl) = map(byte2hex, (r, g, b))
    col = "#%s%s%s" % (re, gr, bl)
    canvas.itemconfig(i, fill=col)

def update_color():
    canvas.after(20, update_color)

    (r, g, b) = pulser.seconds(time.time())
    setcolor(r, g, b)

canvas.after(20, update_color)

def show_tester(e):
    print("Opening web based URL generator in browser...")
    tester_url = 'https://cilamp.se/api/v1/url-generator/#' + CIMID
    webbrowser.open(tester_url)

canvas.bind("<Button-2>", show_tester)
canvas.bind("<Button-3>", show_tester)

def quit_app():
    print("Quitting app.")
    global running
    running = False
    master.after(10, lambda: master.destroy())
    return ""

master.overrideredirect(True)
master.geometry("+250+250")
master.lift()
master.wm_attributes("-topmost", True)
# master.wm_attributes("-disabled", True)
if WINDOWS:
    master.wm_attributes("-transparentcolor", "white")

mainloop()
<commit_msg>fix RMB link to test page<commit_after># coding: utf-8
import os
import sys
import time
import socket
import webbrowser
from uuid import getnode as get_mac
from threading import Thread
from time import sleep

# Local
from client import PY2, FakeLamp
from pulser import Pulser
from optparse import OptionParser

WINDOWS = 'nt' == os.name

# Fill the 2<>3 gap
if PY2:
    from Queue import Queue
    from Tkinter import Tk, Canvas, Menu, mainloop, BitmapImage
    import tkMessageBox
    messagebox = tkMessageBox
else:
    from tkinter import Tk, Canvas, Menu, messagebox, mainloop, BitmapImage
    from queue import Queue

print('Running in ' + ('Python 2.7' if PY2 else 'Python 3.x') + ' mode.')

running = True

pulser = Pulser(primary=(0, 0, 255))

mac = repr(hex(get_mac()))[3:-1]

parser = OptionParser()
parser.add_option("-c", "--controller",
                  dest="controller",
                  help="controller hostname [default: %default]",
                  default="api.cilamp.se")
parser.add_option("-p", "--port",
                  dest="port",
                  help="controller port [default: %default]",
                  default=4040)
parser.add_option("-i", "--cimid",
                  dest="cimid",
                  help="Lamp ID [default: %default]",
                  default=mac)
parser.add_option("-l", "--log",
                  dest="logfile",
                  help="Log commands received to file",
                  default=None)
(options, args) = parser.parse_args()

print("--MANUAL--")
parser.print_help()
print("----------")

CIMID = options.cimid

def log(msg):
    if options.logfile:
        import datetime
        now = datetime.datetime.now()
        fullmsg = now.strftime("%Y-%M-%d %H:%M:%S") + " " + msg
        print(fullmsg)
        with open(options.logfile, 'a') as f:
            f.write(fullmsg + '\n')

# priority of ID:
# 1. command line
# 2. winlamp.id file
# 3. default (succinct MAC)
# (the OptionParser handles case 1 and 3;
# algo below hacks itself into 2!)
if CIMID == mac:
    idfile = 'winlamp.id'
    if os.path.exists('winlamp.id'):
        print(".id file found, using it.")
        with open(idfile) as f:
            CIMID = f.read().strip()

def command_handler(commandline):
    global pulser
    commandline = commandline.decode('utf8')
    log("received command '%s.'" % commandline)
    parts = commandline.split(' ')
    cmd = parts[0]
    if cmd == 'color':
        print("Static color mode.")
        assert len(parts) == 4
        rgb = tuple(map(int, parts[1:]))
        pulser = Pulser(primary=rgb)
    if cmd == 'pulse_1':
        print("Single pulsing color mode.")
        assert len(parts) == 5
        rgb = tuple(map(int, parts[1:4]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb, hz=hz)
    if cmd == 'pulse_2':
        print("Two color pulse mode.")
        assert len(parts) == 8
        rgb1 = tuple(map(int, parts[1:4]))
        rgb2 = tuple(map(int, parts[4:7]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb1, secondary=rgb2, hz=hz)

CONTROLLER_HOST = options.controller
CONTROLLER_PORT = int(options.port)
API_HOST = CONTROLLER_HOST
API_PORT = 8080
V1_LAMP_URL = 'https://%s/v1/%s/' % (API_HOST, CIMID)

def state_changed(new_state):
    print("Connection state changed to: " + new_state)

fakelamp = FakeLamp(CONTROLLER_HOST, CONTROLLER_PORT, CIMID,
                    command_handler, state_changed)
fakelamp.start()

curl_cmdline = 'curl -X POST -F "color=#FF0000" %s' % V1_LAMP_URL
manual = 'ID: %s\n\nMake lamp red:\n%s\n' % (CIMID, curl_cmdline)
print(manual)

master = Tk()

ox = 0
oy = 0

def lmb_down(ev):
    # Drag-to-move hack
    global ox, oy
    (ox, oy) = (ev.x, ev.y)

def lmb_move(ev):
    global ox, oy
    x = master.winfo_pointerx() - ox
    y = master.winfo_pointery() - oy
    master.geometry("+%d+%d" % (x, y))

winsize = 68
canvas = Canvas(master, width=winsize, height=winsize, highlightthickness=0,
                bd=0, relief='ridge')
i = canvas.create_rectangle(0, 0, winsize-1, winsize-1,
                            fill="blue", outline="black")

canvas.pack(padx=0, pady=0)
canvas.configure(bg="white")
canvas.bind("<Button-1>", lmb_down)
canvas.bind("<B1-Motion>", lmb_move)

bmpsize_px = 64  # Tribute to C64 :)
bmpdata = "0x99," * bmpsize_px ** 2
BITMAP = """
#define im_width %d
#define im_height %d
static char im_bits[] = {
%s
};
""" % (bmpsize_px, bmpsize_px, bmpdata)

bmp = BitmapImage(data=BITMAP)

j = canvas.create_image((winsize/2, winsize/2), image=bmp)

def setcolor(r, g, b):
    def byte2hex(b):
        return hex(256+b)[-2:]
    (re, gr, bl) = map(byte2hex, (r, g, b))
    col = "#%s%s%s" % (re, gr, bl)
    canvas.itemconfig(i, fill=col)

def update_color():
    canvas.after(20, update_color)

    (r, g, b) = pulser.seconds(time.time())
    setcolor(r, g, b)

canvas.after(20, update_color)

def show_tester(e):
    print("Opening web based URL generator in browser...")
    tester_url = 'https://cilamp.se/url-generator/#' + CIMID
    webbrowser.open(tester_url)

canvas.bind("<Button-2>", show_tester)
canvas.bind("<Button-3>", show_tester)

def quit_app():
    print("Quitting app.")
    global running
    running = False
    master.after(10, lambda: master.destroy())
    return ""

master.overrideredirect(True)
master.geometry("+250+250")
master.lift()
master.wm_attributes("-topmost", True)
# master.wm_attributes("-disabled", True)
if WINDOWS:
    master.wm_attributes("-transparentcolor", "white")

mainloop()
<|endoftext|>


<commit_before># coding: utf-8
import os
import sys
import time
import socket
import webbrowser
from uuid import getnode as get_mac
from threading import Thread
from time import sleep

# Local
from client import PY2, FakeLamp
from pulser import Pulser
from optparse import OptionParser

WINDOWS = 'nt' == os.name

# Fill the 2<>3 gap
if PY2:
    from Queue import Queue
    from Tkinter import Tk, Canvas, Menu, mainloop, BitmapImage
    import tkMessageBox
    messagebox = tkMessageBox
else:
    from tkinter import Tk, Canvas, Menu, messagebox, mainloop, BitmapImage
    from queue import Queue

print('Running in ' + ('Python 2.7' if PY2 else 'Python 3.x') + ' mode.')

running = True

pulser = Pulser(primary=(0, 0, 255))

mac = repr(hex(get_mac()))[3:-1]

parser = OptionParser()
parser.add_option("-c", "--controller",
                  dest="controller",
                  help="controller hostname [default: %default]",
                  default="api.cilamp.se")
parser.add_option("-p", "--port",
                  dest="port",
                  help="controller port [default: %default]",
                  default=4040)
parser.add_option("-i", "--cimid",
                  dest="cimid",
                  help="Lamp ID [default: %default]",
                  default=mac)
parser.add_option("-l", "--log",
                  dest="logfile",
                  help="Log commands received to file",
                  default=None)
(options, args) = parser.parse_args()

print("--MANUAL--")
parser.print_help()
print("----------")

CIMID = options.cimid

def log(msg):
    if options.logfile:
        import datetime
        now = datetime.datetime.now()
        fullmsg = now.strftime("%Y-%M-%d %H:%M:%S") + " " + msg
        print(fullmsg)
        with open(options.logfile, 'a') as f:
            f.write(fullmsg + '\n')

# priority of ID:
# 1. command line
# 2. winlamp.id file
# 3. default (succinct MAC)
# (the OptionParser handles case 1 and 3;
# algo below hacks itself into 2!)
if CIMID == mac:
    idfile = 'winlamp.id'
    if os.path.exists('winlamp.id'):
        print(".id file found, using it.")
        with open(idfile) as f:
            CIMID = f.read().strip()

def command_handler(commandline):
    global pulser
    commandline = commandline.decode('utf8')
    log("received command '%s.'" % commandline)
    parts = commandline.split(' ')
    cmd = parts[0]
    if cmd == 'color':
        print("Static color mode.")
        assert len(parts) == 4
        rgb = tuple(map(int, parts[1:]))
        pulser = Pulser(primary=rgb)
    if cmd == 'pulse_1':
        print("Single pulsing color mode.")
        assert len(parts) == 5
        rgb = tuple(map(int, parts[1:4]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb, hz=hz)
    if cmd == 'pulse_2':
        print("Two color pulse mode.")
        assert len(parts) == 8
        rgb1 = tuple(map(int, parts[1:4]))
        rgb2 = tuple(map(int, parts[4:7]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb1, secondary=rgb2, hz=hz)

CONTROLLER_HOST = options.controller
CONTROLLER_PORT = int(options.port)
API_HOST = CONTROLLER_HOST
API_PORT = 8080
LAMP_URL = 'https://%s/v1/%s/' % (API_HOST, CIMID)

def colorapi_url(r, g, b):
    return LAMP_URL + 'color=%d,%d,%d' % (r, g, b)

def state_changed(new_state):
    print("Connection state changed to: " + new_state)
    if new_state in ["CONNECTING", "DISCONNECTED"]:
        global pulser
        pulser = Pulser(primary=(50, 50, 200),
                        secondary=(50, 200, 50),
                        hz=0.25)

fakelamp = FakeLamp(CONTROLLER_HOST, CONTROLLER_PORT, CIMID,
                    command_handler, state_changed)
fakelamp.start()

manual = 'ID: %s\n\nMake lamp red:\n%s\n' % (CIMID, colorapi_url(255, 0, 0))
print(manual)

master = Tk()

ox = 0
oy = 0

def lmb_down(ev):
    # Drag-to-move hack
    global ox, oy
    (ox, oy) = (ev.x, ev.y)

def lmb_move(ev):
    global ox, oy
    x = master.winfo_pointerx() - ox
    y = master.winfo_pointery() - oy
    master.geometry("+%d+%d" % (x, y))

winsize = 68
canvas = Canvas(master, width=winsize, height=winsize, highlightthickness=0,
                bd=0, relief='ridge')
i = canvas.create_rectangle(0, 0, winsize-1, winsize-1,
                            fill="blue", outline="black")

canvas.pack(padx=0, pady=0)
canvas.configure(bg="white")
canvas.bind("<Button-1>", lmb_down)
canvas.bind("<B1-Motion>", lmb_move)

bmpsize_px = 64  # Tribute to C64 :)
bmpdata = "0x99," * bmpsize_px ** 2
BITMAP = """
#define im_width %d
#define im_height %d
static char im_bits[] = {
%s
};
""" % (bmpsize_px, bmpsize_px, bmpdata)

bmp = BitmapImage(data=BITMAP)

j = canvas.create_image((winsize/2, winsize/2), image=bmp)

def setcolor(r, g, b):
    def byte2hex(b):
        return hex(256+b)[-2:]
    (re, gr, bl) = map(byte2hex, (r, g, b))
    col = "#%s%s%s" % (re, gr, bl)
    canvas.itemconfig(i, fill=col)

def update_color():
    canvas.after(20, update_color)

    (r, g, b) = pulser.seconds(time.time())
    setcolor(r, g, b)

canvas.after(20, update_color)

def show_manual():
    messagebox.showinfo("Quck start", manual)

def show_tester():
    print("Opening web based URL generator in browser...")
    tester_url = 'https://cilamp.se/url-generator/#' + CIMID
    webbrowser.open(tester_url)

def quit_app():
    print("Quitting app.")
    global running
    running = False
    master.after(10, lambda: master.destroy())
    return ""

popup = Menu(master, tearoff=0)
popup.add_command(label="Quick start", command=show_manual)
popup.add_command(label="URL Generator", command=show_tester)
popup.add_separator()
popup.add_command(label="Quit", command=quit_app)

def do_popup(event):
    # display the popup menu
    try:
        popup.tk_popup(event.x_root, event.y_root, 0)
    finally:
        # make sure to release the grab (Tk 8.0a1 only)
        popup.grab_release()

canvas.bind("<Button-2>", do_popup)
canvas.bind("<Button-3>", do_popup)

master.overrideredirect(True)
master.geometry("+250+250")
master.lift()
master.wm_attributes("-topmost", True)
# master.wm_attributes("-disabled", True)
if WINDOWS:
    master.wm_attributes("-transparentcolor", "white")

mainloop()
<commit_msg>Open context menu on RMB release instead of press<commit_after># coding: utf-8
import os
import sys
import time
import socket
import webbrowser
from uuid import getnode as get_mac
from threading import Thread
from time import sleep

# Local
from client import PY2, FakeLamp
from pulser import Pulser
from optparse import OptionParser

WINDOWS = 'nt' == os.name

# Fill the 2<>3 gap
if PY2:
    from Queue import Queue
    from Tkinter import Tk, Canvas, Menu, mainloop, BitmapImage
    import tkMessageBox
    messagebox = tkMessageBox
else:
    from tkinter import Tk, Canvas, Menu, messagebox, mainloop, BitmapImage
    from queue import Queue

print('Running in ' + ('Python 2.7' if PY2 else 'Python 3.x') + ' mode.')

running = True

pulser = Pulser(primary=(0, 0, 255))

mac = repr(hex(get_mac()))[3:-1]

parser = OptionParser()
parser.add_option("-c", "--controller",
                  dest="controller",
                  help="controller hostname [default: %default]",
                  default="api.cilamp.se")
parser.add_option("-p", "--port",
                  dest="port",
                  help="controller port [default: %default]",
                  default=4040)
parser.add_option("-i", "--cimid",
                  dest="cimid",
                  help="Lamp ID [default: %default]",
                  default=mac)
parser.add_option("-l", "--log",
                  dest="logfile",
                  help="Log commands received to file",
                  default=None)
(options, args) = parser.parse_args()

print("--MANUAL--")
parser.print_help()
print("----------")

CIMID = options.cimid

def log(msg):
    if options.logfile:
        import datetime
        now = datetime.datetime.now()
        fullmsg = now.strftime("%Y-%M-%d %H:%M:%S") + " " + msg
        print(fullmsg)
        with open(options.logfile, 'a') as f:
            f.write(fullmsg + '\n')

# priority of ID:
# 1. command line
# 2. winlamp.id file
# 3. default (succinct MAC)
# (the OptionParser handles case 1 and 3;
# algo below hacks itself into 2!)
if CIMID == mac:
    idfile = 'winlamp.id'
    if os.path.exists('winlamp.id'):
        print(".id file found, using it.")
        with open(idfile) as f:
            CIMID = f.read().strip()

def command_handler(commandline):
    global pulser
    commandline = commandline.decode('utf8')
    log("received command '%s.'" % commandline)
    parts = commandline.split(' ')
    cmd = parts[0]
    if cmd == 'color':
        print("Static color mode.")
        assert len(parts) == 4
        rgb = tuple(map(int, parts[1:]))
        pulser = Pulser(primary=rgb)
    if cmd == 'pulse_1':
        print("Single pulsing color mode.")
        assert len(parts) == 5
        rgb = tuple(map(int, parts[1:4]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb, hz=hz)
    if cmd == 'pulse_2':
        print("Two color pulse mode.")
        assert len(parts) == 8
        rgb1 = tuple(map(int, parts[1:4]))
        rgb2 = tuple(map(int, parts[4:7]))
        hz = float(parts[-1])
        print("%s Hz." % hz)
        pulser = Pulser(primary=rgb1, secondary=rgb2, hz=hz)

CONTROLLER_HOST = options.controller
CONTROLLER_PORT = int(options.port)
API_HOST = CONTROLLER_HOST
API_PORT = 8080
LAMP_URL = 'https://%s/v1/%s/' % (API_HOST, CIMID)

def colorapi_url(r, g, b):
    return LAMP_URL + 'color=%d,%d,%d' % (r, g, b)

def state_changed(new_state):
    print("Connection state changed to: " + new_state)
    if new_state in ["CONNECTING", "DISCONNECTED"]:
        global pulser
        pulser = Pulser(primary=(50, 50, 200),
                        secondary=(50, 200, 50),
                        hz=0.25)

fakelamp = FakeLamp(CONTROLLER_HOST, CONTROLLER_PORT, CIMID,
                    command_handler, state_changed)
fakelamp.start()

manual = 'ID: %s\n\nMake lamp red:\n%s\n' % (CIMID, colorapi_url(255, 0, 0))
print(manual)

master = Tk()

ox = 0
oy = 0

def lmb_down(ev):
    # Drag-to-move hack
    global ox, oy
    (ox, oy) = (ev.x, ev.y)

def lmb_move(ev):
    global ox, oy
    x = master.winfo_pointerx() - ox
    y = master.winfo_pointery() - oy
    master.geometry("+%d+%d" % (x, y))

winsize = 68
canvas = Canvas(master, width=winsize, height=winsize, highlightthickness=0,
                bd=0, relief='ridge')
i = canvas.create_rectangle(0, 0, winsize-1, winsize-1,
                            fill="blue", outline="black")

canvas.pack(padx=0, pady=0)
canvas.configure(bg="white")
canvas.bind("<Button-1>", lmb_down)
canvas.bind("<B1-Motion>", lmb_move)

bmpsize_px = 64  # Tribute to C64 :)
bmpdata = "0x99," * bmpsize_px ** 2
BITMAP = """
#define im_width %d
#define im_height %d
static char im_bits[] = {
%s
};
""" % (bmpsize_px, bmpsize_px, bmpdata)

bmp = BitmapImage(data=BITMAP)

j = canvas.create_image((winsize/2, winsize/2), image=bmp)

def setcolor(r, g, b):
    def byte2hex(b):
        return hex(256+b)[-2:]
    (re, gr, bl) = map(byte2hex, (r, g, b))
    col = "#%s%s%s" % (re, gr, bl)
    canvas.itemconfig(i, fill=col)

def update_color():
    canvas.after(20, update_color)

    (r, g, b) = pulser.seconds(time.time())
    setcolor(r, g, b)

canvas.after(20, update_color)

def show_manual():
    messagebox.showinfo("Quck start", manual)

def show_tester():
    print("Opening web based URL generator in browser...")
    tester_url = 'https://cilamp.se/url-generator/#' + CIMID
    webbrowser.open(tester_url)

def quit_app():
    print("Quitting app.")
    global running
    running = False
    master.after(10, lambda: master.destroy())
    return ""

popup = Menu(master, tearoff=0)
popup.add_command(label="Quick start", command=show_manual)
popup.add_command(label="URL Generator", command=show_tester)
popup.add_separator()
popup.add_command(label="Quit", command=quit_app)

def do_popup(event):
    # display the popup menu
    try:
        popup.tk_popup(event.x_root, event.y_root, 0)
    finally:
        # make sure to release the grab (Tk 8.0a1 only)
        popup.grab_release()

canvas.bind("<ButtonRelease-2>", do_popup)
canvas.bind("<ButtonRelease-3>", do_popup)

master.overrideredirect(True)
master.geometry("+250+250")
master.lift()
master.wm_attributes("-topmost", True)
# master.wm_attributes("-disabled", True)
if WINDOWS:
    master.wm_attributes("-transparentcolor", "white")

mainloop()
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#=======================================================================
#
# cmac.py
# ------
# Simple, pure Python, CMAC implementation using the
# word based model of the AES cipher withsupport for 128 and
# 256 bit keys.
#
# Test vectors used in the tests are from the NIST specification:
# http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
#
#
#
# Author: Joachim Strömbergson
# Copyright (c) 2016, Secworks Sweden AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#=======================================================================

#-------------------------------------------------------------------
# Python module imports.
#-------------------------------------------------------------------
import sys

# Note this assumes that the aes implementation is either in the
# same dir or symlinked.
from aes import *

#-------------------------------------------------------------------
# Constants.
#-------------------------------------------------------------------
VERBOSE = True
R128 = (0, 0, 0, 0x00000087)
MAX128 = ((2**128) - 1)

#-------------------------------------------------------------------
# check_block()
#
# Check and report if a result block matches expected block.
#-------------------------------------------------------------------
def check_block(expected, result):
    if (expected[0] == result[0]) and  (expected[1] == result[1]) and\
         (expected[2] == result[2]) and  (expected[3] == result[3]):
        print("OK. Result matches expected.")
    else:
        print("ERROR. Result does not match expected.")
        print("Expected:")
        print_block(expected)
        print("Got:")
        print_block(result)
        print("")

#-------------------------------------------------------------------
# xor_words()
#-------------------------------------------------------------------
def xor_words(a, b):
    c = (a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3])
    if VERBOSE:
        print("XORing words in the following two 128 bit block gives the result:.")
        print_block(a)
        print_block(b)
        print_block(c)
    return c

#-------------------------------------------------------------------
# shift_words()
#-------------------------------------------------------------------
def shift_words(wl):
    w = ((wl[0] << 96) + (wl[1] << 64) + (wl[2] << 32) + wl[3]) & MAX128
    ws = w << 1 & MAX128
    return ((ws >> 96) & 0xffffffff, (ws >> 64) & 0xffffffff,
            (ws >> 32) & 0xffffffff, ws & 0xffffffff)

#-------------------------------------------------------------------
# pad_block()
#
# Pad a given block with the "1000...." paddning as given by the
# bitlen. Note that bitlen is assumed to be in the
# range [0..127]
#-------------------------------------------------------------------
def pad_block(block, bitlen):
    pass

#-------------------------------------------------------------------
# cmac_gen_subkeys()
#
# Generate subkeys K1 and K2.
#-------------------------------------------------------------------
def cmac_gen_subkeys(key):
    L = aes_encipher_block(key, (0, 0, 0, 0))

    Pre_K1 = shift_words(L)
    MSBL = (L[0] >> 31) & 0x01
    if MSBL:
        K1 = xor_words(Pre_K1, R128)
    else:
        K1 = Pre_K1

    Pre_K2 = shift_words(K1)
    MSBK1 = (K1[0] >> 31) & 0x01
    if MSBK1:
        K2 = xor_words(Pre_K2, R128)
    else:
        K2 = Pre_K2

    if VERBOSE:
        print("Internal data during sub key generation")
        print("---------------------------------------")
        print("L:")
        print_block(L)

        print("MSBL = 0x%01x" % MSBL)
        print("Pre_K1:")
        print_block(Pre_K1)
        print("K1:")
        print_block(K1)
        print("MSBK1 = 0x%01x" % MSBK1)
        print("Pre_K2:")
        print_block(Pre_K2)
        print("K2:")
        print_block(K2)
        print()

    return (K1, K2)

#-------------------------------------------------------------------
# cmac()
#
# Notation follows the description in SP 800-38B
#-------------------------------------------------------------------
def cmac(key, message):
    # Start by generating the subkeys
    (K1, K2) = cmac_gen_subkeys(key)

#-------------------------------------------------------------------
# test_cmac()
#
#-------------------------------------------------------------------
def test_cmac():
    nist_key128  = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    expect_1_128 = (0xbb1d6929, 0xe9593728, 0x7fa37d12, 0x9b756746)
    expect_2_128 = (0x070a16b4, 0x6b4d4144, 0xf79bdd9d, 0xd04a287c)
    expect_3_128 = (0x7d85449e, 0xa6ea19c8, 0x23a7bf78, 0x837dfade)
    expect_4_128 = (0x51f0bebf, 0x7e3b9d92, 0xfc497417, 0x79363cfe)

    nist_key256  = (0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
                    0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4)
    expect_1_256 = (0x028962f6, 0x1b7bf89e, 0xfc6b551f, 0x4667d983)
    expect_2_256 = (0x28a7023f, 0x452e8f82, 0xbd4bf28d, 0x8c37c35c)
    expect_3_256 = (0x156727dc, 0x0878944a, 0x023c1fe0, 0x3bad6d93)
    expect_4_256 = (0xe1992190, 0x549f6ed5, 0x696a2c05, 0x6c315410)

    message = ""
    cmac(nist_key128, message)

#-------------------------------------------------------------------
# test_xor()
#-------------------------------------------------------------------
def test_xor():
    print("*** Testing XOR words ***")
    a = (0x00000000, 0x55555555, 0xaaaaaaaa, 0xff00ff00)
    b = (0xdeadbeef, 0xaa00aa00, 0x55555555, 0xffffffff)
    c = xor_words(a , b)
    print_block(c)

#-------------------------------------------------------------------
# test_cmac_subkey_gen()
#
# Test the subkey functionality by itself. Testvectors are
# from the first examples in NISTs test case suite.
#-------------------------------------------------------------------
def test_cmac_subkey_gen():
    nist_key128 = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    nist_exp_k1 = (0xfbeed618, 0x35713366, 0x7c85e08f, 0x7236a8de)
    nist_exp_k2 = (0xf7ddac30, 0x6ae266cc, 0xf90bc11e, 0xe46d513b)

    (K1, K2) = cmac_gen_subkeys(nist_key128)

    print("*** Testing CMAC subkey generation ***")
    print("Checking key K1")
    check_block(K1, nist_exp_k1)
    print("Checking key K2")
    check_block(K2, nist_exp_k2)

#-------------------------------------------------------------------
# test_final()
#
# Test final tweak.
#-------------------------------------------------------------------
def test_final():
    key = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    final_block = (0x80000000, 0x00000000, 0x00000000, 0x00000000)
    k2 =          (0xf7ddac30, 0x6ae266cc, 0xf90bc11e, 0xe46d513b)
    tweaked_final = xor_words(final_block, k2)
    M = aes_encipher_block(key, tweaked_final)
    expected = (0xbb1d6929, 0xe9593728, 0x7fa37d12, 0x9b756746)
    check_block(expected, M)

#-------------------------------------------------------------------
# main()
#
# If executed tests the ChaCha class using known test vectors.
#-------------------------------------------------------------------
def main():
    print("Testing the CMAC-AES mode")
    print("=========================")
    print

    test_xor()
    test_cmac_subkey_gen()
    test_final()
#    test_cmac()

#-------------------------------------------------------------------
# __name__
# Python thingy which allows the file to be run standalone as
# well as parsed from within a Python interpreter.
#-------------------------------------------------------------------
if __name__=="__main__":
    # Run the main function.
    sys.exit(main())

#=======================================================================
# EOF aes_key_gen.py
#=======================================================================
<commit_msg>Minor nits.<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#=======================================================================
#
# cmac.py
# ------
# Simple, pure Python, CMAC implementation using the
# word based model of the AES cipher withsupport for 128 and
# 256 bit keys.
#
# Test vectors used in the tests are from the NIST specification:
# http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
#
#
#
# Author: Joachim Strömbergson
# Copyright (c) 2016, Secworks Sweden AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#=======================================================================

#-------------------------------------------------------------------
# Python module imports.
#-------------------------------------------------------------------
import sys

# Note this assumes that the aes implementation is either in the
# same dir or symlinked.
from aes import *

#-------------------------------------------------------------------
# Constants.
#-------------------------------------------------------------------
VERBOSE = True
R128 = (0, 0, 0, 0x00000087)
MAX128 = ((2**128) - 1)

#-------------------------------------------------------------------
# check_block()
#
# Check and report if a result block matches expected block.
#-------------------------------------------------------------------
def check_block(expected, result):
    if (expected[0] == result[0]) and  (expected[1] == result[1]) and\
         (expected[2] == result[2]) and  (expected[3] == result[3]):
        print("OK. Result matches expected.")
    else:
        print("ERROR. Result does not match expected.")
        print("Expected:")
        print_block(expected)
        print("Got:")
        print_block(result)
        print("")

#-------------------------------------------------------------------
# xor_words()
#-------------------------------------------------------------------
def xor_words(a, b):
    c = (a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3])
    if VERBOSE:
        print("XORing words in the following two 128 bit block gives the result:")
        print_block(a)
        print_block(b)
        print_block(c)
    return c

#-------------------------------------------------------------------
# shift_words()
#-------------------------------------------------------------------
def shift_words(wl):
    w = ((wl[0] << 96) + (wl[1] << 64) + (wl[2] << 32) + wl[3]) & MAX128
    ws = w << 1 & MAX128
    return ((ws >> 96) & 0xffffffff, (ws >> 64) & 0xffffffff,
            (ws >> 32) & 0xffffffff, ws & 0xffffffff)

#-------------------------------------------------------------------
# pad_block()
#
# Pad a given block with the "1000...." paddning as given by the
# bitlen. Note that bitlen is assumed to be in the
# range [0..127]
#-------------------------------------------------------------------
def pad_block(block, bitlen):
    pass

#-------------------------------------------------------------------
# cmac_gen_subkeys()
#
# Generate subkeys K1 and K2.
#-------------------------------------------------------------------
def cmac_gen_subkeys(key):
    L = aes_encipher_block(key, (0, 0, 0, 0))

    Pre_K1 = shift_words(L)
    MSBL = (L[0] >> 31) & 0x01
    if MSBL:
        K1 = xor_words(Pre_K1, R128)
    else:
        K1 = Pre_K1

    Pre_K2 = shift_words(K1)
    MSBK1 = (K1[0] >> 31) & 0x01
    if MSBK1:
        K2 = xor_words(Pre_K2, R128)
    else:
        K2 = Pre_K2

    if VERBOSE:
        print("Internal data during sub key generation")
        print("---------------------------------------")
        print("L:")
        print_block(L)

        print("MSBL = 0x%01x" % MSBL)
        print("Pre_K1:")
        print_block(Pre_K1)
        print("K1:")
        print_block(K1)
        print("MSBK1 = 0x%01x" % MSBK1)
        print("Pre_K2:")
        print_block(Pre_K2)
        print("K2:")
        print_block(K2)
        print()

    return (K1, K2)

#-------------------------------------------------------------------
# cmac()
#
# Notation follows the description in SP 800-38B
#-------------------------------------------------------------------
def cmac(key, message):
    # Start by generating the subkeys
    (K1, K2) = cmac_gen_subkeys(key)

#-------------------------------------------------------------------
# test_cmac()
#
#-------------------------------------------------------------------
def test_cmac():
    nist_key128  = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    expect_1_128 = (0xbb1d6929, 0xe9593728, 0x7fa37d12, 0x9b756746)
    expect_2_128 = (0x070a16b4, 0x6b4d4144, 0xf79bdd9d, 0xd04a287c)
    expect_3_128 = (0x7d85449e, 0xa6ea19c8, 0x23a7bf78, 0x837dfade)
    expect_4_128 = (0x51f0bebf, 0x7e3b9d92, 0xfc497417, 0x79363cfe)

    nist_key256  = (0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
                    0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4)
    expect_1_256 = (0x028962f6, 0x1b7bf89e, 0xfc6b551f, 0x4667d983)
    expect_2_256 = (0x28a7023f, 0x452e8f82, 0xbd4bf28d, 0x8c37c35c)
    expect_3_256 = (0x156727dc, 0x0878944a, 0x023c1fe0, 0x3bad6d93)
    expect_4_256 = (0xe1992190, 0x549f6ed5, 0x696a2c05, 0x6c315410)

    message = ""
    cmac(nist_key128, message)

#-------------------------------------------------------------------
# test_xor()
#-------------------------------------------------------------------
def test_xor():
    print("*** Testing XOR words ***")
    a = (0x00000000, 0x55555555, 0xaaaaaaaa, 0xff00ff00)
    b = (0xdeadbeef, 0xaa00aa00, 0x55555555, 0xffffffff)
    c = xor_words(a , b)
    print_block(c)

#-------------------------------------------------------------------
# test_cmac_subkey_gen()
#
# Test the subkey functionality by itself. Testvectors are
# from the first examples in NISTs test case suite.
#-------------------------------------------------------------------
def test_cmac_subkey_gen():
    nist_key128 = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    nist_exp_k1 = (0xfbeed618, 0x35713366, 0x7c85e08f, 0x7236a8de)
    nist_exp_k2 = (0xf7ddac30, 0x6ae266cc, 0xf90bc11e, 0xe46d513b)

    (K1, K2) = cmac_gen_subkeys(nist_key128)

    print("*** Testing CMAC subkey generation ***")
    print("Checking key K1")
    check_block(K1, nist_exp_k1)
    print("Checking key K2")
    check_block(K2, nist_exp_k2)

#-------------------------------------------------------------------
# test_final()
#
# Test final tweak.
#-------------------------------------------------------------------
def test_final():
    key = (0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c)
    final_block = (0x80000000, 0x00000000, 0x00000000, 0x00000000)
    k2 =          (0xf7ddac30, 0x6ae266cc, 0xf90bc11e, 0xe46d513b)
    tweaked_final = xor_words(final_block, k2)
    M = aes_encipher_block(key, tweaked_final)
    expected = (0xbb1d6929, 0xe9593728, 0x7fa37d12, 0x9b756746)
    check_block(expected, M)

#-------------------------------------------------------------------
# main()
#
# If executed tests the ChaCha class using known test vectors.
#-------------------------------------------------------------------
def main():
    print("Testing the CMAC-AES mode")
    print("=========================")
    print

    test_xor()
    test_cmac_subkey_gen()
    test_final()
#    test_cmac()

#-------------------------------------------------------------------
# __name__
# Python thingy which allows the file to be run standalone as
# well as parsed from within a Python interpreter.
#-------------------------------------------------------------------
if __name__=="__main__":
    # Run the main function.
    sys.exit(main())

#=======================================================================
# EOF aes_key_gen.py
#=======================================================================
<|endoftext|>


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

#
# HMM model implementation(old) of HMM Aligner
# Simon Fraser University
# NLP Lab
#
# This is the implementation of HMM word aligner, it requires IBM1Old in order
# to function properly
#
import optparse
import sys
import os
import logging
import time
import numpy as np
from math import log
from collections import defaultdict
from copy import deepcopy

from loggers import logging
from models.IBM1 import AlignmentModel as AlignerIBM1
from models.modelBase import AlignmentModelBase as Base
from evaluators.evaluator import evaluate
__version__ = "0.4a"

# This is a private module for transmitting test results. Please ignore.
class DummyTask():
    def __init__(self, taskName="Untitled", serial="XXXX"):
        return

    def progress(self, msg):
        return

try:
    from progress import Task
except all:
    Task = DummyTask

class AlignmentModel(Base):
    def __init__(self):
        self.logger = logging.getLogger('HMM')
        self.p0H = 0.3
        self.nullEmissionProb = 0.000005
        self.smoothFactor = 0.1
        self.a = None
        self.pi = None
        self.task = None
        self.evaluate = evaluate
        self.modelComponents = ["t", "pi", "a"]
        Base.__init__(self)
        return

    def initialiseModel(self, Len):
        doubleLen = 2 * Len
        # a: transition parameter
        # pi: initial parameter
        tmp = 1.0 / Len
        for z in range(doubleLen + 1):
            for y in range(doubleLen + 1):
                for x in range(Len + 1):
                    self.a[z][y][x] = tmp
        tmp = 1.0 / doubleLen
        for x in range(doubleLen + 1):
            self.pi[x] = tmp
        return

    def forwardBackward(self, f, e, small_t):
        alphaScale = [0.0 for x in range(len(f) + 1)]
        alpha = [[0.0 for x in range(len(f) + 1)] for y in range(len(e) + 1)]
        alphaSum = 0

        for i in range(1, len(e) + 1):
            alpha[i][1] = self.pi[i] * small_t[0][i - 1]
            alphaSum += alpha[i][1]

        alphaScale[1] = 1 / alphaSum
        for i in range(1, len(e) + 1):
            alpha[i][1] *= alphaScale[1]

        for t in range(2, len(f) + 1):
            alphaSum = 0
            for j in range(1, len(e) + 1):
                total = 0
                for i in range(1, len(e) + 1):
                    total += alpha[i][t - 1] * self.a[i][j][len(e)]
                alpha[j][t] = small_t[t - 1][j - 1] * total
                alphaSum += alpha[j][t]

            alphaScale[t] = 1.0 / alphaSum
            for i in range(1, len(e) + 1):
                alpha[i][t] = alphaScale[t] * alpha[i][t]

        beta = [[0.0 for x in range(len(f) + 1)] for y in range(len(e) + 1)]
        for i in range(1, len(e) + 1):
            beta[i][len(f)] = alphaScale[len(f)]
        for t in range(len(f) - 1, 0, -1):
            for i in range(1, len(e) + 1):
                total = 0
                for j in range(1, len(e) + 1):
                    total += (beta[j][t + 1] *
                              self.a[i][j][len(e)] *
                              small_t[t][j - 1])
                beta[i][t] = alphaScale[t] * total
        return alpha, alphaScale, beta

    def maxTargetSentenceLength(self, dataset):
        maxLength = 0
        targetLengthSet = defaultdict(int)
        for (f, e, alignment) in dataset:
            tempLength = len(e)
            if tempLength > maxLength:
                maxLength = tempLength
            targetLengthSet[tempLength] += 1
        return (maxLength, targetLengthSet)

    def mapBitextToInt(self, sd_count):
        index = defaultdict(int)
        biword = defaultdict(tuple)
        i = 0
        for key in sd_count:
            index[key] = i
            biword[i] = key
            i += 1
        return (index, biword)

    def baumWelch(self, dataset, iterations=5):
        if not self.task:
            self.task = Task("Aligner", "HMMBaumWelchOI" + str(iterations))
        N, self.targetLengthSet = self.maxTargetSentenceLength(dataset)

        self.logger.info("N " + str(N))
        indexMap, biword = self.mapBitextToInt(self.t)

        sd_size = len(indexMap)
        totalGammaDeltaOAO_t_i = None
        totalGammaDeltaOAO_t_overall_states_over_dest = None

        twoN = 2 * N

        self.a = [[[0.0 for x in range(N + 1)]
                  for y in range(twoN + 1)]
                  for z in range(twoN + 1)]
        self.pi = [0.0 for x in range(twoN + 1)]

        for iteration in range(iterations):
            self.logger.info("HMMBWTypeI Iteration " + str(iteration))

            logLikelihood = 0

            totalGammaDeltaOAO_t_i = \
                [0.0 for x in range(sd_size)]
            totalGammaDeltaOAO_t_overall_states_over_dest =\
                defaultdict(float)
            totalGamma1OAO = [0.0 for x in range(N + 1)]
            totalC_j_Minus_iOAO = [[[0.0 for x in range(N + 1)]
                                    for y in range(N + 1)]
                                   for z in range(N + 1)]
            totalC_l_Minus_iOAO = [[0.0 for x in range(N + 1)]
                                   for y in range(N + 1)]

            gamma = \
                [[0.0 for x in range(N * 2 + 1)] for y in range(N + 1)]
            small_t = \
                [[0.0 for x in range(N * 2 + 1)] for y in range(N * 2 + 1)]

            start0_time = time.time()

            counter = 0
            for (f, e, alignment) in dataset:
                self.task.progress("BaumWelch iter %d, %d of %d" %
                                   (iteration, counter, len(dataset),))
                counter += 1
                c = defaultdict(float)
                if iteration == 0:
                    self.initialiseModel(len(e))
                for i in range(len(f)):
                    for j in range(len(e)):
                        small_t[i][j] = self.t[(f[i][0], e[j][0])]
                alpha, alphaScaled, beta = self.forwardBackward(f, e, small_t)

                # Setting gamma
                for t in range(1, len(f) + 1):
                    logLikelihood += -1 * log(alphaScaled[t])
                    for i in range(1, len(e) + 1):
                        gamma[i][t] =\
                            (alpha[i][t] * beta[i][t]) / alphaScaled[t]
                        totalGammaDeltaOAO_t_i[
                            indexMap[(f[t - 1][0], e[i - 1][0])]] +=\
                            gamma[i][t]
                logLikelihood += -1 * log(alphaScaled[len(f)])

                for t in range(1, len(f)):
                    for i in range(1, len(e) + 1):
                        for j in range(1, len(e) + 1):
                            c[j - i] += (alpha[i][t] *
                                         self.a[i][j][len(e)] *
                                         small_t[t][j - 1] *
                                         beta[j][t + 1])

                for i in range(1, len(e) + 1):
                    for j in range(1, len(e) + 1):
                        totalC_j_Minus_iOAO[i][j][len(e)] += c[j - i]
                        totalC_l_Minus_iOAO[i][len(e)] += c[j - i]
                    totalGamma1OAO[i] += gamma[i][1]
            # end of loop over dataset

            start_time = time.time()

            self.logger.info("likelihood " + str(logLikelihood))
            N = len(totalGamma1OAO) - 1

            for k in range(sd_size):
                f, e = biword[k]

                totalGammaDeltaOAO_t_overall_states_over_dest[e] +=\
                    totalGammaDeltaOAO_t_i[k]

            end_time = time.time()

            self.logger.info("time spent in the end of E-step: " +
                             str(end_time - start_time))
            self.logger.info("time spent in E-step: " +
                             str(end_time - start0_time))

            # M-Step
            del self.a
            del self.pi
            del self.t
            self.a = [[[0.0 for x in range(N + 1)]
                      for y in range(twoN + 1)]
                      for z in range(twoN + 1)]
            self.pi = [0.0 for x in range(twoN + 1)]
            self.t = defaultdict(float)

            self.logger.info("set " + str(self.targetLengthSet.keys()))
            for I in self.targetLengthSet:
                for i in range(1, I + 1):
                    for j in range(1, I + 1):
                        self.a[i][j][I] = \
                            totalC_j_Minus_iOAO[i][j][I] /\
                            (totalC_l_Minus_iOAO[i][I] + 1e-37)

            for i in range(1, N + 1):
                self.pi[i] = totalGamma1OAO[i] * (1.0 / len(dataset))

            for k in range(sd_size):
                f, e = biword[k]
                self.t[(f, e)] = totalGammaDeltaOAO_t_i[k] / \
                    (totalGammaDeltaOAO_t_overall_states_over_dest[e] + 1e-37)

            end2_time = time.time()
            self.logger.info("time spent in M-step: " +
                             str(end2_time - end_time))
            self.logger.info("iteration " + str(iteration) + " completed")
        return

    def multiplyOneMinusP0H(self):
        for I in self.targetLengthSet:
            for i in range(1, I + 1):
                for j in range(1, I + 1):
                    self.a[i][j][I] *= 1 - self.p0H
        for I in self.targetLengthSet:
            for i in range(1, I + 1):
                for j in range(1, I + 1):
                    self.a[i][i + I][I] = self.p0H
                    self.a[i + I][i + I][I] = self.p0H
                    self.a[i + I][j][I] = self.a[i][j][I]
        return

    def tProbability(self, f, e):
        v = 163303
        if (f[0], e[0]) in self.t:
            return self.t[(f[0], e[0])]
        if e[0] == "null":
            return self.nullEmissionProb
        return 1.0 / v

    def aProbability(self, prev_j, i, targetLength):
        # p(i|i',I) is smoothed to uniform distribution for now -->
        # p(i|i',I) = 1/I
        # we can make it interpolation form like what Och and Ney did
        if targetLength in self.targetLengthSet:
            return self.a[prev_j + 1][i + 1][targetLength] + 1e-64
        return 1.0 / targetLength

    def logViterbi(self, f, e):
        '''
        This function returns alignment of given sentence in two languages
        @param f: source sentence
        @param e: target sentence
        @return: list of alignment
        '''
        e = deepcopy(e)
        eLen = len(e)
        for i in range(eLen):
            e.append(("null", "null"))
        score = np.zeros((len(f), len(e)))
        prev_j = np.zeros((len(f), len(e)))

        for i in range(len(f)):
            for j in range(len(e)):
                score[i][j] = log(self.tProbability(f[i], e[j]))
                if i == 0:
                    if j + 1 < len(self.pi) and self.pi[j + 1] != 0:
                        score[i][j] += log(self.pi[j + 1])
                    else:
                        score[i][j] = - sys.maxint - 1
                else:
                    # Find the best alignment for f[i-1]
                    maxScore = -sys.maxint - 1
                    bestPrev_j = -sys.maxint - 1
                    for jPrev in range(len(e)):
                        temp = score[i - 1][jPrev] +\
                            log(self.aProbability(jPrev, j, eLen))
                        if temp > maxScore:
                            maxScore = temp
                            bestPrev_j = jPrev

                    score[i][j] += maxScore
                    prev_j[i][j] = bestPrev_j

        maxScore = -sys.maxint - 1
        best_j = 0
        for j in range(len(e)):
            if score[len(f) - 1][j] > maxScore:
                maxScore = score[len(f) - 1][j]
                best_j = j

        trace = [best_j + 1, ]
        i = len(f) - 1
        j = best_j

        while (i > 0):
            j = int(prev_j[i][j])
            trace = [j + 1] + trace
            i = i - 1
        return trace

    def decode(self, dataset):
        self.logger.info("Start decoding")
        self.logger.info("Testing size: " + str(len(dataset)))
        result = []

        for (f, e, alignment) in dataset:
            sentenceAlignment = []
            N = len(e)
            bestAlignment = self.logViterbi(f, e)

            for i in range(len(bestAlignment)):
                if bestAlignment[i] <= len(e):
                    sentenceAlignment.append((i + 1, bestAlignment[i]))

            result.append(sentenceAlignment)
        self.logger.info("Decoding Completed")
        return result

    def train(self, dataset, iterations):
        self.task = Task("Aligner", "HMMOI" + str(iterations))
        self.task.progress("Training IBM model 1")
        self.logger.info("Training IBM model 1")
        alignerIBM1 = AlignerIBM1()
        alignerIBM1.train(dataset, iterations)
        self.t = alignerIBM1.t
        self.task.progress("IBM model Trained")
        self.logger.info("IBM model Trained")
        self.baumWelch(dataset, iterations=iterations)
        self.task.progress("finalising")
        self.multiplyOneMinusP0H()
        self.task = None
        return
<commit_msg>Cleaning up<commit_after># -*- coding: utf-8 -*-

#
# HMM model implementation(old) of HMM Aligner
# Simon Fraser University
# NLP Lab
#
# This is the implementation of HMM word aligner, it requires IBM1Old in order
# to function properly
#
import optparse
import sys
import os
import logging
import time
import numpy as np
from math import log
from collections import defaultdict
from copy import deepcopy

from loggers import logging
from models.IBM1 import AlignmentModel as AlignerIBM1
from models.modelBase import AlignmentModelBase as Base
from evaluators.evaluator import evaluate
__version__ = "0.4a"

# This is a private module for transmitting test results. Please ignore.
class DummyTask():
    def __init__(self, taskName="Untitled", serial="XXXX"):
        return

    def progress(self, msg):
        return

try:
    from progress import Task
except all:
    Task = DummyTask

class AlignmentModel(Base):
    def __init__(self):
        self.logger = logging.getLogger('HMM')
        self.p0H = 0.3
        self.nullEmissionProb = 0.000005
        self.smoothFactor = 0.1
        self.a = None
        self.pi = None
        self.task = None
        self.evaluate = evaluate
        self.modelComponents = ["t", "pi", "a", "eLengthSet"]
        Base.__init__(self)
        return

    def initialiseModel(self, Len):
        doubleLen = 2 * Len
        # a: transition parameter
        # pi: initial parameter
        tmp = 1.0 / Len
        for z in range(Len):
            for y in range(Len):
                for x in range(Len + 1):
                    self.a[x][z][y] = tmp
        tmp = 1.0 / doubleLen
        for x in range(Len):
            self.pi[x] = tmp
        return

    def forwardBackward(self, f, e, tSmall, a):
        alpha = [[0.0 for x in range(len(e))] for y in range(len(f))]
        alphaScale = [0.0 for x in range(len(f))]
        alphaSum = 0

        for j in range(len(e)):
            alpha[0][j] = self.pi[j] * tSmall[0][j]
            alphaSum += alpha[0][j]

        alphaScale[0] = 1 / alphaSum
        for j in range(len(e)):
            alpha[0][j] *= alphaScale[0]

        for i in range(1, len(f)):
            alphaSum = 0
            for j in range(len(e)):
                total = 0
                for prev_j in range(len(e)):
                    total += alpha[i - 1][prev_j] * a[prev_j][j]
                alpha[i][j] = tSmall[i][j] * total
                alphaSum += alpha[i][j]

            alphaScale[i] = 1.0 / alphaSum
            for j in range(len(e)):
                alpha[i][j] = alphaScale[i] * alpha[i][j]

        beta = [[0.0 for x in range(len(e))] for y in range(len(f))]
        for j in range(len(e)):
            beta[len(f) - 1][j] = alphaScale[len(f) - 1]

        for i in range(len(f) - 2, -1, -1):
            for j in range(len(e)):
                total = 0
                for next_j in range(len(e)):
                    total += (beta[i + 1][next_j] * a[j][next_j] *
                              tSmall[i + 1][next_j])
                beta[i][j] = alphaScale[i] * total
        return alpha, alphaScale, beta

    def maxTargetSentenceLength(self, dataset):
        maxLength = 0
        eLengthSet = defaultdict(int)
        for (f, e, alignment) in dataset:
            tempLength = len(e)
            if tempLength > maxLength:
                maxLength = tempLength
            eLengthSet[tempLength] += 1
        return (maxLength, eLengthSet)

    def baumWelch(self, dataset, iterations=5):
        if not self.task:
            self.task = Task("Aligner", "HMMBaumWelchOI" + str(iterations))
        self.logger.info("Starting Training Process")
        self.logger.info("Training size: " + str(len(dataset)))
        startTime = time.time()

        maxE, self.eLengthSet = self.maxTargetSentenceLength(dataset)

        self.logger.info("Maximum Target sentence length: " + str(maxE))

        self.a = [[[0.0 for x in range(maxE * 2)] for y in range(maxE * 2)]
                  for z in range(maxE + 1)]
        self.pi = [0.0 for x in range(maxE * 2)]

        for iteration in range(iterations):
            self.logger.info("BaumWelch Iteration " + str(iteration))

            logLikelihood = 0

            gamma = [[0.0 for x in range(maxE)] for y in range(maxE * 2)]
            gammaBiword = defaultdict(float)
            gammaSum_0 = [0.0 for x in range(maxE)]

            epsilon = [[[0.0 for x in range(maxE)] for y in range(maxE)]
                       for z in range(maxE + 1)]

            counter = 0
            for (f, e, alignment) in dataset:
                self.task.progress("BaumWelch iter %d, %d of %d" %
                                   (iteration, counter, len(dataset),))
                counter += 1
                if iteration == 0:
                    self.initialiseModel(len(e))

                fLen, eLen = len(f), len(e)
                a = self.a[eLen]
                tSmall = [[self.t[(f[i][0], e[j][0])] for j in range(eLen)]
                          for i in range(fLen)]

                alpha, alphaScale, beta = self.forwardBackward(f, e, tSmall, a)

                # Setting gamma
                for i in range(fLen):
                    logLikelihood -= log(alphaScale[i])
                    for j in range(eLen):
                        gamma[i][j] = alpha[i][j] * beta[i][j] / alphaScale[i]
                        gammaBiword[(f[i][0], e[j][0])] += gamma[i][j]
                for j in range(eLen):
                    gammaSum_0[j] += gamma[0][j]
                logLikelihood -= log(alphaScale[fLen - 1])

                c = [0.0 for i in range(eLen * 2)]
                for i in range(1, fLen):
                    for prev_j in range(eLen):
                        for j in range(eLen):
                            c[eLen - 1 + j - prev_j] += (
                                alpha[i - 1][prev_j] * beta[i][j] *
                                a[prev_j][j] * tSmall[i][j])

                for prev_j in range(eLen):
                    for j in range(eLen):
                        epsilon[eLen][prev_j][j] += c[eLen - 1 + j - prev_j]
            # end of loop over dataset

            self.logger.info("likelihood " + str(logLikelihood))
            # M-Step
            self.t.clear()
            for Len in self.eLengthSet:
                for prev_j in range(Len):
                    epsilonSum = 0.0
                    for j in range(Len):
                        epsilonSum += epsilon[Len][prev_j][j]
                    for j in range(Len):
                        self.a[Len][prev_j][j] = epsilon[Len][prev_j][j] /\
                            (epsilonSum + 1e-37)

            for i in range(maxE):
                self.pi[i] = gammaSum_0[i] * (1.0 / len(dataset))

            gammaEWord = defaultdict(float)
            for f, e in gammaBiword:
                gammaEWord[e] += gammaBiword[(f, e)]
            for f, e in gammaBiword:
                self.t[(f, e)] = gammaBiword[(f, e)] / (gammaEWord[e] + 1e-37)

        endTime = time.time()
        self.logger.info("Training Complete, total time(seconds): %f" %
                         (endTime - startTime,))
        return

    def multiplyOneMinusP0H(self):
        for targetLen in self.eLengthSet:
            a = self.a[targetLen]
            for prev_j in range(targetLen):
                for j in range(targetLen):
                    a[prev_j][j] *= 1 - self.p0H
        for targetLen in self.eLengthSet:
            a = self.a[targetLen]
            for prev_j in range(targetLen):
                for j in range(targetLen):
                    a[prev_j][prev_j + targetLen] = self.p0H
                    a[prev_j + targetLen][prev_j + targetLen] = self.p0H
                    a[prev_j + targetLen][j] = a[prev_j][j]
        return

    def tProbability(self, f, e):
        v = 163303
        if (f[0], e[0]) in self.t:
            return self.t[(f[0], e[0])]
        if e[0] == "null":
            return self.nullEmissionProb
        return 1.0 / v

    def aProbability(self, prev_j, j, targetLength):
        if targetLength in self.eLengthSet:
            return self.a[targetLength][prev_j][j]
        return 1.0 / targetLength

    def logViterbi(self, f, e):
        e = deepcopy(e)
        fLen, eLen = len(f), len(e)
        for i in range(eLen):
            e.append(("null", "null"))
        score = np.zeros((fLen, eLen * 2))
        prev_j = np.zeros((fLen, eLen * 2))

        for i in range(fLen):
            for j in range(eLen * 2):
                score[i][j] = log(self.tProbability(f[i], e[j]))
                if i == 0:
                    if j < len(self.pi) and self.pi[j] != 0:
                        score[i][j] += log(self.pi[j])
                    else:
                        score[i][j] = - sys.maxint - 1
                else:
                    # Find the best alignment for f[i-1]
                    maxScore = -sys.maxint - 1
                    bestPrev_j = -sys.maxint - 1
                    for jPrev in range(eLen * 2):
                        aPr = self.aProbability(jPrev, j, eLen)
                        if aPr == 0:
                            continue
                        temp = score[i - 1][jPrev] + log(aPr)
                        if temp > maxScore:
                            maxScore = temp
                            bestPrev_j = jPrev

                    score[i][j] += maxScore
                    prev_j[i][j] = bestPrev_j

        maxScore = -sys.maxint - 1
        best_j = 0
        for j in range(eLen * 2):
            if score[fLen - 1][j] > maxScore:
                maxScore = score[fLen - 1][j]
                best_j = j

        trace = [best_j + 1, ]
        i = fLen - 1
        j = best_j

        while (i > 0):
            j = int(prev_j[i][j])
            trace = [j + 1] + trace
            i = i - 1
        return trace

    def decode(self, dataset):
        self.logger.info("Start decoding")
        self.logger.info("Testing size: " + str(len(dataset)))
        result = []

        for (f, e, alignment) in dataset:
            sentenceAlignment = []
            bestAlignment = self.logViterbi(f, e)

            for i in range(len(bestAlignment)):
                if bestAlignment[i] <= len(e):
                    sentenceAlignment.append((i + 1, bestAlignment[i]))

            result.append(sentenceAlignment)
        self.logger.info("Decoding Completed")
        return result

    def train(self, dataset, iterations):
        self.task = Task("Aligner", "HMMOI" + str(iterations))
        self.task.progress("Training IBM model 1")
        self.logger.info("Training IBM model 1")
        alignerIBM1 = AlignerIBM1()
        alignerIBM1.train(dataset, iterations)
        self.t = alignerIBM1.t
        self.task.progress("IBM model Trained")
        self.logger.info("IBM model Trained")
        self.baumWelch(dataset, iterations=iterations)
        self.task.progress("finalising")
        self.multiplyOneMinusP0H()
        self.task = None
        return
<|endoftext|>


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

__author__ = 'Daniel Zhang (張道博)'
__copyright__ = 'Copyright (c) 2013, University of Hawaii Smart Energy Project'
__license__ = 'https://raw.github' \
              '.com/Hawaii-Smart-Energy-Project/Maui-Smart-Grid/master/BSD' \
              '-LICENSE.txt'

import sys
import logging
from io import StringIO

class MSGLogger(object):
    """
    This class provides logging functionality.
    """

    def __init__(self, caller, level = 'info'):
        """
        Constructor.

        :params caller: Calling class.
        :params level: An enumerated type detailing the level of the logging.

        @todo Provide enumeration type.
        """

        #print "Initializing logger for %s." % caller

        self.logger = logging.getLogger(caller)

        self.ioStream = StringIO()

        self.streamHandlerStdErr = logging.StreamHandler(sys.stderr)
        self.streamHandlerString = logging.StreamHandler(self.ioStream)
        self.streamHandlerStdErr.setLevel(logging.DEBUG)
        self.streamHandlerString.setLevel(logging.DEBUG)

        formatterStdErr = logging.Formatter(
            u'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        formatterString = logging.Formatter(
            u'string: %(asctime)s - %(name)s - %(levelname)s - %(message)s')

        self.streamHandlerStdErr.setFormatter(formatterStdErr)
        self.streamHandlerString.setFormatter(formatterString)

        self.loggerLevel = None

        level = level.lower()
        if level == 'info':
            self.loggerLevel = logging.INFO
        elif level == 'error':
            self.loggerLevel = logging.ERROR
        elif level == 'silent':
            self.loggerLevel = None
        elif level == 'debug':
            self.loggerLevel = logging.DEBUG
        else:
            self.loggerLevel = None

        # Messages equal to and above the logging level will be logged.
        # @todo Test that logging level is used.
        self.logger.setLevel(self.loggerLevel)

        self.recordingBuffer = []
        self.recording = ''
        self.shouldRecord = False
        self.logCounter = 0

    def logAndWrite(self, message):
        """
        With a given string, write it to stderr and return its value for
        appending to a running log.

        Nothing is added to the message. Therefore, if linefeeds are desired
        they should be included explicitly.

        :param message: A string message to be logged.
        :returns: The message.
        """

        sys.stderr.write(message)
        return message

    def log(self, message, level = None):
        """
        Write a log message.

        Logging levels are

        * info
        * debug
        * error
        * silent

        :params message: A message to be logged.
        :params level: (optional) Logging level.
        """

        self.logger.addHandler(self.streamHandlerStdErr)
        self.logger.addHandler(self.streamHandlerString)

        if not level:
            loggerLevel = self.loggerLevel

        else:
            loggerLevel = None
            if level == 'info':
                loggerLevel = logging.INFO
            elif level == 'debug':
                loggerLevel = logging.DEBUG
            elif level == 'error':
                loggerLevel = logging.ERROR
            elif level == 'silent':
                loggerLevel = None
            else:
                loggerLevel = self.loggerLevel

        if loggerLevel != None:

            self.logger.log(loggerLevel, message)

            if self.shouldRecord:
                self.recordingBuffer.append('%s' % (self.ioStream.getvalue()))
                self.recording = self.recordingBuffer[-1]

            for handler in self.logger.handlers:
                # The flushes here apparently don't have any effect on the
                # logger.
                handler.flush()
                self.ioStream.flush()
                self.logger.removeHandler(handler)

            self.logCounter += 1

    def startRecording(self):
        self.shouldRecord = True

    def endRecording(self):
        self.shouldRecord = False
<commit_msg>removing prefix<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'Daniel Zhang (張道博)'
__copyright__ = 'Copyright (c) 2013, University of Hawaii Smart Energy Project'
__license__ = 'https://raw.github' \
              '.com/Hawaii-Smart-Energy-Project/Maui-Smart-Grid/master/BSD' \
              '-LICENSE.txt'

import sys
import logging
from io import StringIO

class MSGLogger(object):
    """
    This class provides logging functionality.
    """

    def __init__(self, caller, level = 'info'):
        """
        Constructor.

        :params caller: Calling class.
        :params level: An enumerated type detailing the level of the logging.

        @todo Provide enumeration type.
        """

        #print "Initializing logger for %s." % caller

        self.logger = logging.getLogger(caller)

        self.ioStream = StringIO()

        self.streamHandlerStdErr = logging.StreamHandler(sys.stderr)
        self.streamHandlerString = logging.StreamHandler(self.ioStream)
        self.streamHandlerStdErr.setLevel(logging.DEBUG)
        self.streamHandlerString.setLevel(logging.DEBUG)

        formatterStdErr = logging.Formatter(
            u'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        formatterString = logging.Formatter(
            u'%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        self.streamHandlerStdErr.setFormatter(formatterStdErr)
        self.streamHandlerString.setFormatter(formatterString)

        self.loggerLevel = None

        level = level.lower()
        if level == 'info':
            self.loggerLevel = logging.INFO
        elif level == 'error':
            self.loggerLevel = logging.ERROR
        elif level == 'silent':
            self.loggerLevel = None
        elif level == 'debug':
            self.loggerLevel = logging.DEBUG
        else:
            self.loggerLevel = None

        # Messages equal to and above the logging level will be logged.
        # @todo Test that logging level is used.
        self.logger.setLevel(self.loggerLevel)

        self.recordingBuffer = []
        self.recording = ''
        self.shouldRecord = False
        self.logCounter = 0

    def logAndWrite(self, message):
        """
        With a given string, write it to stderr and return its value for
        appending to a running log.

        Nothing is added to the message. Therefore, if linefeeds are desired
        they should be included explicitly.

        :param message: A string message to be logged.
        :returns: The message.
        """

        sys.stderr.write(message)
        return message

    def log(self, message, level = None):
        """
        Write a log message.

        Logging levels are

        * info
        * debug
        * error
        * silent

        :params message: A message to be logged.
        :params level: (optional) Logging level.
        """

        self.logger.addHandler(self.streamHandlerStdErr)
        self.logger.addHandler(self.streamHandlerString)

        if not level:
            loggerLevel = self.loggerLevel

        else:
            loggerLevel = None
            if level == 'info':
                loggerLevel = logging.INFO
            elif level == 'debug':
                loggerLevel = logging.DEBUG
            elif level == 'error':
                loggerLevel = logging.ERROR
            elif level == 'silent':
                loggerLevel = None
            else:
                loggerLevel = self.loggerLevel

        if loggerLevel != None:

            self.logger.log(loggerLevel, message)

            if self.shouldRecord:
                self.recordingBuffer.append('%s' % (self.ioStream.getvalue()))
                self.recording = self.recordingBuffer[-1]

            for handler in self.logger.handlers:
                # The flushes here apparently don't have any effect on the
                # logger.
                handler.flush()
                self.ioStream.flush()
                self.logger.removeHandler(handler)

            self.logCounter += 1

    def startRecording(self):
        self.shouldRecord = True

    def endRecording(self):
        self.shouldRecord = False
<|endoftext|>