<commit_before>
import glob
import json
import NetworkManager
import os
import pyjavaproperties
import re
import sys
import threading
import time
import urllib2

import pprint

try:
    from gi.repository import Gtk
except: # Can't use ImportError, as gi.repository isn't quite that nice...
    import gtk as Gtk

class JsonInfo():

    def __init__(self, baseurl='http://localhost:9090'):
        self.baseurl = baseurl
        self.jsondecoder = json.JSONDecoder()

    def dump(self, data='/all'):
        try:
            return urllib2.urlopen(self.baseurl + data).read()
        except urllib2.URLError:
            return None

    def dict(self, data='/all'):
        dump = self.dump(data)
        if dump:
            return self.jsondecoder.decode(dump)

class MeshStatus():

    def __init__(self, toplevel):
        self.toplevel = toplevel
        self.jsoninfo = JsonInfo()
        self.imagedir = commotion_mesh_panel_png_dir

    def _set_icon(self, cell, filename):
        fullfilename = os.path.join(self.imagedir, filename)
        cell.set_property("pixbuf", Gtk.gdk.pixbuf_new_from_file(fullfilename))

    def _internet_icon(self, column, cell, model, iter):
        if model[iter][3]:
            self._set_icon(cell, 'default_route.png')

    def _hna_icon(self, column, cell, model, iter):
        if model[iter][4]:
            self._set_icon(cell, 'other_route.png')

    def show(self):
        window = Gtk.Window()
        window.set_title('Mesh Status (Links and HNA)')
        vbox = Gtk.VBox(homogeneous=False, spacing=5)
        window.add(vbox)

        links_hna = self.jsoninfo.dict('/links/hna')
        # liststore data:  IP, LQ, NLQ, have_internet, have_HNA
        liststore = Gtk.ListStore(str, int, int, bool, bool)
        if links_hna:
            hna = []
            internet = []
            for i in links_hna['hna']:
                if i['destination'] == '0.0.0.0':
                    internet.append(i['gateway'])
                else:
                    hna.append(i['gateway'])
            for link in links_hna['links']:
                ip = link['remoteIP']
                lqPercent = int(link['linkQuality']*100)
                nlqPercent = int(link['neighborLinkQuality']*100)
                cell = [ ip, lqPercent, nlqPercent ]
                if ip in internet:
                    cell.append(True)
                else:
                    cell.append(False)
                if ip in hna:
                    cell.append(True)
                else:
                    cell.append(False)
                liststore.append(cell)

        treeview = Gtk.TreeView(model=liststore)
        selection = treeview.get_selection()
        selection.set_mode(Gtk.SELECTION_NONE)
        vbox.pack_start(treeview, True, True, 3)

        column = Gtk.TreeViewColumn("Link IP Address")
        column.set_alignment(0.5)
        treeview.append_column(column)
        cell = Gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 0)

        column = Gtk.TreeViewColumn("LQ")
        column.set_alignment(0.5)
        column.set_resizable(True)
        treeview.append_column(column)
        cell = Gtk.CellRendererProgress()
        column.pack_start(cell, True)
        column.add_attribute(cell, "value", 1)

        column = Gtk.TreeViewColumn("NLQ")
        column.set_alignment(0.5)
        column.set_resizable(True)
        treeview.append_column(column)
        cell = Gtk.CellRendererProgress()
        column.pack_start(cell, True)
        column.add_attribute(cell, "value", 2)

        column = Gtk.TreeViewColumn("HNA?")
        column.set_alignment(0.5)
        column.set_resizable(False)
        treeview.append_column(column)
        cell = Gtk.CellRendererPixbuf()
        column.pack_start(cell, False)
        column.set_cell_data_func(cell, self._hna_icon)

        column = Gtk.TreeViewColumn("Internet?")
        column.set_alignment(0.5)
        column.set_resizable(False)
        treeview.append_column(column)
        cell = Gtk.CellRendererPixbuf()
        column.pack_start(cell, False)
        column.set_cell_data_func(cell, self._internet_icon)

        window.show_all()

def get_visible_adhocs():
    actives = []
    nets = []
    strengths = dict()
    for ac in NetworkManager.NetworkManager.ActiveConnections:
        for d in ac.Devices:
            if d.Managed and d.DeviceType == NetworkManager.NM_DEVICE_TYPE_WIFI:
                wireless = d.SpecificDevice()
                aap = wireless.ActiveAccessPoint
                if aap.Mode == NetworkManager.NM_802_11_MODE_ADHOC:
                    channel = (aap.Frequency - 2407) / 5
                    actives.append(tuple([aap.Ssid, aap.HwAddress, channel]))
                for ap in wireless.GetAccessPoints():
                    if ap.Mode == NetworkManager.NM_802_11_MODE_ADHOC:
                        channel = (aap.Frequency - 2407) / 5
                        nets.append(tuple([ap.Ssid, ap.HwAddress, channel]))
                        strengths[ap.Ssid] = ap.Strength
    return [tuple(actives), tuple(nets), strengths]

def get_profiles():
    '''get all the available mesh profiles and return as a list of tuples'''
    profiles = []
    for f in glob.glob('/etc/nm-dispatcher-olsrd/*.profile'):
        p = pyjavaproperties.Properties()
        p.load(open(f))
        bssid = p['bssid'].upper()
        channel = int(p['channel'])
        profiles.append(tuple([p['ssid'], bssid, channel]))
    return tuple(profiles)

def add_menu_item(menu, name, function, imagefile=None):
    item = Gtk.ImageMenuItem(name)
    if imagefile:
        icon = Gtk.Image()
        icon.set_from_file(imagefile)
        item.set_image(icon)
    item.show()
    item.connect( "activate", function)
    menu.add(item)

def add_menu_label(menu, name):
    item = Gtk.ImageMenuItem(name)
    item.set_sensitive(False)
    item.show()
    menu.add(item)

def add_visible_profile_menu_item(menu, name, function, strength):
    if strength > 98:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-100.png')
    elif strength >= 75:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-75.png')
    elif strength >= 50:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-50.png')
    elif strength >= 25:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-25.png')
    else:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-00.png')

def choose_profile(*arguments):
    print('choose_profile: '),
    pprint.pprint(arguments)
    print('Launching: ' + arguments[0].get_name())

def show_menu(widget, event, applet):
    if event.type == Gtk.gdk.BUTTON_PRESS and \
        (event.button == 1 or event.button == 3):
        menu = Gtk.Menu()

        add_menu_label(menu, 'Active Mesh')

        actives, visibles, strengths = get_visible_adhocs()
        profiles = get_profiles()
        for profile in actives:
            if profile in profiles:
                add_menu_item(menu, profile[0], choose_profile,
                              '/usr/share/icons/hicolor/22x22/apps/nm-adhoc.png')

        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_label(menu, 'Available Profiles')
        for profile in profiles:
            if profile in actives:
                continue
            elif profile in visibles:
                add_visible_profile_menu_item(menu, profile[0], choose_profile,
                                              strengths[profile[0]])
            else:
                add_menu_item(menu, profile[0], choose_profile)

        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_item(menu, 'Show Mesh Status', show_mesh_status)
        add_menu_item(menu, 'Save Mesh Status To File...', save_mesh_status_to_file)
        add_menu_item(menu, Gtk.STOCK_ABOUT, show_about)
        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_item(menu, Gtk.STOCK_QUIT, do_exit)
        menu.popup( None, None, None, event.button, event.time )

        widget.emit_stop_by_name("button_press_event")

def show_mesh_status(*arguments):
    MeshStatus(arguments[0].get_toplevel()).show()

def save_mesh_status_to_file(*arguments):
    toplevel = arguments[0].get_toplevel()
    dialog = Gtk.FileChooserDialog("Save Mesh Status to File...",
                                   toplevel,
                                   Gtk.FILE_CHOOSER_ACTION_SAVE,
                                   (Gtk.STOCK_CANCEL, Gtk.RESPONSE_CANCEL,
                                    Gtk.STOCK_SAVE, Gtk.RESPONSE_OK))
    dialog.set_default_response(Gtk.RESPONSE_OK)
    dialog.set_do_overwrite_confirmation(True)

    file_filter = Gtk.FileFilter()
    file_filter.add_pattern("*.json")
    file_filter.set_name("JSON (*.json)")
    dialog.add_filter(file_filter)

    file_filter = Gtk.FileFilter()
    file_filter.add_pattern("*")
    file_filter.set_name("All files (*.*)")
    dialog.add_filter(file_filter)

    response = dialog.run()
    msg = None
    if response == Gtk.RESPONSE_OK:
        filename = dialog.get_filename()
        if not filename.endswith('.json'):
            filename += '.json'
        dump = JsonInfo().dump('/all')
        if dump:
            with open(filename, 'w') as f:
                f.write(dump)
        else:
            msg = Gtk.MessageDialog(toplevel,
                                    Gtk.DIALOG_DESTROY_WITH_PARENT,
                                    Gtk.MESSAGE_ERROR,
                                    (Gtk.BUTTONS_CLOSE),
                                    'Nothing was written because olsrd is not running, there is no active mesh profile!')
            msg.run()
            msg.destroy()
    dialog.destroy()

def show_about(*arguments):
    about_dialog = Gtk.AboutDialog()
    about_dialog.set_destroy_with_parent(True)
    about_dialog.set_program_name('Commotion Mesh Applet')
    about_dialog.set_comments('Commotion is an open-source communication tool that uses mobile phones, computers, and other wireless devices to create decentralized mesh networks.')
    about_dialog.set_website('https://commotionwireless.net/')
    icon = Gtk.gdk.pixbuf_new_from_file(os.path.join(commotion_mesh_panel_svg_dir,
                                        'commotion.svg'))
    about_dialog.set_logo(icon)

    def close(dialog, response, editor):
        dialog.destroy()
    about_dialog.connect("response", close, None)

    about_dialog.show_all()

def do_exit(*arguments):
    sys.exit()

def applet_factory(applet, iid, data = None):
    applet.set_background_widget(applet) # /* enable transparency hack */

    icon = Gtk.gdk.pixbuf_new_from_file(os.path.join(commotion_mesh_panel_svg_dir,
                                                     'commotion-mesh-disconnected.svg'))
    image = Gtk.Image()
    image.set_from_pixbuf(icon.scale_simple(22, 22, Gtk.gdk.INTERP_BILINEAR))
    button = Gtk.Button()
    button.set_relief(Gtk.RELIEF_NONE)
    button.set_image(image)
    button.connect("button_press_event", show_menu, applet)
    applet.add(button)
    applet.show_all()
    print('Factory started')
    return True

commotion_mesh_panel_svg_dir = '/usr/share/icons/hicolor/scalable/apps'
commotion_mesh_panel_png_dir = '/usr/share/icons/hicolor/scalable/apps'
<commit_msg>add an infobar to the status window to show the local status info<commit_after>
import glob
import json
import NetworkManager
import os
import pyjavaproperties
import re
import sys
import threading
import time
import urllib2

import pprint

try:
    from gi.repository import Gtk
except: # Can't use ImportError, as gi.repository isn't quite that nice...
    import gtk as Gtk

class JsonInfo():

    def __init__(self, baseurl='http://localhost:9090'):
        self.baseurl = baseurl
        self.jsondecoder = json.JSONDecoder()

    def dump(self, data='/all'):
        try:
            return urllib2.urlopen(self.baseurl + data).read()
        except urllib2.URLError:
            return None

    def dict(self, data='/all'):
        dump = self.dump(data)
        if dump:
            return self.jsondecoder.decode(dump)

class MeshStatus():

    def __init__(self, toplevel):
        self.toplevel = toplevel
        self.jsoninfo = JsonInfo()
        self.imagedir = commotion_mesh_panel_png_dir

    def _set_icon(self, cell, filename):
        fullfilename = os.path.join(self.imagedir, filename)
        cell.set_property("pixbuf", Gtk.gdk.pixbuf_new_from_file(fullfilename))

    def _internet_icon(self, column, cell, model, iter):
        if model[iter][3]:
            self._set_icon(cell, 'default_route.png')

    def _hna_icon(self, column, cell, model, iter):
        if model[iter][4]:
            self._set_icon(cell, 'other_route.png')

    def show(self):
        window = Gtk.Window()
        window.set_title('Mesh Status (Links and HNA)')
        window.set_resizable(False)
        vbox = Gtk.VBox(homogeneous=False, spacing=5)
        window.add(vbox)

        links_hna = self.jsoninfo.dict('/links/hna')
        # liststore data:  IP, LQ, NLQ, have_internet, have_HNA
        liststore = Gtk.ListStore(str, int, int, bool, bool)
        if links_hna:
            connected = True
            hna = []
            internet = []
            for i in links_hna['hna']:
                if i['destination'] == '0.0.0.0':
                    internet.append(i['gateway'])
                else:
                    hna.append(i['gateway'])
            for link in links_hna['links']:
                ip = link['remoteIP']
                lqPercent = int(link['linkQuality']*100)
                nlqPercent = int(link['neighborLinkQuality']*100)
                cell = [ ip, lqPercent, nlqPercent ]
                if ip in internet:
                    cell.append(True)
                else:
                    cell.append(False)
                if ip in hna:
                    cell.append(True)
                else:
                    cell.append(False)
                liststore.append(cell)
        else:
            connected = False
        myip = link['localIP']

        infobar = Gtk.InfoBar()
        if connected:
            infobar.set_message_type(Gtk.MESSAGE_OTHER)
            label = Gtk.Label('mesh address: ' + myip)
        else:
            infobar.set_message_type(Gtk.MESSAGE_ERROR)
            label = Gtk.Label('Not connected to a mesh!')
        content = infobar.get_content_area()
        content.set_homogeneous(False)
        content.pack_start(label, expand=False)
        if myip in hna:
            image = Gtk.Image()
            image.set_from_file(os.path.join(self.imagedir, 'other_route.png'))
            content.pack_start(image, expand=False)
            need_filler = True
        else:
            need_filler = False
        if myip in internet:
            image = Gtk.Image()
            image.set_from_file(os.path.join(self.imagedir, 'default_route.png'))
            # leave empty space so the internet icon is properly aligned
            if need_filler:
                content.pack_start(image, expand=False)
            else:
                content.pack_end(image, expand=False)
        vbox.pack_start(infobar, False)

        treeview = Gtk.TreeView(model=liststore)
        selection = treeview.get_selection()
        selection.set_mode(Gtk.SELECTION_NONE)
        vbox.pack_start(treeview, True, True, 3)

        column = Gtk.TreeViewColumn("Link IP Address")
        column.set_alignment(0.5)
        treeview.append_column(column)
        cell = Gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 0)

        column = Gtk.TreeViewColumn("LQ")
        column.set_alignment(0.5)
        column.set_resizable(True)
        treeview.append_column(column)
        cell = Gtk.CellRendererProgress()
        column.pack_start(cell, True)
        column.add_attribute(cell, "value", 1)

        column = Gtk.TreeViewColumn("NLQ")
        column.set_alignment(0.5)
        column.set_resizable(True)
        treeview.append_column(column)
        cell = Gtk.CellRendererProgress()
        column.pack_start(cell, True)
        column.add_attribute(cell, "value", 2)

        column = Gtk.TreeViewColumn("HNA?")
        column.set_alignment(0.5)
        column.set_resizable(False)
        treeview.append_column(column)
        cell = Gtk.CellRendererPixbuf()
        column.pack_start(cell, False)
        column.set_cell_data_func(cell, self._hna_icon)

        column = Gtk.TreeViewColumn("Internet?")
        column.set_alignment(0.5)
        column.set_resizable(False)
        treeview.append_column(column)
        cell = Gtk.CellRendererPixbuf()
        column.pack_start(cell, False)
        column.set_cell_data_func(cell, self._internet_icon)

        window.show_all()

def get_visible_adhocs():
    actives = []
    nets = []
    strengths = dict()
    for ac in NetworkManager.NetworkManager.ActiveConnections:
        for d in ac.Devices:
            if d.Managed and d.DeviceType == NetworkManager.NM_DEVICE_TYPE_WIFI:
                wireless = d.SpecificDevice()
                aap = wireless.ActiveAccessPoint
                if aap.Mode == NetworkManager.NM_802_11_MODE_ADHOC:
                    channel = (aap.Frequency - 2407) / 5
                    actives.append(tuple([aap.Ssid, aap.HwAddress, channel]))
                for ap in wireless.GetAccessPoints():
                    if ap.Mode == NetworkManager.NM_802_11_MODE_ADHOC:
                        channel = (aap.Frequency - 2407) / 5
                        nets.append(tuple([ap.Ssid, ap.HwAddress, channel]))
                        strengths[ap.Ssid] = ap.Strength
    return [tuple(actives), tuple(nets), strengths]

def get_profiles():
    '''get all the available mesh profiles and return as a list of tuples'''
    profiles = []
    for f in glob.glob('/etc/nm-dispatcher-olsrd/*.profile'):
        p = pyjavaproperties.Properties()
        p.load(open(f))
        bssid = p['bssid'].upper()
        channel = int(p['channel'])
        profiles.append(tuple([p['ssid'], bssid, channel]))
    return tuple(profiles)

def add_menu_item(menu, name, function, imagefile=None):
    item = Gtk.ImageMenuItem(name)
    if imagefile:
        icon = Gtk.Image()
        icon.set_from_file(imagefile)
        item.set_image(icon)
    item.show()
    item.connect( "activate", function)
    menu.add(item)

def add_menu_label(menu, name):
    item = Gtk.ImageMenuItem(name)
    item.set_sensitive(False)
    item.show()
    menu.add(item)

def add_visible_profile_menu_item(menu, name, function, strength):
    if strength > 98:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-100.png')
    elif strength >= 75:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-75.png')
    elif strength >= 50:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-50.png')
    elif strength >= 25:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-25.png')
    else:
        add_menu_item(menu, name, function,
                      '/usr/share/icons/hicolor/22x22/apps/nm-signal-00.png')

def choose_profile(*arguments):
    print('choose_profile: '),
    pprint.pprint(arguments)
    print('Launching: ' + arguments[0].get_name())

def show_menu(widget, event, applet):
    if event.type == Gtk.gdk.BUTTON_PRESS and \
        (event.button == 1 or event.button == 3):
        menu = Gtk.Menu()

        add_menu_label(menu, 'Active Mesh')

        actives, visibles, strengths = get_visible_adhocs()
        profiles = get_profiles()
        for profile in actives:
            if profile in profiles:
                add_menu_item(menu, profile[0], choose_profile,
                              '/usr/share/icons/hicolor/22x22/apps/nm-adhoc.png')

        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_label(menu, 'Available Profiles')
        for profile in profiles:
            if profile in actives:
                continue
            elif profile in visibles:
                add_visible_profile_menu_item(menu, profile[0], choose_profile,
                                              strengths[profile[0]])
            else:
                add_menu_item(menu, profile[0], choose_profile)

        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_item(menu, 'Show Mesh Status', show_mesh_status)
        add_menu_item(menu, 'Save Mesh Status To File...', save_mesh_status_to_file)
        add_menu_item(menu, Gtk.STOCK_ABOUT, show_about)
        sep = Gtk.SeparatorMenuItem(); sep.show(); menu.add(sep)
        add_menu_item(menu, Gtk.STOCK_QUIT, do_exit)
        menu.popup( None, None, None, event.button, event.time )

        widget.emit_stop_by_name("button_press_event")

def show_mesh_status(*arguments):
    MeshStatus(arguments[0].get_toplevel()).show()

def save_mesh_status_to_file(*arguments):
    toplevel = arguments[0].get_toplevel()
    dialog = Gtk.FileChooserDialog("Save Mesh Status to File...",
                                   toplevel,
                                   Gtk.FILE_CHOOSER_ACTION_SAVE,
                                   (Gtk.STOCK_CANCEL, Gtk.RESPONSE_CANCEL,
                                    Gtk.STOCK_SAVE, Gtk.RESPONSE_OK))
    dialog.set_default_response(Gtk.RESPONSE_OK)
    dialog.set_do_overwrite_confirmation(True)

    file_filter = Gtk.FileFilter()
    file_filter.add_pattern("*.json")
    file_filter.set_name("JSON (*.json)")
    dialog.add_filter(file_filter)

    file_filter = Gtk.FileFilter()
    file_filter.add_pattern("*")
    file_filter.set_name("All files (*.*)")
    dialog.add_filter(file_filter)

    response = dialog.run()
    msg = None
    if response == Gtk.RESPONSE_OK:
        filename = dialog.get_filename()
        if not filename.endswith('.json'):
            filename += '.json'
        dump = JsonInfo().dump('/all')
        if dump:
            with open(filename, 'w') as f:
                f.write(dump)
        else:
            msg = Gtk.MessageDialog(toplevel,
                                    Gtk.DIALOG_DESTROY_WITH_PARENT,
                                    Gtk.MESSAGE_ERROR,
                                    (Gtk.BUTTONS_CLOSE),
                                    'Nothing was written because olsrd is not running, there is no active mesh profile!')
            msg.run()
            msg.destroy()
    dialog.destroy()

def show_about(*arguments):
    about_dialog = Gtk.AboutDialog()
    about_dialog.set_destroy_with_parent(True)
    about_dialog.set_program_name('Commotion Mesh Applet')
    about_dialog.set_comments('Commotion is an open-source communication tool that uses mobile phones, computers, and other wireless devices to create decentralized mesh networks.')
    about_dialog.set_website('https://commotionwireless.net/')
    icon = Gtk.gdk.pixbuf_new_from_file(os.path.join(commotion_mesh_panel_svg_dir,
                                        'commotion.svg'))
    about_dialog.set_logo(icon)

    def close(dialog, response, editor):
        dialog.destroy()
    about_dialog.connect("response", close, None)

    about_dialog.show_all()

def do_exit(*arguments):
    sys.exit()

def applet_factory(applet, iid, data = None):
    applet.set_background_widget(applet) # /* enable transparency hack */

    icon = Gtk.gdk.pixbuf_new_from_file(os.path.join(commotion_mesh_panel_svg_dir,
                                                     'commotion-mesh-disconnected.svg'))
    image = Gtk.Image()
    image.set_from_pixbuf(icon.scale_simple(22, 22, Gtk.gdk.INTERP_BILINEAR))
    button = Gtk.Button()
    button.set_relief(Gtk.RELIEF_NONE)
    button.set_image(image)
    button.connect("button_press_event", show_menu, applet)
    applet.add(button)
    applet.show_all()
    print('Factory started')
    return True

commotion_mesh_panel_svg_dir = '/usr/share/icons/hicolor/scalable/apps'
commotion_mesh_panel_png_dir = '/usr/share/icons/hicolor/scalable/apps'
<|endoftext|>


<commit_before>import math
import pygame
from pygame.locals import *
import os.path
import sys

class VisualisationPlugin:
    meter_center = (200, 200)
    needle_length = 100
    display_surface = None
    plugin_object = None
    race_object = None

    needle_length = 140
    participant_info_box_width = 180
    participant_info_box_height = 90

    background_image = None

    gauge_center = (514, 375) # gauge center position in background image
    gauge_rect = pygame.Rect(330, 200, 360, 350)
    time_display_rect = pygame.Rect(10, 10, 180, 80)

    start_time = None

    application = None

    def __init__(self, application_object, plugin_object):
        print "init in plugin"
        self.application = application_object
        self.plugin_object = plugin_object
        self.display_surface = self.application.get_window_surface()

    def start(self, race_object):
        print "start in plugin"
        print "race object sent to plugin:"
        print race_object

        self.race_object = race_object
        self.render()

        clock = pygame.time.Clock()
        while True:
          clock.tick(50)

          for event in pygame.event.get():
              if event.type == pygame.locals.KEYUP:
                  if event.key == pygame.locals.K_ESCAPE:
                      pygame.quit()
                      sys.exit()
                  elif event.key == pygame.locals.K_a:
                      if (self.race_object):
                          participant = self.race_object.participants[0]
                          participant.increase_distance(0.5)
                          print self.race_object.participants[0].distance
                          print self.race_object.elapsed_time()
                  elif event.key == pygame.locals.K_s:
                      if (self.race_object):
                          participant = self.race_object.participants[1]
                          participant.increase_distance(0.5)
                          print self.race_object.participants[1].distance
                          print self.race_object.elapsed_time()

          # Clear the screen
          #self.display_surface.fill((0, 0, 0))

          self.update()

    def spinCount(self, count, roller):
        print "spinCount in plugin"

    def render(self):
        # Resolution
        display_info = pygame.display.Info()
        display_width = display_info.current_w
        display_height = display_info.current_h

        background_image_path = os.path.join(self.plugin_object.path, "images/background-wood3-1024x768.png")
        self.background_image = pygame.image.load(background_image_path).convert()
        backgroundRect = self.background_image.get_rect()
        backgroundRect.x = 0
        backgroundRect.y = 0
        self.display_surface.blit(self.background_image, backgroundRect)

        #needle_image_path = os.path.join(self.plugin_object.path, "images/needle.png")
        #needle = pygame.image.load(needle_image_path).convert()
        #needleRect = needle.get_rect()
        #needleRect.centerx = 600
        #needleRect.centery = 500
        #self.display_surface.blit(needle, needleRect)

        pygame.display.update()

    def update(self):
        self.clear_gauge()
        self.update_gauge()

        self.update_time_display()

        self.update_boxes()

        pygame.display.update()

    def clear_gauge(self):
        self.display_surface.blit(self.background_image, (self.gauge_rect[0], self.gauge_rect[1]), self.gauge_rect)

    def update_gauge(self):
        line1_angle = (self.race_object.participants[0].distance / self.race_object.options.distance) * 360
        line1_x2 = self.gauge_center[0] + math.cos(math.radians(line1_angle - 90)) * self.needle_length
        line1_y2 = self.gauge_center[1] + math.sin(math.radians(line1_angle - 90)) * self.needle_length
        pygame.draw.line(self.display_surface, Color("red"), self.gauge_center, (line1_x2, line1_y2), 1)

        line2_angle = (self.race_object.participants[1].distance / self.race_object.options.distance) * 360
        line2_angle_radians = line2_angle * (180 / math.pi)
        line2_x2 = self.gauge_center[0] + math.cos(math.radians(line2_angle - 90)) * self.needle_length
        line2_y2 = self.gauge_center[1] + math.sin(math.radians(line2_angle - 90)) * self.needle_length
        pygame.draw.line(self.display_surface, Color("blue"), self.gauge_center, (line2_x2, line2_y2), 1)

    def update_time_display(self):
        self.display_surface.fill(Color("black"), self.time_display_rect)

        font_path = "./fonts/Cave-Story.ttf"
        time_font = pygame.font.Font(font_path, 68)

        # set up the text
        time_string = '{0:.2f}'.format(self.race_object.elapsed_time())
        print time_string
        text = time_font.render(time_string, True, Color("white"), None)
        text_rect = text.get_rect()
        text_rect.centerx = self.time_display_rect.centerx
        text_rect.centery = self.time_display_rect.centery
        self.display_surface.blit(text, text_rect)

    def update_boxes(self):
        self.render_participant_info_box(self.race_object.participants[0], (800, 20))
        self.render_participant_info_box(self.race_object.participants[1], (800, 150))

    def render_participant_info_box(self, participant, position):
        box_rect = pygame.Rect(position[0], position[1], self.participant_info_box_width, self.participant_info_box_height)
        self.display_surface.fill(participant.color, box_rect)

        font_path = "./fonts/Cave-Story.ttf"
        distance_font = pygame.font.Font(font_path, 68)
        distance_string = str('{0:.2f}'.format(participant.distance))
        text = distance_font.render(distance_string, True, Color("white"), None)
        text_rect = text.get_rect()
        text_rect.centerx = box_rect.centerx
        text_rect.centery = box_rect.centery
        self.display_surface.blit(text, text_rect)

<commit_msg>start_time no longer in needles plugin<commit_after>import math
import pygame
from pygame.locals import *
import os.path
import sys

class VisualisationPlugin:
    meter_center = (200, 200)
    needle_length = 100
    display_surface = None
    plugin_object = None
    race_object = None

    needle_length = 140
    participant_info_box_width = 180
    participant_info_box_height = 90

    background_image = None

    gauge_center = (514, 375) # gauge center position in background image
    gauge_rect = pygame.Rect(330, 200, 360, 350)
    time_display_rect = pygame.Rect(10, 10, 180, 80)

    application = None

    def __init__(self, application_object, plugin_object):
        print "init in plugin"
        self.application = application_object
        self.plugin_object = plugin_object
        self.display_surface = self.application.get_window_surface()

    def start(self, race_object):
        print "start in plugin"
        print "race object sent to plugin:"
        print race_object

        self.race_object = race_object
        self.render()

        clock = pygame.time.Clock()
        while True:
          clock.tick(50)

          for event in pygame.event.get():
              if event.type == pygame.locals.KEYUP:
                  if event.key == pygame.locals.K_ESCAPE:
                      pygame.quit()
                      sys.exit()
                  elif event.key == pygame.locals.K_a:
                      if (self.race_object):
                          participant = self.race_object.participants[0]
                          participant.increase_distance(0.5)
                          print self.race_object.participants[0].distance
                          print self.race_object.elapsed_time()
                  elif event.key == pygame.locals.K_s:
                      if (self.race_object):
                          participant = self.race_object.participants[1]
                          participant.increase_distance(0.5)
                          print self.race_object.participants[1].distance
                          print self.race_object.elapsed_time()

          # Clear the screen
          #self.display_surface.fill((0, 0, 0))

          self.update()

    def spinCount(self, count, roller):
        print "spinCount in plugin"

    def render(self):
        # Resolution
        display_info = pygame.display.Info()
        display_width = display_info.current_w
        display_height = display_info.current_h

        background_image_path = os.path.join(self.plugin_object.path, "images/background-wood3-1024x768.png")
        self.background_image = pygame.image.load(background_image_path).convert()
        backgroundRect = self.background_image.get_rect()
        backgroundRect.x = 0
        backgroundRect.y = 0
        self.display_surface.blit(self.background_image, backgroundRect)

        #needle_image_path = os.path.join(self.plugin_object.path, "images/needle.png")
        #needle = pygame.image.load(needle_image_path).convert()
        #needleRect = needle.get_rect()
        #needleRect.centerx = 600
        #needleRect.centery = 500
        #self.display_surface.blit(needle, needleRect)

        pygame.display.update()

    def update(self):
        self.clear_gauge()
        self.update_gauge()

        self.update_time_display()

        self.update_boxes()

        pygame.display.update()

    def clear_gauge(self):
        self.display_surface.blit(self.background_image, (self.gauge_rect[0], self.gauge_rect[1]), self.gauge_rect)

    def update_gauge(self):
        line1_angle = (self.race_object.participants[0].distance / self.race_object.options.distance) * 360
        line1_x2 = self.gauge_center[0] + math.cos(math.radians(line1_angle - 90)) * self.needle_length
        line1_y2 = self.gauge_center[1] + math.sin(math.radians(line1_angle - 90)) * self.needle_length
        pygame.draw.line(self.display_surface, Color("red"), self.gauge_center, (line1_x2, line1_y2), 1)

        line2_angle = (self.race_object.participants[1].distance / self.race_object.options.distance) * 360
        line2_angle_radians = line2_angle * (180 / math.pi)
        line2_x2 = self.gauge_center[0] + math.cos(math.radians(line2_angle - 90)) * self.needle_length
        line2_y2 = self.gauge_center[1] + math.sin(math.radians(line2_angle - 90)) * self.needle_length
        pygame.draw.line(self.display_surface, Color("blue"), self.gauge_center, (line2_x2, line2_y2), 1)

    def update_time_display(self):
        self.display_surface.fill(Color("black"), self.time_display_rect)

        font_path = "./fonts/Cave-Story.ttf"
        time_font = pygame.font.Font(font_path, 68)

        # set up the text
        time_string = '{0:.2f}'.format(self.race_object.elapsed_time())
        print time_string
        text = time_font.render(time_string, True, Color("white"), None)
        text_rect = text.get_rect()
        text_rect.centerx = self.time_display_rect.centerx
        text_rect.centery = self.time_display_rect.centery
        self.display_surface.blit(text, text_rect)

    def update_boxes(self):
        self.render_participant_info_box(self.race_object.participants[0], (800, 20))
        self.render_participant_info_box(self.race_object.participants[1], (800, 150))

    def render_participant_info_box(self, participant, position):
        box_rect = pygame.Rect(position[0], position[1], self.participant_info_box_width, self.participant_info_box_height)
        self.display_surface.fill(participant.color, box_rect)

        font_path = "./fonts/Cave-Story.ttf"
        distance_font = pygame.font.Font(font_path, 68)
        distance_string = str('{0:.2f}'.format(participant.distance))
        text = distance_font.render(distance_string, True, Color("white"), None)
        text_rect = text.get_rect()
        text_rect.centerx = box_rect.centerx
        text_rect.centery = box_rect.centery
        self.display_surface.blit(text, text_rect)

<|endoftext|>


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

Generated by 'django-admin startproject' using Django 1.8.

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

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

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

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

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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'l)zht&^pddidsyqe$+09%se1*ba2#b_q-!j0^v$(-3c-=-vmq4'

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

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
    'organizer',
    'blog',
)

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

ROOT_URLCONF = 'suorganizer.urls'

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [
        os.path.join(BASE_DIR, 'templates'),
    ],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
        ],
    },
}]

WSGI_APPLICATION = 'suorganizer.wsgi.application'

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

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

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
<commit_msg>Ch11: Add contact app to settings.<commit_after>"""
Django settings for suorganizer project.

Generated by 'django-admin startproject' using Django 1.8.

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

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

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

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

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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'l)zht&^pddidsyqe$+09%se1*ba2#b_q-!j0^v$(-3c-=-vmq4'

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

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
    'organizer',
    'blog',
    'contact',
)

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

ROOT_URLCONF = 'suorganizer.urls'

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [
        os.path.join(BASE_DIR, 'templates'),
    ],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
        ],
    },
}]

WSGI_APPLICATION = 'suorganizer.wsgi.application'

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

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

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
<|endoftext|>


<commit_before>from __future__ import division, print_function

import numpy as np

from .optimizer import LinearScanOptimizer

class PeriodicModeler(object):
    """Base class for periodic modeling"""
    def __init__(self, optimizer=None, fit_period=False,
                 optimizer_kwds=None, *args, **kwargs):
        if optimizer is None:
            kwds = optimizer_kwds or {}
            optimizer = LinearScanOptimizer(**kwds)
        elif optimizer_kwds:
            warnings.warn("Optimizer specified, so optimizer keywords ignored")

        if not hasattr(optimizer, 'best_period'):
            raise ValueError("optimizer must be a PeriodicOptimizer instance: "
                             "{0} has no best_period method".format(optimizer))
        self.optimizer = optimizer
        self.fit_period = fit_period
        self.args = args
        self.kwargs = kwargs
        self._best_period = None

    def fit(self, t, y, dy=None):
        """Fit the multiterm Periodogram model to the data.

        Parameters
        ----------
        t : array_like, one-dimensional
            sequence of observation times
        y : array_like, one-dimensional
            sequence of observed values
        dy : float or array_like (optional)
            errors on observed values
        """
        # For linear models, dy=1 is equivalent to no errors
        if dy is None:
            dy = 1

        self.t, self.y, self.dy = np.broadcast_arrays(t, y, dy)

        self._fit(self.t, self.y, self.dy)
        self._best_period = None  # reset best period in case of refitting

        if self.fit_period:
            self._best_period = self._calc_best_period()

        return self

    def predict(self, t, period=None):
        """Compute the best-fit model at ``t`` for a given frequency omega

        Parameters
        ----------
        t : float or array_like
            times at which to predict
        period : float (optional)
            The period at which to compute the model. If not specified, it
            will be computed via the optimizer provided at initialization.

        Returns
        -------
        y : np.ndarray
            predicted model values at times t
        """
        t = np.asarray(t)
        if period is None:
            period = self.best_period
        result = self._predict(t.ravel(), period=period)
        return result.reshape(t.shape)

    def score_frequency_grid(self, f0, df, N):
        """Compute the score on a frequency grid.

        Some models can compute results faster if the inputs are passed in this
        manner.

        Parameters
        ----------
        f0, df, N : (float, float, int)
            parameters describing the frequency grid freq = f0 + df * arange(N)
            Note that these are frequencies, not angular frequencies.

        Returns
        -------
        score : ndarray
            the length-N array giving the score at each frequency
        """
        return self._score_frequency_grid(f0, df, N)

    def periodogram_auto(self, oversampling=5, nyquist_factor=3,
                         return_periods=True):
        """Compute the periodogram on an automatically-determined grid

        This function uses heuristic arguments to choose a suitable frequency
        grid for the data. Note that depending on the data window function,
        the model may be sensitive to periodicity at higher frequencies than
        this function returns!

        The final number of frequencies will be
        Nf = oversampling * nyquist_factor * len(t) / 2

        Parameters
        ----------
        oversampling : float
            the number of samples per approximate peak width
        nyquist_factor : float
            the highest frequency, in units of the nyquist frequency for points
            spread uniformly through the data range.

        Returns
        -------
        period : ndarray
            the grid of periods
        power : ndarray
            the power at each frequency
        """
        N = len(self.t)
        T = np.max(self.t) - np.min(self.t)
        df = 1. / T / oversampling
        f0 = df
        Nf = int(0.5 * oversampling * nyquist_factor * N)
        freq = f0 + df * np.arange(Nf)
        return 1. / freq, self._score_frequency_grid(f0, df, Nf)

    def score(self, periods=None):
        """Compute the periodogram for the given period or periods

        Parameters
        ----------
        periods : float or array_like
            Array of angular frequencies at which to compute
            the periodogram.

        Returns
        -------
        scores : np.ndarray
            Array of normalized powers (between 0 and 1) for each frequency.
            Shape of scores matches the shape of the provided periods.
        """
        periods = np.asarray(periods)
        return self._score(periods.ravel()).reshape(periods.shape)

    periodogram = score

    @property
    def best_period(self):
        """Lazy evaluation of the best period given the model"""
        if self._best_period is None:
            self._best_period = self._calc_best_period()
        return self._best_period

    def find_best_periods(self, n_periods=5, return_scores=False):
        """Find the top several best periods for the model"""
        return self.optimizer.find_best_periods(self, n_periods,
                                                return_scores=return_scores)

    def _calc_best_period(self):
        """Compute the best period using the optimizer"""
        return self.optimizer.best_period(self)

    # The following methods should be overloaded by derived classes:

    def _score_frequency_grid(self, f0, df, N):
        freq = f0 + df * np.arange(N)
        return self._score(1. / freq)

    def _score(self, periods):
        """Compute the score of the model given the periods"""
        raise NotImplementedError()

    def _fit(self, t, y, dy):
        """Fit the model to the given data"""
        raise NotImplementedError()

    def _predict(self, t, period):
        """Predict the model values at the given times"""
        raise NotImplementedError()

class PeriodicModelerMultiband(PeriodicModeler):
    """Base class for periodic modeling on multiband data"""

    def fit(self, t, y, dy=None, filts=0):
        """Fit the multiterm Periodogram model to the data.

        Parameters
        ----------
        t : array_like, one-dimensional
            sequence of observation times
        y : array_like, one-dimensional
            sequence of observed values
        dy : float or array_like (optional)
            errors on observed values
        filts : array_like (optional)
            The array specifying the filter/bandpass for each observation.
        """
        self.unique_filts_ = np.unique(filts)

        # For linear models, dy=1 is equivalent to no errors
        if dy is None:
            dy = 1

        all_data = np.broadcast_arrays(t, y, dy, filts)
        self.t, self.y, self.dy, self.filts = map(np.ravel, all_data)

        self._fit(self.t, self.y, self.dy, self.filts)
        self._best_period = None  # reset best period in case of refitting

        if self.fit_period:
            self._best_period = self._calc_best_period()
        return self

    def predict(self, t, filts, period=None):
        """Compute the best-fit model at ``t`` for a given frequency omega

        Parameters
        ----------
        t : float or array_like
            times at which to predict
        filts : array_like (optional)
            the array specifying the filter/bandpass for each observation. This
            is used only in multiband periodograms.
        period : float (optional)
            The period at which to compute the model. If not specified, it
            will be computed via the optimizer provided at initialization.

        Returns
        -------
        y : np.ndarray
            predicted model values at times t
        """
        unique_filts = set(np.unique(filts))
        if not unique_filts.issubset(self.unique_filts_):
            raise ValueError("filts does not match training data: "
                             "input: {0} output: {1}"
                             "".format(set(self.unique_filts_),
                                       set(unique_filts)))
        t, filts = np.broadcast_arrays(t, filts)

        if period is None:
            period = self.best_period

        result = self._predict(t.ravel(), filts=filts.ravel(), period=period)
        return result.reshape(t.shape)

    # The following methods should be overloaded by derived classes:

    def _score(self, periods):
        """Compute the score of the model given the periods"""
        raise NotImplementedError()

    def _fit(self, t, y, dy, filts):
        """Fit the model to the given data"""
        raise NotImplementedError()

    def _predict(self, t, filts, period):
        """Predict the model values at the given times & filters"""
        raise NotImplementedError()
<commit_msg>DOC: correct 'frequency' to 'period' in docstrings<commit_after>from __future__ import division, print_function

import numpy as np

from .optimizer import LinearScanOptimizer

class PeriodicModeler(object):
    """Base class for periodic modeling"""
    def __init__(self, optimizer=None, fit_period=False,
                 optimizer_kwds=None, *args, **kwargs):
        if optimizer is None:
            kwds = optimizer_kwds or {}
            optimizer = LinearScanOptimizer(**kwds)
        elif optimizer_kwds:
            warnings.warn("Optimizer specified, so optimizer keywords ignored")

        if not hasattr(optimizer, 'best_period'):
            raise ValueError("optimizer must be a PeriodicOptimizer instance: "
                             "{0} has no best_period method".format(optimizer))
        self.optimizer = optimizer
        self.fit_period = fit_period
        self.args = args
        self.kwargs = kwargs
        self._best_period = None

    def fit(self, t, y, dy=None):
        """Fit the multiterm Periodogram model to the data.

        Parameters
        ----------
        t : array_like, one-dimensional
            sequence of observation times
        y : array_like, one-dimensional
            sequence of observed values
        dy : float or array_like (optional)
            errors on observed values
        """
        # For linear models, dy=1 is equivalent to no errors
        if dy is None:
            dy = 1

        self.t, self.y, self.dy = np.broadcast_arrays(t, y, dy)

        self._fit(self.t, self.y, self.dy)
        self._best_period = None  # reset best period in case of refitting

        if self.fit_period:
            self._best_period = self._calc_best_period()

        return self

    def predict(self, t, period=None):
        """Compute the best-fit model at ``t`` for a given period

        Parameters
        ----------
        t : float or array_like
            times at which to predict
        period : float (optional)
            The period at which to compute the model. If not specified, it
            will be computed via the optimizer provided at initialization.

        Returns
        -------
        y : np.ndarray
            predicted model values at times t
        """
        t = np.asarray(t)
        if period is None:
            period = self.best_period
        result = self._predict(t.ravel(), period=period)
        return result.reshape(t.shape)

    def score_frequency_grid(self, f0, df, N):
        """Compute the score on a frequency grid.

        Some models can compute results faster if the inputs are passed in this
        manner.

        Parameters
        ----------
        f0, df, N : (float, float, int)
            parameters describing the frequency grid freq = f0 + df * arange(N)
            Note that these are frequencies, not angular frequencies.

        Returns
        -------
        score : ndarray
            the length-N array giving the score at each frequency
        """
        return self._score_frequency_grid(f0, df, N)

    def periodogram_auto(self, oversampling=5, nyquist_factor=3,
                         return_periods=True):
        """Compute the periodogram on an automatically-determined grid

        This function uses heuristic arguments to choose a suitable frequency
        grid for the data. Note that depending on the data window function,
        the model may be sensitive to periodicity at higher frequencies than
        this function returns!

        The final number of frequencies will be
        Nf = oversampling * nyquist_factor * len(t) / 2

        Parameters
        ----------
        oversampling : float
            the number of samples per approximate peak width
        nyquist_factor : float
            the highest frequency, in units of the nyquist frequency for points
            spread uniformly through the data range.

        Returns
        -------
        period : ndarray
            the grid of periods
        power : ndarray
            the power at each frequency
        """
        N = len(self.t)
        T = np.max(self.t) - np.min(self.t)
        df = 1. / T / oversampling
        f0 = df
        Nf = int(0.5 * oversampling * nyquist_factor * N)
        freq = f0 + df * np.arange(Nf)
        return 1. / freq, self._score_frequency_grid(f0, df, Nf)

    def score(self, periods=None):
        """Compute the periodogram for the given period or periods

        Parameters
        ----------
        periods : float or array_like
            Array of periods at which to compute the periodogram.

        Returns
        -------
        scores : np.ndarray
            Array of normalized powers (between 0 and 1) for each period.
            Shape of scores matches the shape of the provided periods.
        """
        periods = np.asarray(periods)
        return self._score(periods.ravel()).reshape(periods.shape)

    periodogram = score

    @property
    def best_period(self):
        """Lazy evaluation of the best period given the model"""
        if self._best_period is None:
            self._best_period = self._calc_best_period()
        return self._best_period

    def find_best_periods(self, n_periods=5, return_scores=False):
        """Find the top several best periods for the model"""
        return self.optimizer.find_best_periods(self, n_periods,
                                                return_scores=return_scores)

    def _calc_best_period(self):
        """Compute the best period using the optimizer"""
        return self.optimizer.best_period(self)

    # The following methods should be overloaded by derived classes:

    def _score_frequency_grid(self, f0, df, N):
        freq = f0 + df * np.arange(N)
        return self._score(1. / freq)

    def _score(self, periods):
        """Compute the score of the model given the periods"""
        raise NotImplementedError()

    def _fit(self, t, y, dy):
        """Fit the model to the given data"""
        raise NotImplementedError()

    def _predict(self, t, period):
        """Predict the model values at the given times"""
        raise NotImplementedError()

class PeriodicModelerMultiband(PeriodicModeler):
    """Base class for periodic modeling on multiband data"""

    def fit(self, t, y, dy=None, filts=0):
        """Fit the multiterm Periodogram model to the data.

        Parameters
        ----------
        t : array_like, one-dimensional
            sequence of observation times
        y : array_like, one-dimensional
            sequence of observed values
        dy : float or array_like (optional)
            errors on observed values
        filts : array_like (optional)
            The array specifying the filter/bandpass for each observation.
        """
        self.unique_filts_ = np.unique(filts)

        # For linear models, dy=1 is equivalent to no errors
        if dy is None:
            dy = 1

        all_data = np.broadcast_arrays(t, y, dy, filts)
        self.t, self.y, self.dy, self.filts = map(np.ravel, all_data)

        self._fit(self.t, self.y, self.dy, self.filts)
        self._best_period = None  # reset best period in case of refitting

        if self.fit_period:
            self._best_period = self._calc_best_period()
        return self

    def predict(self, t, filts, period=None):
        """Compute the best-fit model at ``t`` for a given period

        Parameters
        ----------
        t : float or array_like
            times at which to predict
        filts : array_like (optional)
            the array specifying the filter/bandpass for each observation. This
            is used only in multiband periodograms.
        period : float (optional)
            The period at which to compute the model. If not specified, it
            will be computed via the optimizer provided at initialization.

        Returns
        -------
        y : np.ndarray
            predicted model values at times t
        """
        unique_filts = set(np.unique(filts))
        if not unique_filts.issubset(self.unique_filts_):
            raise ValueError("filts does not match training data: "
                             "input: {0} output: {1}"
                             "".format(set(self.unique_filts_),
                                       set(unique_filts)))
        t, filts = np.broadcast_arrays(t, filts)

        if period is None:
            period = self.best_period

        result = self._predict(t.ravel(), filts=filts.ravel(), period=period)
        return result.reshape(t.shape)

    # The following methods should be overloaded by derived classes:

    def _score(self, periods):
        """Compute the score of the model given the periods"""
        raise NotImplementedError()

    def _fit(self, t, y, dy, filts):
        """Fit the model to the given data"""
        raise NotImplementedError()

    def _predict(self, t, filts, period):
        """Predict the model values at the given times & filters"""
        raise NotImplementedError()
<|endoftext|>


<commit_before>import re
import sys
import json
import uuid
import sqlite3
from datetime import datetime
from hashlib import sha256, md5

from geoip import geolite2

from website.app import init_app
from website.models import User, Node
from website.util.metrics import get_entry_point

from scripts.migrate_piwik import utils
from scripts.migrate_piwik import settings
from scripts.migrate_piwik import lookup_data

def main():

    history_run_id = utils.get_history_run_id_for('extract')
    complaints_run_id = utils.get_complaints_run_id_for('extract')
    if history_run_id != complaints_run_id:
        print("You need to validate your exported data! Bailing...")
        sys.exit()

    extract_complaints = utils.get_complaints_for('extract', 'r')
    extract_complaints.readline()  # toss header
    if extract_complaints.readline():
        print("You have unaddressed complaints! Bailing...")
        sys.exit()

    sqlite_db = sqlite3.connect(settings.SQLITE_PATH)
    sqlite_setup(sqlite_db)

    input_file = open(utils.get_dir_for('extract') + '/' + settings.EXTRACT_FILE, 'r')
    transform_dir = utils.get_dir_for('transform01')
    output_file = open(transform_dir + '/' + settings.TRANSFORM01_FILE, 'w')

    history_file = utils.get_history_for('transform01', 'w')
    history_file.write('Run ID: {}\n'.format(complaints_run_id))
    history_file.write('Beginning extraction at: {}Z\n'.format(datetime.utcnow()))

    user_cache = {}
    node_cache = {}
    location_cache = {}

    linenum = 0
    tally = {'missing_user': 0, 'missing_node': 0}
    for pageview_json in input_file.readlines():
        linenum += 1
        if not linenum % 1000:
            print('Transforming line {}'.format(linenum))

        raw_pageview = json.loads(pageview_json)
        visit = raw_pageview['visit']
        action = raw_pageview['action']

        location = None
        ip_addr = visit['ip_addr']
        if ip_addr is not None:
            if not location_cache.has_key(ip_addr):
                location_cache[ip_addr] = geolite2.lookup(ip_addr)

            location = location_cache[ip_addr]

        session_id = str(uuid.uuid4())
        keen_id = get_or_create_keen_id(visit['visitor_id'], sqlite_db)

        user_id = visit['user_id']
        if user_id is not None:
            if not user_cache.has_key(user_id):
                user_obj = User.load(user_id)
                user_cache[user_id] = {
                    'anon': md5(session_id).hexdigest(),
                    'entry_point': None if user_obj is None else get_entry_point(user_obj)
                }

            anon_id = user_cache[user_id]['anon']
            user_entry_point = user_cache[user_id]['entry_point']

        node = None
        node_id = action['node_id']
        if node_id is not None:
            if not node_cache.has_key(node_id):
                node_cache[node_id] = Node.load(node_id)
            node = node_cache[node_id]

        browser_version = [None, None]
        if visit['ua']['browser']['version']:
            browser_version = visit['ua']['browser']['version'].split('.')

        browser_info = {
            'device': {
                'family': visit['ua']['device'],
            },
            'os': {
                'major': None,
                'patch_minor': None,
                'minor': None,
                'family': parse_os_family(visit['ua']['os']),
                'patch': None,
            },
            'browser': {
                'major': browser_version[0],
                'minor': browser_version[1],
                'family': parse_browser_family(visit['ua']['browser']['name']),
                'patch': None,
            },
        }

        node_tags = action['node_tags'] or ''

        # piwik stores resolution as 1900x600 mostly, but sometimes as a float?
        # For the sake of my sanity and yours, let's ignore floats.
        screen_resolution = (None, None)
        if re.search('x', visit['ua']['screen']):
            screen_resolution = visit['ua']['screen'].split('x')

        pageview = {
            'page': {
                'title': action['page']['title'],
                'url': action['page']['url_prefix'] + action['page']['url'],
                'info': {}  # (add-on)
            },
            'referrer': {
                'url': action['referrer'] or None,
                'info': {}, # (add-on)
            },
            'tech': {
                'browser': {  # JS-side will be filled in by Keen.helpers.getBrowserProfile()
                    'cookies': True if visit['ua']['browser']['cookies'] else False,
                    'screen': {
                        'height': screen_resolution[1],
                        'width': screen_resolution[0],
                    },
                },
                'ip': ip_addr,  # private
                'ua': None,
                'info': browser_info,
            },
            'time': {
                'utc': parse_server_time(action['timestamp']),
                'local': {}
            },
            'visitor': {
                'id': keen_id,
                'session': session_id,  # random val (sessionId)
                'returning': True if visit['visitor_returning'] else False,  # visit
            },
            'user': {
                'id': user_id,  # private
                'entryPoint': user_entry_point,
            },
            'node': {
                'id': node_id,
                'title': getattr(node, 'title', None),
                'type': getattr(node, 'category', None),
                'tags': [tag for tag in node_tags.split(',')]
            },
            'geo': {},
            'anon': {
                'id': anon_id,
                'continent': getattr(location, 'continent', None),
                'country': getattr(location, 'country', None),
                'latitude': getattr(location, 'location', (None, None))[0],
                'longitude': getattr(location, 'location', (None, None))[1],
            },
            'keen': {
                'timestamp': action['timestamp'],
                'addons': [
                    {
                        'name': 'keen:referrer_parser',
                        'input': {
                            'referrer_url': 'referrer.url',
                            'page_url': 'page.url'
                        },
                        'output': 'referrer.info'
                    },
                    {
                        'name': 'keen:url_parser',
                        'input': {
                            'url': 'page.url'
                        },
                        'output': 'page.info'
                    },
                    {
                        'name': 'keen:url_parser',
                        'input': {
                            'url': 'referrer.url'
                        },
                        'output': 'referrer.info'
                    },
                    {  # private
                        'name': 'keen:ip_to_geo',
                        'input': {
                            'ip': 'tech.ip'
                        },
                        'output': 'geo',
                    }
                ],
            }
        }

        if node_id is None:
            tally['missing_node'] += 1

        if user_id is None:
            tally['missing_user'] += 1

        output_file.write(json.dumps(pageview) + '\n')

    history_file.write('Finished extraction at: {}Z\n'.format(datetime.utcnow()))
    history_file.write('Final count was: {}\n'.format(linenum))
    history_file.write('{} pageviews lacked a user id.\n'.format(tally['missing_user']))
    history_file.write('{} pageviews lacked a node id.\n'.format(tally['missing_node']))
    sqlite_db.close()

def sqlite_setup(sqlite_db):
    """Test whether we already have an sqlite db for mapping Piwik user_ids to new keen ids,
    and if not create one.
    :return:
    """
    cursor = sqlite_db.cursor()

    try:
        cursor.execute('SELECT COUNT(*) FROM matched_ids')
    except sqlite3.OperationalError:
        cursor.execute('CREATE TABLE matched_ids (piwik_id TEXT, keen_id TEXT)')
        sqlite_db.commit()

def get_or_create_keen_id(user_id, sqlite_db):
    """Gets or creates a new Keen Id given a Piwik User Id from the db

    :param user_id: Piwik User Id from current row in database
    :param sqlite_db: SQLite3 database handle
    :return: Keen Id as str
    """
    cursor = sqlite_db.cursor()
    query = "SELECT * FROM matched_ids WHERE piwik_id='{p_id}'".format(p_id=user_id)
    cursor.execute(query)

    keen_id = cursor.fetchall()

    if len(keen_id) > 1:
        raise Exception("Multiple ID's found for single Piwik User ID")

    if not keen_id:
        keen_id = uuid.uuid4()
        query = "INSERT INTO matched_ids (piwik_id, keen_id) VALUES ('{p_id}', '{n_id}');".format(
            p_id=str(user_id), n_id=str(keen_id)
        )
        cursor.execute(query)
        sqlite_db.commit()
        return str(keen_id)

    return str(keen_id[0][1])

def parse_os_family(os_key):
    """Attempts to parse Piwik OS key codes into corresponding OS names

    :param os_name: Operating System keycode
    :return: Operating System name
    """

    if os_key in lookup_data.legacy_os_keys:
        os_key = lookup_data.legacy_os_keys[os_key]

    return lookup_data.os_keys.get(os_key, 'Unknown')

def parse_browser_family(browser_key):
    """Attempts to parse Piwik browser key codes into corresponding browser names

    :param browser_key: Browser keycode
    :return: Browser name
    """
    return lookup_data.browser_keys.get(browser_key, 'Unknown')

def parse_server_time(server_time):
    timestamp = datetime.strptime(server_time, '%Y-%m-%d %H:%M:%S')
    return {
        'hour_of_day': timestamp.hour,
        'day_of_week': timestamp.isoweekday(),
        'day_of_month': timestamp.day,
        'month': timestamp.month,
        'year': timestamp.year,
    }

if __name__ == "__main__":
    init_app(set_backends=True, routes=False)
    main()
<commit_msg>transform-01: fix casing on user entry point<commit_after>import re
import sys
import json
import uuid
import sqlite3
from datetime import datetime
from hashlib import sha256, md5

from geoip import geolite2

from website.app import init_app
from website.models import User, Node
from website.util.metrics import get_entry_point

from scripts.migrate_piwik import utils
from scripts.migrate_piwik import settings
from scripts.migrate_piwik import lookup_data

def main():

    history_run_id = utils.get_history_run_id_for('extract')
    complaints_run_id = utils.get_complaints_run_id_for('extract')
    if history_run_id != complaints_run_id:
        print("You need to validate your exported data! Bailing...")
        sys.exit()

    extract_complaints = utils.get_complaints_for('extract', 'r')
    extract_complaints.readline()  # toss header
    if extract_complaints.readline():
        print("You have unaddressed complaints! Bailing...")
        sys.exit()

    sqlite_db = sqlite3.connect(settings.SQLITE_PATH)
    sqlite_setup(sqlite_db)

    input_file = open(utils.get_dir_for('extract') + '/' + settings.EXTRACT_FILE, 'r')
    transform_dir = utils.get_dir_for('transform01')
    output_file = open(transform_dir + '/' + settings.TRANSFORM01_FILE, 'w')

    history_file = utils.get_history_for('transform01', 'w')
    history_file.write('Run ID: {}\n'.format(complaints_run_id))
    history_file.write('Beginning extraction at: {}Z\n'.format(datetime.utcnow()))

    user_cache = {}
    node_cache = {}
    location_cache = {}

    linenum = 0
    tally = {'missing_user': 0, 'missing_node': 0}
    for pageview_json in input_file.readlines():
        linenum += 1
        if not linenum % 1000:
            print('Transforming line {}'.format(linenum))

        raw_pageview = json.loads(pageview_json)
        visit = raw_pageview['visit']
        action = raw_pageview['action']

        location = None
        ip_addr = visit['ip_addr']
        if ip_addr is not None:
            if not location_cache.has_key(ip_addr):
                location_cache[ip_addr] = geolite2.lookup(ip_addr)

            location = location_cache[ip_addr]

        session_id = str(uuid.uuid4())
        keen_id = get_or_create_keen_id(visit['visitor_id'], sqlite_db)

        user_id = visit['user_id']
        if user_id is not None:
            if not user_cache.has_key(user_id):
                user_obj = User.load(user_id)
                user_cache[user_id] = {
                    'anon': md5(session_id).hexdigest(),
                    'entry_point': None if user_obj is None else get_entry_point(user_obj)
                }

            anon_id = user_cache[user_id]['anon']
            user_entry_point = user_cache[user_id]['entry_point']

        node = None
        node_id = action['node_id']
        if node_id is not None:
            if not node_cache.has_key(node_id):
                node_cache[node_id] = Node.load(node_id)
            node = node_cache[node_id]

        browser_version = [None, None]
        if visit['ua']['browser']['version']:
            browser_version = visit['ua']['browser']['version'].split('.')

        browser_info = {
            'device': {
                'family': visit['ua']['device'],
            },
            'os': {
                'major': None,
                'patch_minor': None,
                'minor': None,
                'family': parse_os_family(visit['ua']['os']),
                'patch': None,
            },
            'browser': {
                'major': browser_version[0],
                'minor': browser_version[1],
                'family': parse_browser_family(visit['ua']['browser']['name']),
                'patch': None,
            },
        }

        node_tags = action['node_tags'] or ''

        # piwik stores resolution as 1900x600 mostly, but sometimes as a float?
        # For the sake of my sanity and yours, let's ignore floats.
        screen_resolution = (None, None)
        if re.search('x', visit['ua']['screen']):
            screen_resolution = visit['ua']['screen'].split('x')

        pageview = {
            'page': {
                'title': action['page']['title'],
                'url': action['page']['url_prefix'] + action['page']['url'],
                'info': {}  # (add-on)
            },
            'referrer': {
                'url': action['referrer'] or None,
                'info': {}, # (add-on)
            },
            'tech': {
                'browser': {  # JS-side will be filled in by Keen.helpers.getBrowserProfile()
                    'cookies': True if visit['ua']['browser']['cookies'] else False,
                    'screen': {
                        'height': screen_resolution[1],
                        'width': screen_resolution[0],
                    },
                },
                'ip': ip_addr,  # private
                'ua': None,
                'info': browser_info,
            },
            'time': {
                'utc': parse_server_time(action['timestamp']),
                'local': {}
            },
            'visitor': {
                'id': keen_id,
                'session': session_id,  # random val (sessionId)
                'returning': True if visit['visitor_returning'] else False,  # visit
            },
            'user': {
                'id': user_id,
                'entry_point': user_entry_point,
            },
            'node': {
                'id': node_id,
                'title': getattr(node, 'title', None),
                'type': getattr(node, 'category', None),
                'tags': [tag for tag in node_tags.split(',')]
            },
            'geo': {},
            'anon': {
                'id': anon_id,
                'continent': getattr(location, 'continent', None),
                'country': getattr(location, 'country', None),
                'latitude': getattr(location, 'location', (None, None))[0],
                'longitude': getattr(location, 'location', (None, None))[1],
            },
            'keen': {
                'timestamp': action['timestamp'],
                'addons': [
                    {
                        'name': 'keen:referrer_parser',
                        'input': {
                            'referrer_url': 'referrer.url',
                            'page_url': 'page.url'
                        },
                        'output': 'referrer.info'
                    },
                    {
                        'name': 'keen:url_parser',
                        'input': {
                            'url': 'page.url'
                        },
                        'output': 'page.info'
                    },
                    {
                        'name': 'keen:url_parser',
                        'input': {
                            'url': 'referrer.url'
                        },
                        'output': 'referrer.info'
                    },
                    {  # private
                        'name': 'keen:ip_to_geo',
                        'input': {
                            'ip': 'tech.ip'
                        },
                        'output': 'geo',
                    }
                ],
            }
        }

        if node_id is None:
            tally['missing_node'] += 1

        if user_id is None:
            tally['missing_user'] += 1

        output_file.write(json.dumps(pageview) + '\n')

    history_file.write('Finished extraction at: {}Z\n'.format(datetime.utcnow()))
    history_file.write('Final count was: {}\n'.format(linenum))
    history_file.write('{} pageviews lacked a user id.\n'.format(tally['missing_user']))
    history_file.write('{} pageviews lacked a node id.\n'.format(tally['missing_node']))
    sqlite_db.close()

def sqlite_setup(sqlite_db):
    """Test whether we already have an sqlite db for mapping Piwik user_ids to new keen ids,
    and if not create one.
    :return:
    """
    cursor = sqlite_db.cursor()

    try:
        cursor.execute('SELECT COUNT(*) FROM matched_ids')
    except sqlite3.OperationalError:
        cursor.execute('CREATE TABLE matched_ids (piwik_id TEXT, keen_id TEXT)')
        sqlite_db.commit()

def get_or_create_keen_id(user_id, sqlite_db):
    """Gets or creates a new Keen Id given a Piwik User Id from the db

    :param user_id: Piwik User Id from current row in database
    :param sqlite_db: SQLite3 database handle
    :return: Keen Id as str
    """
    cursor = sqlite_db.cursor()
    query = "SELECT * FROM matched_ids WHERE piwik_id='{p_id}'".format(p_id=user_id)
    cursor.execute(query)

    keen_id = cursor.fetchall()

    if len(keen_id) > 1:
        raise Exception("Multiple ID's found for single Piwik User ID")

    if not keen_id:
        keen_id = uuid.uuid4()
        query = "INSERT INTO matched_ids (piwik_id, keen_id) VALUES ('{p_id}', '{n_id}');".format(
            p_id=str(user_id), n_id=str(keen_id)
        )
        cursor.execute(query)
        sqlite_db.commit()
        return str(keen_id)

    return str(keen_id[0][1])

def parse_os_family(os_key):
    """Attempts to parse Piwik OS key codes into corresponding OS names

    :param os_name: Operating System keycode
    :return: Operating System name
    """

    if os_key in lookup_data.legacy_os_keys:
        os_key = lookup_data.legacy_os_keys[os_key]

    return lookup_data.os_keys.get(os_key, 'Unknown')

def parse_browser_family(browser_key):
    """Attempts to parse Piwik browser key codes into corresponding browser names

    :param browser_key: Browser keycode
    :return: Browser name
    """
    return lookup_data.browser_keys.get(browser_key, 'Unknown')

def parse_server_time(server_time):
    timestamp = datetime.strptime(server_time, '%Y-%m-%d %H:%M:%S')
    return {
        'hour_of_day': timestamp.hour,
        'day_of_week': timestamp.isoweekday(),
        'day_of_month': timestamp.day,
        'month': timestamp.month,
        'year': timestamp.year,
    }

if __name__ == "__main__":
    init_app(set_backends=True, routes=False)
    main()
<|endoftext|>


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

from django.views.generic import View
from django import http
from django.template import RequestContext, loader
from django.shortcuts import render_to_response

class GenericView(View):
    response_cls = http.HttpResponse
    content_type = "text/html"

    def init(self, *args, **kwargs):
        pass

    def get_context_data(self):
        context = {"view": self}
        context.update(self.kwargs)
        return context

    def dispatch(self, request, *args, **kwargs):
        self.init(request, *args, **kwargs)
        return super(GenericView, self).dispatch(request, *args, **kwargs)

    def render(self, template=None, context=None, data=None,
               response_cls=None, content_type=None):

        output_data = data or b""

        if template:
            _context = self.get_context_data()
            _context.update(context)

            context_instance = RequestContext(self.request)
            output_data = loader.render_to_string(
                                template, _context,
                                context_instance=context_instance)

        if content_type is None:
            content_type = self.content_type

        if not response_cls:
            response_cls = self.response_cls

        return response_cls(output_data, content_type=content_type)

class GenericTemplateView(GenericView):
    tmpl_name = None

    def get(self, request, *args, **kwargs):
        if self.tmpl_name is None:
            raise ValueError("tmpl_name attr must be a valid template name")
        return self.render(self.tmpl_name)
<commit_msg>Minor fixes.<commit_after># -*- coding: utf-8 -*-

from django.views.generic import View
from django.template import RequestContext, loader
from django.shortcuts import render_to_response

from .. import http

class GenericView(View):
    response_cls = http.HttpResponse
    content_type = "text/html"

    def init(self, *args, **kwargs):
        pass

    def get_context_data(self):
        context = {"view": self}
        context.update(self.kwargs)
        return context

    def dispatch(self, request, *args, **kwargs):
        self.init(request, *args, **kwargs)
        return super(GenericView, self).dispatch(request, *args, **kwargs)

    def render(self, template=None, context=None, data=None,
               response_cls=None, content_type=None):

        output_data = data or b""

        if template:
            _context = self.get_context_data()
            _context.update(context or {})

            context_instance = RequestContext(self.request)
            output_data = loader.render_to_string(
                                template, _context,
                                context_instance=context_instance)

        if content_type is None:
            content_type = self.content_type

        if not response_cls:
            response_cls = self.response_cls

        return response_cls(output_data, content_type=content_type)

class GenericTemplateView(GenericView):
    tmpl_name = None

    def get(self, request, *args, **kwargs):
        if self.tmpl_name is None:
            raise ValueError("tmpl_name attr must be a valid template name")
        return self.render(self.tmpl_name)
<|endoftext|>


<commit_before>import sys

class Node(object):
    def __init__(self):
        self.left = None
        self.right = None
        self.destination = None
        self.gateway = None
        self.interface = None

if __name__ == '__main__':
    with open('routes.txt') as r:
        routeslines = r.readlines()

    routes = []
    routesbinary = []
    for line in routeslines:
        routes.append(line.split())

    root = Node()
    cNode = root
    temp = []
    for val in routes:
        temp = val[0].split("/")
        temp = temp[0].split(".")
        tempstring = ''
        for value in temp:
            binarystring = "{0:b}".format(int(value))
            while(len(binarystring) != 4):
                binarystring = "0" + binarystring
            tempstring = tempstring + binarystring

        for i in tempstring:
            if(i == '0'):
                if(cNode.left == None):
                    cNode.left = Node()
                    cNode.left.destination = val[0]
                    cNode.left.gateway = val[1]
                    cNode.left.interface = val[2]
                    break
                else:
                    cNode = cNode.left
            else:
                if(cNode.right == None):
                    cNode.right = Node()
                    cNode.right.destination = val[0]
                    cNode.right.gateway = val[1]
                    cNode.right.interface = val[2]
                    break
                else:
                    cNode = cNode.right

    arp = {}
    with open('arp.txt') as arptxt:
        for line in arptxt:
            arp[line.split(" ")[0]] = line.split(" ")[1]

    while True:
        inp = raw_input("Enter PDU: \n")   # Get the input
        if inp == "":       # If it is a blank line...
            break           # ...break the loop
        temp = inp.split(" ")
        print temp
        if (len(temp) != 7):
            break
        interface = temp[0]
        src = temp[1]
        dest = temp[2]
        protocol = temp[3]
        ttl = int(temp[4])
        srcport = temp[5]
        destport = temp[6]
        if (ttl < 1):
            print (src + "->" + dest + " discarded (TTL expired)")
        tempstring = ''
        temp = dest[0].split("/")
        temp = temp[0].split(".")
        for value in temp:
            binarystring = "{0:b}".format(int(value))
            while(len(binarystring) != 4):
                binarystring = "0" + binarystring
            tempstring = tempstring + binarystring
        cnode = root
        for i in tempstring:
            if(i == '0'):
                if(cNode.left == None):
                    break
                else:
                    cNode = cNode.left
            else:
                if(cNode.right == None):
                    break
                else:
                    cNode = cNode.right
        #if direct point to point
        if (cNode.gateway == "0.0.0.0" and cNode.destination.split("/")[1] == 32):
                #arp lookup
                if (arp[dest]):
                    print (src + ":" + srcport + "->" + dest + ":" + destport + " via " + cNode.gateway + "(" + interface + "-" + arp[dest] +") ttl " + str(ttl - 1))
                else:
                    print (src + "->" + dest + " discarded (destination unreachable)")
        else:
            #routing table lookup
            print (src + ":" + srcport + "->" + dest + ":" + destport + " via " + cNode.gateway + "(" + cNode.interface  +") ttl " + str(ttl - 1))
<commit_msg>fixed ttl<commit_after>import sys

class Node(object):
    def __init__(self):
        self.left = None
        self.right = None
        self.destination = None
        self.gateway = None
        self.interface = None

if __name__ == '__main__':
    with open('routes.txt') as r:
        routeslines = r.readlines()

    routes = []
    routesbinary = []
    for line in routeslines:
        routes.append(line.split())

    root = Node()
    cNode = root
    temp = []
    for val in routes:
        temp = val[0].split("/")
        temp = temp[0].split(".")
        tempstring = ''
        for value in temp:
            binarystring = "{0:b}".format(int(value))
            while(len(binarystring) != 4):
                binarystring = "0" + binarystring
            tempstring = tempstring + binarystring

        for i in tempstring:
            if(i == '0'):
                if(cNode.left == None):
                    cNode.left = Node()
                    cNode.left.destination = val[0]
                    cNode.left.gateway = val[1]
                    cNode.left.interface = val[2]
                    break
                else:
                    cNode = cNode.left
            else:
                if(cNode.right == None):
                    cNode.right = Node()
                    cNode.right.destination = val[0]
                    cNode.right.gateway = val[1]
                    cNode.right.interface = val[2]
                    break
                else:
                    cNode = cNode.right

    arp = {}
    with open('arp.txt') as arptxt:
        for line in arptxt:
            arp[line.split(" ")[0]] = line.split(" ")[1]

    while True:
        inp = raw_input("Enter PDU: \n")   # Get the input
        if inp == "":       # If it is a blank line...
            break           # ...break the loop
        temp = inp.split(" ")
        print temp
        if (len(temp) != 7):
            break
        interface = temp[0]
        src = temp[1]
        dest = temp[2]
        protocol = temp[3]
        ttl = int(temp[4])
        srcport = temp[5]
        destport = temp[6]
        if (ttl <= 1):
            print (src + "->" + dest + " discarded (TTL expired)")
        tempstring = ''
        temp = dest[0].split("/")
        temp = temp[0].split(".")
        for value in temp:
            binarystring = "{0:b}".format(int(value))
            while(len(binarystring) != 4):
                binarystring = "0" + binarystring
            tempstring = tempstring + binarystring
        cnode = root
        for i in tempstring:
            if(i == '0'):
                if(cNode.left == None):
                    break
                else:
                    cNode = cNode.left
            else:
                if(cNode.right == None):
                    break
                else:
                    cNode = cNode.right
        #if direct point to point
        if (cNode.gateway == "0.0.0.0" and cNode.destination.split("/")[1] == 32):
                #arp lookup
                if (arp[dest]):
                    print (src + ":" + srcport + "->" + dest + ":" + destport + " via " + cNode.gateway + "(" + interface + "-" + arp[dest] +") ttl " + str(ttl - 1))
                else:
                    print (src + "->" + dest + " discarded (destination unreachable)")
        else:
            #routing table lookup
            print (src + ":" + srcport + "->" + dest + ":" + destport + " via " + cNode.gateway + "(" + cNode.interface  +") ttl " + str(ttl - 1))
<|endoftext|>