<commit_before>from flask import render_template, request
from . import main
from ..models import Resource
import json

@main.route('/')
def index():
    return render_template('main/index.html')

@main.route('/get-resources')
def get_resources():
    resources = Resource.query.all()
    resources_as_dicts = Resource.get_resources_as_dicts(resources)
    return json.dumps(resources_as_dicts)

@main.route('/get-associations/<int:resource_id>')
def get_associations(resource_id):
    resource = Resource.query.get(resource_id)
    associations = {}
    if resource is None: return json.dumps(associations)
    for descriptor in resource.text_descriptors:
        associations[descriptor.descriptor.name] = descriptor.text
    for descriptor in resource.option_descriptors:
        associations[descriptor.descriptor.name] = descriptor.descriptor.values[
            descriptor.option]
    return json.dumps(associations)

<commit_msg>small style fix<commit_after>from flask import render_template
from . import main
from ..models import Resource
import json

@main.route('/')
def index():
    return render_template('main/index.html')

@main.route('/get-resources')
def get_resources():
    resources = Resource.query.all()
    resources_as_dicts = Resource.get_resources_as_dicts(resources)
    return json.dumps(resources_as_dicts)

@main.route('/get-associations/<int:resource_id>')
def get_associations(resource_id):
    resource = Resource.query.get(resource_id)
    associations = {}
    if resource is None:
        return json.dumps(associations)
    for td in resource.text_descriptors:
        associations[td.descriptor.name] = td.text
    for od in resource.option_descriptors:
        associations[od.descriptor.name] = od.descriptor.values[od.option]
    return json.dumps(associations)
<|endoftext|>


<commit_before>#!/usr/bin/env python3.6
"""
Copyright (c) 2014-2016, GhostBSD. 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. Redistribution's of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistribution's 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.
"""

from subprocess import Popen, PIPE, call
from sys import path
import os.path
import re
from time import sleep

path.append("/usr/local/share/networkmgr")
ncard = 'ifconfig -l'
notnics = ["lo", "fwe", "fwip", "tap", "plip", "pfsync", "pflog",
           "tun", "sl", "faith", "ppp", "brige", "ixautomation"]

if os.path.exists("/sbin/openrc") is True:
    openrc = True
else:
    openrc = False

def scanWifiBssid(bssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep -a %s" % (wificard, bssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()[0].rstrip()
    return info

def ifnetworkup():
    pass

def wlan_list():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    wlanlist = []
    for wlan in crd.stdout.readlines()[0].rstrip().split(' '):
        if "wlan" in wlan:
            wlanlist.append(wlan)
    return wlanlist

def wired_list():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    wiredlist = []
    for wiredcn in crd.stdout.readlines()[0].rstrip().split(' '):
        wnc = wiredcn
        wcardn = re.sub(r'\d+', '', wiredcn)
        if wcardn not in notnics:
            wiredlist.append(wnc)
    return wiredlist

def ifwificardadded():
    wifis = 'sysctl -in net.wlan.devices'
    wifinics = Popen(wifis, shell=True, stdout=PIPE, universal_newlines=True)
    wifiscards = wifinics.stdout.readlines()
    answer = False
    if len(wifiscards) != 0:
        ifwifi = wifiscards[0].rstrip()
        rc_conf = open('/etc/rc.conf', 'r').read()
        wificardlist = ifwifi.split()
        for wfcard in wificardlist:
            if 'wlans_%s=' % wfcard not in rc_conf:
                answer = True
                break
    return answer

def ifwiredcardadded():
    cardlist = wired_list()
    answer = False
    if len(cardlist) != 0:
        rc_conf = open('/etc/rc.conf', 'r').read()
        for card in cardlist:
            if 'ifconfig_%s=' % card not in rc_conf:
                answer = True
                break
    return answer

def isanewnetworkcardinstall():
    if ifwificardadded() is True or ifwiredcardadded() is True:
        return True
    else:
        return False

def bssidsn(bssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep -a %s" % (wificard, bssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()
    if len(info) == 0:
        return 0
    else:
        newline = info[0][33:]
        bssidlist = newline.split(' ')
        bssidlist = list(filter(None, bssidlist))
        return barpercent(bssidlist[3])

def scanSsid(ssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep %s" % (wificard, ssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()[0].rstrip().split(' ')
    info = list(filter(None, info))
    return info

def wiredonlineinfo():
    for netcard in wired_list():
        lan = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                    universal_newlines=True)
        if 'inet ' in lan.stdout.read():
            isonlin = True
            break
        else:
            isonlin = False
    return isonlin

def ifcardisonline(netcard):
    lan = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                universal_newlines=True)
    if 'inet ' in lan.stdout.read():
        return True
    else:
        return False

def ifWlanInRc():
    rc_conf = open('/etc/rc.conf', 'r').read()
    if 'wlan' in rc_conf:
        return True
    else:
        return False

def ifWlan():
    nics = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    if "wlan" in nics.stdout.read():
        return True
    else:
        return False

def defaultcard():
    cmd = "netstat -r | grep default"
    nics = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    device = nics.stdout.readlines()
    if len(device) == 0:
        return None
    else:
        return list(filter(None, device[0].rstrip().split()))[3]

def ifWlanDisable(wificard):
    cmd = "ifconfig %s list scan" % wificard
    nics = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    if "" == nics.stdout.read():
        return True
    else:
        return False

def ifStatue(wificard):
    cmd = "ifconfig %s" % wificard
    wl = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    wlout = wl.stdout.read()
    if "associated" in wlout:
        return True
    else:
        return False

def get_ssid(wificard):
    wlan = Popen('ifconfig %s | grep ssid' % wificard,
                 shell=True, stdout=PIPE, universal_newlines=True)
    return wlan.stdout.readlines()[0].rstrip().split()[1]

def get_bssid(wificard):
    wlan = Popen('ifconfig -v %s | grep bssid' % wificard,
                 shell=True, stdout=PIPE, universal_newlines=True)
    return wlan.stdout.readlines()[0].rstrip().split()[-1]

def networklist():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    devicelist = []
    for deviced in crd.stdout.readlines()[0].rstrip().split(' '):
        ndev = deviced
        card = re.sub(r'\d+', '', deviced)
        if card not in notnics:
            devicelist.append(ndev)
    return devicelist

def ifcardconnected(netcard):
    wifi = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                 universal_newlines=True)
    if 'status: active' in wifi.stdout.read():
        return True
    else:
        return False

def barpercent(sn):
    sig = int(sn.partition(':')[0])
    noise = int(sn.partition(':')[2])
    return int((sig - noise) * 4)

def networkdictionary():
    nlist = networklist()
    maindictionary = {}
    for card in nlist:
        if 'wlan' in card:
            scanv = "ifconfig -v %s list scan | grep -va BSSID" % card
            wifi = Popen(scanv, shell=True, stdout=PIPE,
                         universal_newlines=True)
            connectioninfo = {}
            for line in wifi.stdout:
                if line[0] == " ":
                    ssid = "Unknown"
                    newline = line[:83]
                else:
                    ssid = line[:33].strip()
                    newline = line[:83].strip()
                info = newline[33:].split(' ')
                info = list(filter(None, info))
                sn = info[3]
                bssid = info[0]
                info[3] = barpercent(sn)
                info.insert(0, ssid)
                connectioninfo[bssid] = info
            if ifWlanDisable(card) is True:
                connectionstat = {
                    "connection": "Disabled",
                    "ssid": None, "bssid": None
                }
            elif ifStatue(card) is False:
                connectionstat = {
                    "connection": "Disconnected",
                    "ssid": None, "bssid": None
                }
            else:
                ssid = get_ssid(card)
                bssid = get_bssid(card)
                connectionstat = {
                    "connection": "Connected",
                    "ssid": ssid,
                    "bssid": bssid
                }
            seconddictionary = {
                'state': connectionstat,
                'info': connectioninfo
            }
        else:
            if ifcardisonline(card) is True:
                connectionstat = {"connection": "Connected"}
            elif ifcardconnected(card) is True:
                connectionstat = {"connection": "Disconnected"}
            else:
                connectionstat = {"connection": "Unplug"}
            seconddictionary = {'state': connectionstat, 'info': None}
        maindictionary[card] = seconddictionary
    return maindictionary

def card_service():
    service_list = []
    for card in wired_list():
        crd = Popen("rc-status | grep " + card, shell=True, stdout=PIPE,
                    universal_newlines=True)
        for service in crd.stdout.readlines():
            service_list.append(service.split()[0])
    return service_list

def stopallnetwork():
    if openrc is True:
        for service in card_service():
            call('doas service %s stop' % service, shell=True)
            sleep(1)
        call('doas service network stop', shell=True)
    else:
        call('doas service netif stop', shell=True)
    sleep(1)

def startallnetwork():
    if openrc is True:
        call('doas service network start', shell=True)
    else:
        call('doas service netif start', shell=True)
    sleep(1)

def restartnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s restart' % netcard, shell=True)
    else:
        call('doas service netif restart %s' % netcard, shell=True)
    sleep(1)

def stopnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s stop' % netcard, shell=True)
    else:
        call('doas service netif stop %s' % netcard, shell=True)
    sleep(1)

def startnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s start' % netcard, shell=True)
    else:
        call('doas service netif start %s' % netcard, shell=True)
        sleep(1)

def wifiDisconnection(wificard):
    if openrc is True:
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s down' % wificard, shell=True)
    if openrc is True:
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    sleep(1)

def disableWifi(wificard):
    if openrc is True:
        call('doas service dhcpcd.%s stop' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s down' % wificard, shell=True)
    sleep(1)

def enableWifi(wificard):
    if openrc is True:
        call('doas service dhcpcd.%s restart' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s restart' % wificard, shell=True)
    else:
        call('doas service wpa_supplicant restart %s' % wificard, shell=True)
    sleep(1)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    sleep(1)

def connectToSsid(name, wificard):
    # call('doas service netif restart wlan0', shell=True
    call("doas ifconfig %s ssid '%s'" % (wificard, name), shell=True)
    if openrc is True:
        call('doas service dhcpcd.%s restart' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s restart' % wificard, shell=True)
    else:
        call('doas service netif restart %s' % wificard, shell=True)
    sleep(1)

def connectionStatus(card):
    if card is None:
        netstate = "All network cards disalble"
    elif 'wlan' in card:
        if ifWlanDisable(card) is False and ifStatue(card) is True:
            cmd1 = "ifconfig %s | grep ssid" % card
            cmd2 = "ifconfig %s | grep 'inet '" % card
            out1 = Popen(cmd1, shell=True, stdout=PIPE,
                         universal_newlines=True)
            out2 = Popen(cmd2, shell=True, stdout=PIPE,
                         universal_newlines=True)
            line1 = out1.stdout.read().strip()
            line2 = out2.stdout.read().strip()
            netstate = line1 + '\n' + line2
        else:
            netstate = "WiFi %s not conected" % card
    else:
        cmd = "ifconfig %s | grep 'inet '" % card
        out = Popen(cmd, shell=True, stdout=PIPE,
                    universal_newlines=True)
        line = out.stdout.read().strip()
        netstate = line
    return netstate
<commit_msg>Corrected misspelling.<commit_after>#!/usr/bin/env python3.6
"""
Copyright (c) 2014-2016, GhostBSD. 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. Redistribution's of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistribution's 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.
"""

from subprocess import Popen, PIPE, call
from sys import path
import os.path
import re
from time import sleep

path.append("/usr/local/share/networkmgr")
ncard = 'ifconfig -l'
notnics = ["lo", "fwe", "fwip", "tap", "plip", "pfsync", "pflog",
           "tun", "sl", "faith", "ppp", "brige", "ixautomation"]

if os.path.exists("/sbin/openrc") is True:
    openrc = True
else:
    openrc = False

def scanWifiBssid(bssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep -a %s" % (wificard, bssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()[0].rstrip()
    return info

def ifnetworkup():
    pass

def wlan_list():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    wlanlist = []
    for wlan in crd.stdout.readlines()[0].rstrip().split(' '):
        if "wlan" in wlan:
            wlanlist.append(wlan)
    return wlanlist

def wired_list():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    wiredlist = []
    for wiredcn in crd.stdout.readlines()[0].rstrip().split(' '):
        wnc = wiredcn
        wcardn = re.sub(r'\d+', '', wiredcn)
        if wcardn not in notnics:
            wiredlist.append(wnc)
    return wiredlist

def ifwificardadded():
    wifis = 'sysctl -in net.wlan.devices'
    wifinics = Popen(wifis, shell=True, stdout=PIPE, universal_newlines=True)
    wifiscards = wifinics.stdout.readlines()
    answer = False
    if len(wifiscards) != 0:
        ifwifi = wifiscards[0].rstrip()
        rc_conf = open('/etc/rc.conf', 'r').read()
        wificardlist = ifwifi.split()
        for wfcard in wificardlist:
            if 'wlans_%s=' % wfcard not in rc_conf:
                answer = True
                break
    return answer

def ifwiredcardadded():
    cardlist = wired_list()
    answer = False
    if len(cardlist) != 0:
        rc_conf = open('/etc/rc.conf', 'r').read()
        for card in cardlist:
            if 'ifconfig_%s=' % card not in rc_conf:
                answer = True
                break
    return answer

def isanewnetworkcardinstall():
    if ifwificardadded() is True or ifwiredcardadded() is True:
        return True
    else:
        return False

def bssidsn(bssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep -a %s" % (wificard, bssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()
    if len(info) == 0:
        return 0
    else:
        newline = info[0][33:]
        bssidlist = newline.split(' ')
        bssidlist = list(filter(None, bssidlist))
        return barpercent(bssidlist[3])

def scanSsid(ssid, wificard):
    grepListScanv = "ifconfig -v %s list scan | grep %s" % (wificard, ssid)
    wifi = Popen(grepListScanv, shell=True, stdout=PIPE,
                 universal_newlines=True)
    info = wifi.stdout.readlines()[0].rstrip().split(' ')
    info = list(filter(None, info))
    return info

def wiredonlineinfo():
    for netcard in wired_list():
        lan = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                    universal_newlines=True)
        if 'inet ' in lan.stdout.read():
            isonlin = True
            break
        else:
            isonlin = False
    return isonlin

def ifcardisonline(netcard):
    lan = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                universal_newlines=True)
    if 'inet ' in lan.stdout.read():
        return True
    else:
        return False

def ifWlanInRc():
    rc_conf = open('/etc/rc.conf', 'r').read()
    if 'wlan' in rc_conf:
        return True
    else:
        return False

def ifWlan():
    nics = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    if "wlan" in nics.stdout.read():
        return True
    else:
        return False

def defaultcard():
    cmd = "netstat -r | grep default"
    nics = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    device = nics.stdout.readlines()
    if len(device) == 0:
        return None
    else:
        return list(filter(None, device[0].rstrip().split()))[3]

def ifWlanDisable(wificard):
    cmd = "ifconfig %s list scan" % wificard
    nics = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    if "" == nics.stdout.read():
        return True
    else:
        return False

def ifStatue(wificard):
    cmd = "ifconfig %s" % wificard
    wl = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    wlout = wl.stdout.read()
    if "associated" in wlout:
        return True
    else:
        return False

def get_ssid(wificard):
    wlan = Popen('ifconfig %s | grep ssid' % wificard,
                 shell=True, stdout=PIPE, universal_newlines=True)
    return wlan.stdout.readlines()[0].rstrip().split()[1]

def get_bssid(wificard):
    wlan = Popen('ifconfig -v %s | grep bssid' % wificard,
                 shell=True, stdout=PIPE, universal_newlines=True)
    return wlan.stdout.readlines()[0].rstrip().split()[-1]

def networklist():
    crd = Popen(ncard, shell=True, stdout=PIPE, universal_newlines=True)
    devicelist = []
    for deviced in crd.stdout.readlines()[0].rstrip().split(' '):
        ndev = deviced
        card = re.sub(r'\d+', '', deviced)
        if card not in notnics:
            devicelist.append(ndev)
    return devicelist

def ifcardconnected(netcard):
    wifi = Popen('ifconfig ' + netcard, shell=True, stdout=PIPE,
                 universal_newlines=True)
    if 'status: active' in wifi.stdout.read():
        return True
    else:
        return False

def barpercent(sn):
    sig = int(sn.partition(':')[0])
    noise = int(sn.partition(':')[2])
    return int((sig - noise) * 4)

def networkdictionary():
    nlist = networklist()
    maindictionary = {}
    for card in nlist:
        if 'wlan' in card:
            scanv = "ifconfig -v %s list scan | grep -va BSSID" % card
            wifi = Popen(scanv, shell=True, stdout=PIPE,
                         universal_newlines=True)
            connectioninfo = {}
            for line in wifi.stdout:
                if line[0] == " ":
                    ssid = "Unknown"
                    newline = line[:83]
                else:
                    ssid = line[:33].strip()
                    newline = line[:83].strip()
                info = newline[33:].split(' ')
                info = list(filter(None, info))
                sn = info[3]
                bssid = info[0]
                info[3] = barpercent(sn)
                info.insert(0, ssid)
                connectioninfo[bssid] = info
            if ifWlanDisable(card) is True:
                connectionstat = {
                    "connection": "Disabled",
                    "ssid": None, "bssid": None
                }
            elif ifStatue(card) is False:
                connectionstat = {
                    "connection": "Disconnected",
                    "ssid": None, "bssid": None
                }
            else:
                ssid = get_ssid(card)
                bssid = get_bssid(card)
                connectionstat = {
                    "connection": "Connected",
                    "ssid": ssid,
                    "bssid": bssid
                }
            seconddictionary = {
                'state': connectionstat,
                'info': connectioninfo
            }
        else:
            if ifcardisonline(card) is True:
                connectionstat = {"connection": "Connected"}
            elif ifcardconnected(card) is True:
                connectionstat = {"connection": "Disconnected"}
            else:
                connectionstat = {"connection": "Unplug"}
            seconddictionary = {'state': connectionstat, 'info': None}
        maindictionary[card] = seconddictionary
    return maindictionary

def card_service():
    service_list = []
    for card in wired_list():
        crd = Popen("rc-status | grep " + card, shell=True, stdout=PIPE,
                    universal_newlines=True)
        for service in crd.stdout.readlines():
            service_list.append(service.split()[0])
    return service_list

def stopallnetwork():
    if openrc is True:
        for service in card_service():
            call('doas service %s stop' % service, shell=True)
            sleep(1)
        call('doas service network stop', shell=True)
    else:
        call('doas service netif stop', shell=True)
    sleep(1)

def startallnetwork():
    if openrc is True:
        call('doas service network start', shell=True)
    else:
        call('doas service netif start', shell=True)
    sleep(1)

def restartnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s restart' % netcard, shell=True)
    else:
        call('doas service netif restart %s' % netcard, shell=True)
    sleep(1)

def stopnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s stop' % netcard, shell=True)
    else:
        call('doas service netif stop %s' % netcard, shell=True)
    sleep(1)

def startnetworkcard(netcard):
    if openrc is True:
        call('doas service dhcpcd.%s start' % netcard, shell=True)
    else:
        call('doas service netif start %s' % netcard, shell=True)
        sleep(1)

def wifiDisconnection(wificard):
    if openrc is True:
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s down' % wificard, shell=True)
    if openrc is True:
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    sleep(1)

def disableWifi(wificard):
    if openrc is True:
        call('doas service dhcpcd.%s stop' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s stop' % wificard, shell=True)
        sleep(1)
    call('doas ifconfig %s down' % wificard, shell=True)
    sleep(1)

def enableWifi(wificard):
    if openrc is True:
        call('doas service dhcpcd.%s restart' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s restart' % wificard, shell=True)
    else:
        call('doas service wpa_supplicant restart %s' % wificard, shell=True)
    sleep(1)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    call('doas ifconfig %s up scan' % wificard, shell=True)
    sleep(1)

def connectToSsid(name, wificard):
    # call('doas service netif restart wlan0', shell=True
    call("doas ifconfig %s ssid '%s'" % (wificard, name), shell=True)
    if openrc is True:
        call('doas service dhcpcd.%s restart' % wificard, shell=True)
        sleep(1)
        call('doas service wpa_supplicant.%s restart' % wificard, shell=True)
    else:
        call('doas service netif restart %s' % wificard, shell=True)
    sleep(1)

def connectionStatus(card):
    if card is None:
        netstate = "All network cards disable"
    elif 'wlan' in card:
        if ifWlanDisable(card) is False and ifStatue(card) is True:
            cmd1 = "ifconfig %s | grep ssid" % card
            cmd2 = "ifconfig %s | grep 'inet '" % card
            out1 = Popen(cmd1, shell=True, stdout=PIPE,
                         universal_newlines=True)
            out2 = Popen(cmd2, shell=True, stdout=PIPE,
                         universal_newlines=True)
            line1 = out1.stdout.read().strip()
            line2 = out2.stdout.read().strip()
            netstate = line1 + '\n' + line2
        else:
            netstate = "WiFi %s not conected" % card
    else:
        cmd = "ifconfig %s | grep 'inet '" % card
        out = Popen(cmd, shell=True, stdout=PIPE,
                    universal_newlines=True)
        line = out.stdout.read().strip()
        netstate = line
    return netstate
<|endoftext|>


<commit_before>from __future__ import unicode_literals

import logging
import os

from mopidy import config, ext
from mopidy.config import Deprecated

from pandora import BaseAPIClient

__version__ = '0.1.6'

logger = logging.getLogger(__name__)

class Extension(ext.Extension):

    dist_name = 'Mopidy-Pandora'
    ext_name = 'pandora'
    version = __version__

    def get_default_config(self):
        conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf')
        return config.read(conf_file)

    def get_config_schema(self):
        schema = super(Extension, self).get_config_schema()
        schema['api_host'] = config.String(optional=True)
        schema['partner_encryption_key'] = config.String()
        schema['partner_decryption_key'] = config.String()
        schema['partner_username'] = config.String()
        schema['partner_password'] = config.String()
        schema['partner_device'] = config.String()
        schema['username'] = config.String()
        schema['password'] = config.Secret()
        schema['preferred_audio_quality'] = config.String(optional=True, choices=[BaseAPIClient.LOW_AUDIO_QUALITY,
                                                                                BaseAPIClient.MED_AUDIO_QUALITY,
                                                                                BaseAPIClient.HIGH_AUDIO_QUALITY])
        schema['sort_order'] = config.String(optional=True, choices=['date', 'A-Z', 'a-z'])
        schema['auto_setup'] = config.Boolean()
        schema['auto_set_repeat'] = Deprecated()
        schema['event_support_enabled'] = config.Boolean()
        schema['double_click_interval'] = config.String()
        schema['on_pause_resume_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        schema['on_pause_next_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        schema['on_pause_previous_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        return schema

    def setup(self, registry):
        from .backend import PandoraBackend
        registry.add('backend', PandoraBackend)
<commit_msg>Update version number.<commit_after>from __future__ import unicode_literals

import logging
import os

from mopidy import config, ext
from mopidy.config import Deprecated

from pandora import BaseAPIClient

__version__ = '0.1.7'

logger = logging.getLogger(__name__)

class Extension(ext.Extension):

    dist_name = 'Mopidy-Pandora'
    ext_name = 'pandora'
    version = __version__

    def get_default_config(self):
        conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf')
        return config.read(conf_file)

    def get_config_schema(self):
        schema = super(Extension, self).get_config_schema()
        schema['api_host'] = config.String(optional=True)
        schema['partner_encryption_key'] = config.String()
        schema['partner_decryption_key'] = config.String()
        schema['partner_username'] = config.String()
        schema['partner_password'] = config.String()
        schema['partner_device'] = config.String()
        schema['username'] = config.String()
        schema['password'] = config.Secret()
        schema['preferred_audio_quality'] = config.String(optional=True, choices=[BaseAPIClient.LOW_AUDIO_QUALITY,
                                                                                BaseAPIClient.MED_AUDIO_QUALITY,
                                                                                BaseAPIClient.HIGH_AUDIO_QUALITY])
        schema['sort_order'] = config.String(optional=True, choices=['date', 'A-Z', 'a-z'])
        schema['auto_setup'] = config.Boolean()
        schema['auto_set_repeat'] = Deprecated()
        schema['event_support_enabled'] = config.Boolean()
        schema['double_click_interval'] = config.String()
        schema['on_pause_resume_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        schema['on_pause_next_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        schema['on_pause_previous_click'] = config.String(choices=['thumbs_up', 'thumbs_down', 'sleep'])
        return schema

    def setup(self, registry):
        from .backend import PandoraBackend
        registry.add('backend', PandoraBackend)
<|endoftext|>


<commit_before>"""
Copyright [2009-2019] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

# ----------------------------------------------------------------------------------

import os
import sys
import subprocess
import argparse

# ------------------------------------- GLOBALS ------------------------------------

LSF_GROUP = "/family_srch"
MEMORY = 8000
CPU = 8

# ----------------------------------------------------------------------------------

def checkout_family(rfam_acc):
    """
    Checks out a family from Rfam based on a valid Rfam accession.

    rfam_acc: A valid Rfam accession

    return: None
    """

    cmd = "rfco.pl %s" % rfam_acc

    subprocess.call(cmd, shell=True)

    # add some checks here

# ----------------------------------------------------------------------------------

def submit_new_rfsearch_job(family_dir):
    """
    Submits a new lsf job that runs rfsearch to update SCORES for a new release.
    If no threshold is set with rfsearch.pl, it uses existing thresholds by default.

    family_dir: The physical location of the family directory

    return: None
    """
    # use the pre-process command to change directory to family_dir

    lsf_err_file = os.path.join(family_dir, "auto_rfsearch.err")
    lsf_out_file = os.path.join(family_dir, "auto_rfsearch.out")

    cmd = ("bsub -M %s -R \"rusage[mem=%s]\" -o %s -e %s -n %s -g %s "
          "cd %s && rfsearch.pl -cnompi")

    print cmd % (MEMORY, MEMORY, lsf_out_file, lsf_err_file, CPU, LSF_GROUP, family_dir)
    subprocess.call(cmd % (MEMORY, MEMORY, lsf_out_file, lsf_err_file,
                         CPU, LSF_GROUP, family_dir), shell=True)

# ----------------------------------------------------------------------------------

def load_rfam_accessions_from_file(accession_list):
    """
    This function parses a .txt file containing Rfam accessions and returns those
    accession_list: This is a .txt file containing a list of Rfam accessions

    return: list of Rfam family accessions
    """

    fp = open(accession_list, 'r')

    accessions = [x.strip() for x in fp]

    fp.close()

    return accessions

# ----------------------------------------------------------------------------------

if __name__ == '__main__':

    # create a new argument parser object
    parser = argparse.ArgumentParser(description='Update scores for new release')

    # group required arguments together
    req_args = parser.add_argument_group("required arguments")
    req_args.add_argument('--dest_dir', help='destination directory where to checkout families',
                        type=str, required=True)

    parser.add_argument('-f', help='a file containing a list of Rfam family accessions', type=str)
    parser.add_argument('--all', help='runs rfsearch on all families', type=str)
    parser.add_argument('--acc', help="a valid rfam family accession RFXXXXX",
                        type=str, default=None)
    args = parser.parse_args()

    #if args.h:
    #    parser.print_help()

    if args.acc:
        if args.acc[0:2] == 'RF' and len(args.acc) == 7:
            os.chdir(args.dest_dir)
            family_dir = os.path.join(args.dest_dir, args.acc)

	    # checkout family if not done already
            if not os.path.exists(family_dir):
                checkout_family(args.acc)

            submit_new_rfsearch_job(family_dir)

    elif args.f:
	if not os.path.isfile(args.f):
		print "The file location you provided does not exist!\n"
	# move to destination directory
	os.chdir(args.dest_dir)
	accessions = load_rfam_accessions_from_file(args.f)

	for rfam_acc in accessions:
		# get location of family directory
		family_dir = os.path.join(args.dest_dir, rfam_acc)

		# checkout family if not done already
            	if not os.path.exists(family_dir):
                	checkout_family(rfam_acc)

		submit_new_rfsearch_job(family_dir)
<commit_msg>Resolves code duplicaton rfco/rfsearch<commit_after>"""
Copyright [2009-2019] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

# ----------------------------------------------------------------------------------

import os
import sys
import subprocess
import argparse

# ------------------------------------- GLOBALS ------------------------------------

LSF_GROUP = "/family_srch"
MEMORY = 8000
CPU = 8

# ----------------------------------------------------------------------------------

def checkout_family(rfam_acc):
    """
    Checks out a family from Rfam based on a valid Rfam accession.

    rfam_acc: A valid Rfam accession

    return: None
    """

    cmd = "rfco.pl %s" % rfam_acc

    subprocess.call(cmd, shell=True)

    # add some checks here

# ----------------------------------------------------------------------------------

def submit_new_rfsearch_job(family_dir):
    """
    Submits a new lsf job that runs rfsearch to update SCORES for a new release.
    If no threshold is set with rfsearch.pl, it uses existing thresholds by default.

    family_dir: The physical location of the family directory

    return: None
    """
    # use the pre-process command to change directory to family_dir

    lsf_err_file = os.path.join(family_dir, "auto_rfsearch.err")
    lsf_out_file = os.path.join(family_dir, "auto_rfsearch.out")

    cmd = ("bsub -M %s -R \"rusage[mem=%s]\" -o %s -e %s -n %s -g %s "
          "cd %s && rfsearch.pl -cnompi")

    print cmd % (MEMORY, MEMORY, lsf_out_file, lsf_err_file, CPU, LSF_GROUP, family_dir)
    subprocess.call(cmd % (MEMORY, MEMORY, lsf_out_file, lsf_err_file,
                         CPU, LSF_GROUP, family_dir), shell=True)

# ----------------------------------------------------------------------------------

def load_rfam_accessions_from_file(accession_list):
    """
    This function parses a .txt file containing Rfam accessions and returns those
    accession_list: This is a .txt file containing a list of Rfam accessions

    return: list of Rfam family accessions
    """

    fp = open(accession_list, 'r')

    accessions = [x.strip() for x in fp]

    fp.close()

    return accessions

# ----------------------------------------------------------------------------------

def checkout_and_search_family(rfam_acc, dest_dir):
	"""
	This function combines family checkout (rfco.pl) and re-scoring of hits
	using rfsearch.pl.

	rfam_acc: A valid Rfam family accession (RFXXXXX)
	dest_dir: A valid destination directory, where to checkout the family

	return: void
	"""

	# get family directory
	family_dir = os.path.join(dest_dir, rfam_acc)
	# checkout family if not done already
        if not os.path.exists(family_dir):
        	checkout_family(args.acc)

	submit_new_rfsearch_job(family_dir)

# ----------------------------------------------------------------------------------

if __name__ == '__main__':

    # create a new argument parser object
    parser = argparse.ArgumentParser(description='Update scores for new release')

    # group required arguments together
    req_args = parser.add_argument_group("required arguments")
    req_args.add_argument('--dest_dir', help='destination directory where to checkout families',
                        type=str, required=True)

    parser.add_argument('-f', help='a file containing a list of Rfam family accessions', type=str)
    parser.add_argument('--all', help='runs rfsearch on all families', type=str)
    parser.add_argument('--acc', help="a valid rfam family accession RFXXXXX",
                        type=str, default=None)
    args = parser.parse_args()

    #if args.h:
    #    parser.print_help()

    if args.acc:
        if args.acc[0:2] == 'RF' and len(args.acc) == 7:
            os.chdir(args.dest_dir)
   	    checkout_and_search_family(args.acc, args.dest_dir)

    elif args.f:
	if not os.path.isfile(args.f):
		print "The file location you provided does not exist!\n"
	# move to destination directory
	os.chdir(args.dest_dir)
	accessions = load_rfam_accessions_from_file(args.f)

	for rfam_acc in accessions:
		checkout_and_search_family(rfam_acc, args.dest_dir)

<|endoftext|>


<commit_before>import matplotlib.pyplot as plt
import seaborn
import pandas as pd
import os
import json

colours = seaborn.color_palette("deep", 8)
flags = ""

def loud() :
	flags += " -v -n"

def multicore(cores = 8) :
	flags += " -N %d" % cores

# Compile
def compile() :
	os.system("ssm")

# Simulate from current state
def sim(jsonfile = "mle", out = 0) :
	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Simulating from %s.json." % jsonfile
		os.system("cat ../%s.json | ./simul -N 8 -P .. --traj -I %d%s > /dev/null" % (jsonfile, out, flags))
	else :
		print "%s.json does not exist, simulating using theta.json."
		os.system("cat ../theta.json | ./simul -N 8 -P .. --traj%d%s > /dev/null" % (out, flags))

	os.chdir("..")

# Simplex
def simplex(runs = 10000) :
	os.chdir("bin")
	os.system("cat ../theta.json | ./simplex -M %d %s > mle.json" % (runs, flags))
	os.rename("mle.json", "../mle.json")
	os.chdir("..")

# Plot original data
def plotdata(show = True) :
	data = pd.read_csv("data/data.csv", parse_dates = True, index_col = "date")
	data.plot(legend = False)
	plt.xlabel("Time")
	plt.ylabel("Observed Cases")
	plt.title("Observed Data")
	if show :
		plt.show()

# Plot data and simulated trace
def plotsim(jsonfile = "theta") :
	sim(jsonfile)
	trace = pd.read_csv("X_0.csv", parse_dates = True, index_col = "date")
	plotdata(False)
	trace.plot(y="I", c = colours[2])
	plt.legend(["Observed data", "Simulated trace"])
	plt.show()

# Parameter evolutions
def plottrace() :
	"blah"

# Summarise parameters and model fits
def summary(jsonfile = "mle") :

	if os.path.isfile("%s.json" % jsonfile) :
		s = json.load(open("%s.json" % jsonfile))
	else :
		print "%s.json does not exist; summarising theta.json.\n" % jsonfile
		s = json.load(open("theta.json"))

	for key, value in s["resources"][0]["data"].items() :
		print("%s" % key + "\t" + "%s" % value).expandtabs(20)

# Particle MCMC
def pmcmc(steps = 100000, burn = 10000) :
	"blah"
<commit_msg>Blackbox<commit_after>import matplotlib.pyplot as plt
import seaborn
import pandas as pd
import os
import json

colours = seaborn.color_palette("deep", 8)
flags = ""

# TODO : Use varargout to control whether anything is returned

# Compile the model
def compile() :
	os.system("ssm")
	# TODO : add error checks; check through JSON files for syntax errors if compile fails
	# If none found, suggest the user cry a little

# Simulate from current state
def sim(jsonfile = "mle", out = 0) :

	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Simulating from %s.json." % jsonfile
		os.system("cat ../%s.json | ./simul -N 8 -P .. --traj -I %d > /dev/null" % (jsonfile, out))
	else :
		print "%s.json does not exist, simulating using theta.json."
		os.system("cat ../theta.json | ./simul -N 8 -P .. --traj -I %d > /dev/null" % (out))

	os.chdir("..")

	# TODO : look into stochastic simulations ( -J particles )
	# Create flags for turning off demographic stochasticity, white noises and diffusions

# Simplex
def simplex(steps = 10000, jsonfile = "mle") :
	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Simplex on %s.json, %d iterations." % (jsonfile, steps)
		os.system("cat ../%s.json | ./simplex -M %d > ../out.json" % (jsonfile, steps))

	else :
		print "%s.json does not exist; running Simplex on theta.json, %d iterations.\n" % (jsonfile, steps)
		os.system("cat ../theta.json | ./simplex -M %d > ../out.json" % (steps))

	os.rename("../out.json", "../mle.json")
	os.chdir("..")

	# TODO : Create flags for turning off demographic stochasticity, white noises and diffusions

# Plot original data
def plotdata(show = True) :
	data = pd.read_csv("data/data.csv", parse_dates = True, index_col = "date")
	data.plot(legend = False)
	plt.xlabel("Time")
	plt.ylabel("Observed Cases")
	plt.title("Observed Data")
	if show :
		plt.show()
	# TODO : return original data as a dataframe

# Plot data and simulated trace
def plotsim(jsonfile = "mle", trajfile = "X_0") :
	sim(jsonfile)
	traj = pd.read_csv("%s.csv" % trajfile, parse_dates = True, index_col = "date")
	plotdata(False)
	traj.plot(y = "I", c = colours[2])
	plt.legend(["Observed data", "Simulated trace"])
	plt.xlabel("Time")
	plt.show()
	# TODO : think about defaulting to jsonfile = pmcmc, or drop pmcmc.json altogether

# Plot parameter evolutions
def plottrace(tracefile = "trace_0") :
	t = trace(tracefile)

	if t is not None :
		t.plot(subplots = True)
		plt.show()

# Return parameter evolutions as dataframe
def trace(tracefile = "trace_0") :
	if not os.path.isfile("%s.csv" % tracefile) :
		print "%s.csv not found, please specify another trace file." % tracefile
	else :
		t = pd.read_csv("%s.csv" % tracefile, index_col = "index")
		return t

# Summarise parameters and model fits
def summary(jsonfile = "mle") :

	if os.path.isfile("%s.json" % jsonfile) :
		print "Summary of %s.json :\n" % jsonfile
		s = json.load(open("%s.json" % jsonfile))
	else :
		print "%s.json does not exist; summarising theta.json.\n" % jsonfile
		s = json.load(open("theta.json"))

	for key, value in s["resources"][0]["data"].items() :
		print("%s" % key + "\t" + "%s" % value).expandtabs(20)

	if jsonfile is not "mle" :
		for key, value in s["resources"][2]["data"].items() :
			print("%s" % key + "\t" + "%s" % value).expandtabs(20)

# Particle MCMC
def pmcmc(steps = 100000, burn = 10000, particles = 1000, jsonfile = "mle", out = 0) :
	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Particle MCMC from %s.json, %d particles, %d iterations ( %d single-particle burn-in )." % (jsonfile, particles, steps, burn)
		os.system("cat ../%s.json | ./pmcmc -N 8 -M %d | ./pmcmc -J %d -M %d --trace -N 8 -P .. -I %d > ../out.json" % (jsonfile, burn, particles, steps, out))
	else :
		print "%s.json does not exist, performing Particle MCMC using theta.json, %d particles, %d iterations ( %d single-particle burn-in )." % (jsonfile, particles, steps, burn)
		os.system("cat ../theta.json | ./pmcmc -J %d -N 8 -M %d | ./pmcmc -J %d -M %d --trace -N 8 -P .. -I %d > ../out.json" % (burn, particles, steps, out))

	os.rename("../out.json", "../pmcmc.json")
	os.chdir("..")
	# TODO : Create flags for turning off demographic stochasticity, white noises and diffusions

# Kalman Simplex
def ksimplex(steps = 10000, out = 0, jsonfile = "mle") :
	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Kalman Simplex from %s.json." % jsonfile
		os.system("cat ../%s.json | ./ksimplex -M %d -P .. -I %d > ../out.json" % (jsonfile, steps, out))
	else :
		print "%s.json does not exist, simulating using theta.json." % jsonfile
		os.system("cat ../theta.json | ./ksimplex -M %d -P .. -I %d > ../out.json" % (steps, out))

	os.rename("../out.json", "../mle.json")
	os.chdir("..")
	# TODO : Create flags for turning off demographic stochasticity, white noises and diffusions

# Kalman MCMC
def kmcmc(steps = 100000, jsonfile = "mle", out = 0, burn = 10000) :
	os.chdir("bin")

	if os.path.isfile("../%s.json" % jsonfile) :
		print "Kalman MCMC from %s.json, %d iterations ( %d burn-in )." % (jsonfile, steps, burn)
		os.system("cat ../%s.json | ./kmcmc -M %d | ./kmcmc -M %d -P .. --trace -I %d%s > ../out.json" % (jsonfile, burn, steps, out, flags))
	else :
		print "%s.json does not exist, performing Kalman MCMC using theta.json, %d iterations ( %d burn-in )." % (jsonfile, steps, burn)
		os.system("cat ../theta.json | ./kmcmc -M %d | ./kmcmc -M %d -P .. --trace -I %d%s > ../out.json" % (jsonfile, burn, steps, out, flags))

	os.rename("../out.json",  "../mle.json")
	os.chdir("..")
	# TODO : Create flags for turning off demographic stochasticity, white noises and diffusions

# Shortcut : black box generic inference. Expensive.
def blackbox(short = False) :
	if not short :
		compile()
		simplex(jsonfile = "theta")
		ksimplex()
		kmcmc()
		pmcmc(steps = 500000)
		plotsim()

	else :
		compile()
		simplex(jsonfile = "theta", steps = 100)
		ksimplex(steps = 50)
		kmcmc(steps = 100, burn = 10)
		pmcmc(steps = 100, burn = 10, particles = 2)
		plotsim("pmcmc")

# Latin hypercube initial conditions setup
def lhs(IC = 500, accept = 10) :
	print "Come back later."
	# TODO : Create IC initial conditions, sampled from parameter space
	# Make a backup of the user's IC files
	# For each IC, write a new file, run a simplex, ...
	# HERE : determine if we stop at simplex or follow with a ksimplex
	# Decide if we reject some before ksimplex
	# What do we do with the top solutions ?
	# How are they determined ?

<|endoftext|>


<commit_before>'''
Created on Sep 18, 2014

@author: David Zwicker <dzwicker@seas.harvard.edu>
'''

from __future__ import division

import subprocess
import os

from .project import HPCProjectBase
from ..algorithm.utils import change_directory

def parse_time(text):
    """ parse time of slurm output """
    # check for days
    tokens = text.split('-', 1)
    if len(tokens) > 1:
        days = int(tokens[0])
        rest = tokens[1]
    else:
        days = 0
        rest = tokens[0]

    # check for time
    tokens = rest.split(':')
    return days*24*60 + int(tokens[0])*60 + int(tokens[1])

class SlurmProject(HPCProjectBase):
    """ HPC project based on the slurm scheduler """

    job_files = {'pass1_single.py', 'pass1_single_slurm.sh',
                 'pass2_single.py', 'pass2_single_slurm.sh'}

    def submit(self):
        """ submit the tracking job using slurm """
        with change_directory(self.folder):
            # submit first job
            res = subprocess.check_output(['sbatch', 'pass1_single_slurm.sh'])
            pid_pass1 = int(res.split()[-1])
            self.pids = [pid_pass1]
            self.logger.info('Job id of first pass: %d', pid_pass1)

            # submit second job if requested
            if self.passes >= 2:
                res = subprocess.check_output(['sbatch',
                                               '--dependency=afterok:%d' % pid_pass1,
                                               'pass2_single_slurm.sh'])
                pid_pass2 = int(res.split()[-1])
                self.pids.append(pid_pass2)
                self.logger.info('Job id of second pass: %d', pid_pass2)

    def check_pass_status(self, pass_id):
        """ check the status of a single pass """
        status = {}

        # check whether slurm job has been initialized
        pid_file = os.path.join(self.folder, 'pass%d_job_id.txt' % pass_id)
        try:
            pids = open(pid_file).readlines()
        except OSError:
            status['general'] = 'not-started'
            return status
        else:
            status['general'] = 'started'

        # check the status of the job
        pid = int(pids[-1])
        res = subprocess.check_output(['squeue', '-j', pid,
                                       '-o', '"%T|%M"']) #< output format
        if 'Invalid job id specified' in res:
            # job seems to have finished already
            res = subprocess.check_output(['sacct', '-j', pid, '-P',
                                           '-o', 'state,MaxRSS,Elapsed,cputime'])
            chunks = res.split('|')
            status['state'] = chunks[0]
            status['elapsed'] = chunks[2]

        else:
            # jobs seems to be currently running
            chunks = res.split('|')
            status['state'] = chunks[0]
            status['elapsed'] = chunks[1]

        return status

    def get_status(self):
        """ check the status of the project """
        status = {}
        if os.path.isdir(self.folder):
            # project is initialized
            status['project'] = 'initialized'

            status['pass1'] = self.check_pass_status(1)
            status['pass2'] = self.check_pass_status(2)

        else:
            status['project'] = 'not-initialized'
        return status
            <commit_msg>Fixed bug<commit_after>'''
Created on Sep 18, 2014

@author: David Zwicker <dzwicker@seas.harvard.edu>
'''

from __future__ import division

import subprocess
import os

from .project import HPCProjectBase
from ..algorithm.utils import change_directory

def parse_time(text):
    """ parse time of slurm output """
    # check for days
    tokens = text.split('-', 1)
    if len(tokens) > 1:
        days = int(tokens[0])
        rest = tokens[1]
    else:
        days = 0
        rest = tokens[0]

    # check for time
    tokens = rest.split(':')
    return days*24*60 + int(tokens[0])*60 + int(tokens[1])

class SlurmProject(HPCProjectBase):
    """ HPC project based on the slurm scheduler """

    job_files = {'pass1_single.py', 'pass1_single_slurm.sh',
                 'pass2_single.py', 'pass2_single_slurm.sh'}

    def submit(self):
        """ submit the tracking job using slurm """
        with change_directory(self.folder):
            # submit first job
            res = subprocess.check_output(['sbatch', 'pass1_single_slurm.sh'])
            pid_pass1 = int(res.split()[-1])
            self.pids = [pid_pass1]
            self.logger.info('Job id of first pass: %d', pid_pass1)

            # submit second job if requested
            if self.passes >= 2:
                res = subprocess.check_output(['sbatch',
                                               '--dependency=afterok:%d' % pid_pass1,
                                               'pass2_single_slurm.sh'])
                pid_pass2 = int(res.split()[-1])
                self.pids.append(pid_pass2)
                self.logger.info('Job id of second pass: %d', pid_pass2)

    def check_pass_status(self, pass_id):
        """ check the status of a single pass """
        status = {}

        # check whether slurm job has been initialized
        pid_file = os.path.join(self.folder, 'pass%d_job_id.txt' % pass_id)
        try:
            pids = open(pid_file).readlines()
        except IOError:
            status['general'] = 'not-started'
            return status
        else:
            status['general'] = 'started'

        # check the status of the job
        pid = pids[-1]
        res = subprocess.check_output(['squeue', '-j', pid,
                                       '-o', '"%T|%M"']) #< output format
        if 'Invalid job id specified' in res:
            # job seems to have finished already
            res = subprocess.check_output(['sacct', '-j', pid, '-P',
                                           '-o', 'state,MaxRSS,Elapsed,cputime'])
            chunks = res.split('|')
            status['state'] = chunks[0]
            status['elapsed'] = chunks[2]

        else:
            # jobs seems to be currently running
            chunks = res.split('|')
            status['state'] = chunks[0]
            status['elapsed'] = chunks[1]

        return status

    def get_status(self):
        """ check the status of the project """
        status = {}
        if os.path.isdir(self.folder):
            # project is initialized
            status['project'] = 'initialized'

            status['pass1'] = self.check_pass_status(1)
            status['pass2'] = self.check_pass_status(2)

        else:
            status['project'] = 'not-initialized'
        return status
            <|endoftext|>


<commit_before>from argparse import ArgumentParser
from diary_range import connect
from presenter import display_entries
from fuzzydate import custom_date

PROGRAM_NAME = 'diary'
VERSION_NUMBER = '2.0.0'

#TODO add help text for optional arguments
#TODO add default base dir and device name

# SETUP MAIN PARSER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

parser = ArgumentParser(description='')
parser.add_argument('--version', action='version',
        version='{} {}'.format(PROGRAM_NAME, VERSION_NUMBER))
parser.add_argument('-b', '--base', help='path to base folder')

subparsers = parser.add_subparsers()

# EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def edit_command(conn, entry_id, **kwargs):
    '''Edit the most recent entry or the entry specified by entry_id.'''
    entry = conn.find_by_id(entry_id) if entry_id else conn.most_recent_entry()
    entry.command_line_edit()

subparser = subparsers.add_parser('edit')
subparser.add_argument('entry_id', nargs='?')
subparser.set_defaults(func=edit_command)

# NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def new_command(conn, date, **kwargs):
    '''Create and edit a new entry with the current date or the given date.'''
    entry = conn.new_entry(date)
    entry.command_line_edit()

subparser = subparsers.add_parser('new')
subparser.add_argument('date', type=custom_date, nargs='?')
subparser.set_defaults(func=new_command)

# SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def search_command(conn, search_terms, descending, after, before, **kwargs):
    '''Display entries containing all of the terms in search_terms.'''
    entries = conn.search_entries(*search_terms, descending=descending,
                                  min_date=after, max_date=before)
    display_entries(entries, search_terms)

subparser = subparsers.add_parser('search', aliases=['list'])
subparser.add_argument('search_terms', nargs='*')
subparser.add_argument('--before', type=custom_date, metavar='DATE')
subparser.add_argument('--after', type=custom_date, metavar='DATE')
subparser.add_argument('--asc', action='store_false', dest='descending')
subparser.add_argument('--desc', action='store_true', dest='descending')
subparser.set_defaults(func=search_command, descending=True)

# WORDCOUNT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def wordcount_command(conn, group_by, **kwargs):
    '''Pretty print wordcount statistics for all entries.'''
    if group_by is None: group_by = 'Total'
    wordcounts = {}
    entry_counts = {}

    for entry in conn.get_entries():
        group = entry.date.strftime(group_by)
        if group not in wordcounts:
            wordcounts[group], entry_counts[group] = 0, 0
        wordcounts[group] += entry.wordcount
        entry_counts[group] += 1

    results = [ (group, wordcounts[group], entry_counts[group])
                            for group in sorted(wordcounts.keys()) ]

    if len(results)>1:
        results.append( ('Total', sum(wordcounts.values()),
                                  sum(entry_counts.values())) )

    max_lengths = {'len_group': max(len(str(result[0])) for result in results),
                   'len_wc': len(str(results[-1][1])),
                   'len_ec': len(str(results[-1][2]))}

    format_string = '{0:>{len_group}}:  {1:>{len_wc}} words,  {2:>{len_ec}} entries'

    for result in results:
        print(format_string.format(*result, **max_lengths))

subparser = subparsers.add_parser('wordcount', aliases=['wc'])
subparser.add_argument('-y', '--year', action='store_const', const='%Y', dest='group_by')
subparser.add_argument('-m', '--month', action='store_const', const='%Y-%m', dest='group_by')
subparser.add_argument('-w', '--weekday', action='store_const', const='%u %a', dest='group_by')
subparser.add_argument('-g', '--group-by', dest='group_by', metavar='DATE_FORMAT')
subparser.set_defaults(func=wordcount_command)

# PROCESS ARGS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def process_args():
    args = parser.parse_args()
    if hasattr(args, 'func'):
        conn = connect(args.base)
        args.func(conn, **vars(args))
    else:
        parser.print_usage()

if __name__ == '__main__':
    process_args()
<commit_msg>Added complete help and description messages to cli.py<commit_after>from argparse import ArgumentParser
from diary_range import connect
from presenter import display_entries
from fuzzydate import custom_date

__version__ = '2.0.0'

#TODO add default base dir and device name

# SETUP MAIN PARSER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

parser = ArgumentParser(
    description='A program for writing and viewing a personal diary')

parser.add_argument('--version', action='version',
        version='%(prog)s {}'.format(__version__))

parser.add_argument('-b', '--base', help='path to base folder')

subparsers = parser.add_subparsers(title='subcommands')

# EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def edit_command(conn, entry_id, **kwargs):
    entry = conn.find_by_id(entry_id) if entry_id else conn.most_recent_entry()
    entry.command_line_edit()

subparser = subparsers.add_parser('edit',
    description='Open Vim to edit the most recent entry '
                'or the entry specified by entry_id',
    help='edit the most recent entry or a specified entry')

subparser.add_argument('entry_id', nargs='?',
    help='entry id of the form "$timestamp-$device_name"')

subparser.set_defaults(func=edit_command)

# NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def new_command(conn, date, **kwargs):
    entry = conn.new_entry(date)
    entry.command_line_edit()

subparser = subparsers.add_parser('new',
    description='Open Vim to edit a new entry',
    help='create a new entry')

subparser.add_argument('date', type=custom_date, nargs='?',
    help='date of the new entry (defaults to now)')

subparser.set_defaults(func=new_command)

# SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def search_command(conn, search_terms, descending, after, before, **kwargs):
    entries = conn.search_entries(*search_terms, descending=descending,
                                  min_date=after, max_date=before)
    display_entries(entries, search_terms)

subparser = subparsers.add_parser('search', aliases=['list'],
    description='Display entries containing all of the given search terms',
    help='display all entries, with optional search filter')

subparser.add_argument('search_terms', nargs='*',
    help='any number of regular expressions to search for')

subparser.add_argument('--before', type=custom_date, metavar='DATE',
    help='only show entries occurring before DATE')
subparser.add_argument('--after', type=custom_date, metavar='DATE',
    help='only show entries occurring after DATE')

sort_order = subparser.add_mutually_exclusive_group()
sort_order.add_argument('--asc', action='store_false', dest='descending',
    help='sort in ascending date order')
sort_order.add_argument('--desc', action='store_true', dest='descending',
    help='sort in descending date order')

subparser.set_defaults(func=search_command, descending=True)

# WORDCOUNT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def wordcount_command(conn, group_by, **kwargs):
    if group_by is None: group_by = 'Total'
    wordcounts = {}
    entry_counts = {}

    for entry in conn.get_entries():
        group = entry.date.strftime(group_by)
        if group not in wordcounts:
            wordcounts[group], entry_counts[group] = 0, 0
        wordcounts[group] += entry.wordcount
        entry_counts[group] += 1

    results = [ (group, wordcounts[group], entry_counts[group])
                            for group in sorted(wordcounts.keys()) ]

    if len(results)>1:
        results.append( ('Total', sum(wordcounts.values()),
                                  sum(entry_counts.values())) )

    max_lengths = {'len_group': max(len(str(result[0])) for result in results),
                   'len_wc': len(str(results[-1][1])),
                   'len_ec': len(str(results[-1][2]))}

    fmt_str = '{0:>{len_group}}:  {1:>{len_wc}} words,  {2:>{len_ec}} entries'

    for result in results:
        print(fmt_str.format(*result, **max_lengths))

subparser = subparsers.add_parser('wordcount', aliases=['wc'],
    description='Pretty print aggregated wordcount totals',
    help='print wordcount statistics')

group_by = subparser.add_mutually_exclusive_group()
group_by.add_argument('-y', '--year', action='store_const', const='%Y',
    dest='group_by', help='group by year')
group_by.add_argument('-m', '--month', action='store_const', const='%Y-%m',
    dest='group_by', help='group by month')
group_by.add_argument('-w', '--weekday', action='store_const', const='%u %a',
    dest='group_by', help='group by weekday')
group_by.add_argument('-g', '--group-by', metavar='DATE_FORMAT',
    dest='group_by', help='format entry dates with DATE_FORMAT and combine '
                          'wordcount totals for all entries which have the '
                          'same formatted date, e.g. "%%Y-%%m-%%d"')

subparser.set_defaults(func=wordcount_command)

# PROCESS ARGS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def process_args():
    args = parser.parse_args()
    if hasattr(args, 'func'):
        conn = connect(args.base)
        args.func(conn, **vars(args))
    else:
        parser.print_usage()

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


<commit_before># -*- coding: utf-8 -*-
# Author: caphm
# Module: KodiMonitor
# Created on: 08.02.2018
# License: MIT https://goo.gl/5bMj3H

"""Playback tracking & update of associated item properties in Kodi library"""

import json
import xbmc
import xbmcgui

from resources.lib.utils import noop, log

def _get_safe_with_fallback(item, fallback, **kwargs):
    itemkey = kwargs.get('itemkey', 'title')
    fallbackkey = kwargs.get('fallbackkey', 'title')
    default = kwargs.get('default', '')
    try:
        return item.get(itemkey) or fallback.get(fallbackkey)
    except AttributeError:
        return default

def _retry(func, max_tries):
    for _ in range(1, max_tries):
        xbmc.sleep(3000)
        retval = func()
        if retval is not None:
            return retval
    return None

def _json_rpc(method, params=None):
    request_data = {'jsonrpc': '2.0', 'method': method, 'id': 1,
                    'params': params or {}}
    request = json.dumps(request_data)
    response = json.loads(unicode(xbmc.executeJSONRPC(request), 'utf-8',
                                  errors='ignore'))
    if 'error' in response:
        raise IOError('JSONRPC-Error {}: {}'
                      .format(response['error']['code'],
                              response['error']['message']))
    return response['result']

def _get_active_video_player():
    return next((player['playerid']
                 for player in _json_rpc('Player.GetActivePlayers')
                 if player['type'] == 'video'),
                None)

def _match_episode(item, episode, fallback_data):
    title = _get_safe_with_fallback(item, fallback_data, itemkey='label')
    try:
        matches_show = (item.get('tvshowid') == episode['tvshowid'] or
                        item.get('showtitle') == episode['showtitle'])
        matches_season = item.get('season') == episode['season']
        matches_episode = item.get('episode') == episode['episode']
        matches_explicitly = (matches_show and matches_season and
                              matches_episode)
    except AttributeError:
        matches_explicitly = False

    episode_meta = 'S%02dE%02d' % (episode['season'],
                                   episode['episode'])
    matches_meta = (episode['showtitle'] in title and
                    episode_meta in title)
    return matches_explicitly or matches_meta

def _guess_episode(item, fallback_data):
    resp = _json_rpc('VideoLibrary.GetEpisodes',
                     {'properties': ['playcount', 'tvshowid',
                                     'showtitle', 'season',
                                     'episode']})
    return next(({'dbtype': 'episode', 'dbid': episode['episodeid'],
                  'playcount': episode['playcount']}
                 for episode in resp.get('episodes', [])
                 if _match_episode(item, episode, fallback_data)),
                None)

def _match_movie(item, movie, fallback_data):
    title = _get_safe_with_fallback(item, fallback_data)
    movie_meta = '%s (%d)' % (movie['label'], movie['year'])
    return movie_meta == title or movie['label'] in title

def _guess_movie(item, fallback_data):
    params = {'properties': ['playcount', 'year', 'title']}
    try:
        params['filter'] = {'year': item['year']}
    except (TypeError, KeyError):
        pass
    resp = _json_rpc('VideoLibrary.GetMovies', params)
    return next(({'dbtype': 'movie', 'dbid': movie['movieid'],
                  'playcount': movie['playcount']}
                 for movie in resp.get('movies', [])
                 if _match_movie(item, movie, fallback_data)),
                None)

class KodiMonitor(xbmc.Monitor):
    """
    Tracks status and progress of video playbacks initiated by the addon and
    saves bookmarks and watched state for the associated items into the Kodi
    library.
    """

    PROP_PLAYBACK_TRACKING = 'tracking'

    def __init__(self, kodi_helper, log_fn=noop):
        super(KodiMonitor, self).__init__()
        self.kodi_helper = kodi_helper
        self.video_info = None
        self.progress = 0
        self.log = log_fn

    def is_initialized_playback(self):
        """
        Indicates if a playback was initiated by the netflix addon by
        checking the appropriate window property set by KodiHelper.
        """
        return self._is_playback_status(self.kodi_helper.PROP_PLAYBACK_INIT)

    def is_tracking_playback(self):
        """
        Indicates if an ongoing playback is actively tracked by an
        instance of this class.
        """
        return (self.video_info is not None and
                self._is_playback_status(self.PROP_PLAYBACK_TRACKING))

    def update_playback_progress(self):
        """
        Updates the internal progress status of a tracked playback
        and saves bookmarks to Kodi library.
        """
        if not self.is_tracking_playback():
            return

        player_id = _get_active_video_player()
        try:
            progress = _json_rpc('Player.GetProperties', {
                'playerid': player_id,
                'properties': ['percentage', 'time']
            })
        except IOError:
            return
        playtime_seconds = (progress['time']['hours'] * 3600 +
                            progress['time']['minutes'] * 60 +
                            progress['time']['seconds'])
        self._update_item_details({'resume': {'position': playtime_seconds}})
        self.progress = progress['percentage']

    def onNotification(self, sender, method, data):
        """
        Callback for Kodi notifications that handles and dispatches playback
        started and playback stopped events.
        """
        # pylint: disable=unused-argument, invalid-name
        data = json.loads(unicode(data, 'utf-8', errors='ignore'))
        if method == 'Player.OnPlay':
            self._on_playback_started(data.get('item', None))
        elif method == 'Player.OnStop':
            self._on_playback_stopped()

    @log
    def _on_playback_started(self, item):
        player_id = _retry(_get_active_video_player, 5)

        if player_id is not None and self.is_initialized_playback():
            self.video_info = self._get_video_info(player_id, item)
            self.progress = 0
            xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
                self.kodi_helper.PROP_NETFLIX_PLAY,
                self.PROP_PLAYBACK_TRACKING)
            self.log('Tracking playback of {}'.format(self.video_info))
        else:
            # Clean up remnants from improperly stopped previous playbacks.
            # Clearing the window property does not work as expected, thus
            # we overwrite it with an arbitrary value
            xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
                self.kodi_helper.PROP_NETFLIX_PLAY, 'notnetflix')
            self.log('Not tracking playback: {}'
                     .format('Playback not initiated by netflix plugin'
                             if self.is_initialized_playback() else
                             'Unable to obtain active video player'))

    @log
    def _on_playback_stopped(self):
        if self.is_tracking_playback():
            if self.progress >= 90:
                new_playcount = self.video_info.get('playcount', 0) + 1
                self._update_item_details({'playcount': new_playcount,
                                           'resume': {'position': 0}})
                action = 'marking {} as watched.'.format(self.video_info)
            else:
                action = ('not marking {} as watched, progress too little'
                          .format(self.video_info))
            self.log('Tracked playback stopped: {}'.format(action))

        xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
            self.kodi_helper.PROP_NETFLIX_PLAY, 'stopped')
        self.video_info = None
        self.progress = 0

    @log
    def _get_video_info(self, player_id, fallback_data):
        info = _json_rpc('Player.GetItem',
                         {
                             'playerid': player_id,
                             'properties': ['playcount', 'title', 'year',
                                            'tvshowid', 'showtitle',
                                            'season', 'episode']
                         }).get('item', {})
        try:
            return {'dbtype': info['type'], 'dbid': info['id'],
                    'playcount': info.get('playcount', 0)}
        except KeyError:
            video_info = (self._guess_episode(info, fallback_data) or
                          self._guess_movie(info, fallback_data))
            if video_info is None:
                self.log('Unable to obtain video info (fallback_data={})'
                         .format(fallback_data),
                         xbmc.LOGERROR)
            else:
                self.log('Obtained video info by guessing ({})'
                         .format(video_info),
                         xbmc.LOGWARNING)
            return video_info

    @log
    def _update_item_details(self, properties):
        method = ('VideoLibrary.Set{}Details'
                  .format(self.video_info['dbtype'].capitalize()))
        params = {'{}id'.format(self.video_info['dbtype']):
                  self.video_info['dbid']}
        params.update(properties)
        _json_rpc(method, params)

    def _is_playback_status(self, status):
        return xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).getProperty(
            self.kodi_helper.PROP_NETFLIX_PLAY) == status
<commit_msg>More codeclimate<commit_after># -*- coding: utf-8 -*-
# Author: caphm
# Module: KodiMonitor
# Created on: 08.02.2018
# License: MIT https://goo.gl/5bMj3H

"""Playback tracking & update of associated item properties in Kodi library"""

import json
import xbmc
import xbmcgui

from resources.lib.utils import noop, log

def _get_safe_with_fallback(item, fallback, **kwargs):
    itemkey = kwargs.get('itemkey', 'title')
    fallbackkey = kwargs.get('fallbackkey', 'title')
    default = kwargs.get('default', '')
    try:
        return item.get(itemkey) or fallback.get(fallbackkey)
    except AttributeError:
        return default

def _retry(func, max_tries):
    for _ in range(1, max_tries):
        xbmc.sleep(3000)
        retval = func()
        if retval is not None:
            return retval
    return None

def _json_rpc(method, params=None):
    request_data = {'jsonrpc': '2.0', 'method': method, 'id': 1,
                    'params': params or {}}
    request = json.dumps(request_data)
    response = json.loads(unicode(xbmc.executeJSONRPC(request), 'utf-8',
                                  errors='ignore'))
    if 'error' in response:
        raise IOError('JSONRPC-Error {}: {}'
                      .format(response['error']['code'],
                              response['error']['message']))
    return response['result']

def _get_active_video_player():
    return next((player['playerid']
                 for player in _json_rpc('Player.GetActivePlayers')
                 if player['type'] == 'video'),
                None)

def _first_match_or_none(mediatype, item, candidates, item_fb, match_fn):
    return next(({'dbtype': mediatype,
                  'dbid': candidate['{}id'.format(mediatype)],
                  'playcount': candidate['playcount']}
                 for candidate in candidates
                 if match_fn(item, candidate, item_fb)),
                None)

def _match_movie(item, movie, fallback_data):
    title = _get_safe_with_fallback(item, fallback_data)
    movie_meta = '%s (%d)' % (movie['label'], movie['year'])
    return movie_meta == title or movie['label'] in title

def _match_episode_explicitly(item, candidate):
    try:
        matches_show = (item.get('tvshowid') == candidate['tvshowid'] or
                        item.get('showtitle') == candidate['showtitle'])
        matches_season = item.get('season') == candidate['season']
        matches_episode = item.get('episode') == candidate['episode']
        return matches_show and matches_season and matches_episode
    except AttributeError:
        return False

def _match_episode_by_title(title, candidate):
    episode_meta = 'S%02dE%02d' % (candidate['season'],
                                   candidate['episode'])
    return candidate['showtitle'] in title and episode_meta in title

def _match_episode(item, candidate, item_fb):
    title = _get_safe_with_fallback(item, item_fb, itemkey='label')
    return (_match_episode_explicitly(item, candidate) or
            _match_episode_by_title(title, candidate))

def _guess_episode(item, item_fb):
    resp = _json_rpc('VideoLibrary.GetEpisodes',
                     {'properties': ['playcount', 'tvshowid',
                                     'showtitle', 'season',
                                     'episode']})
    return _first_match_or_none('episode', item, resp.get('episodes', []),
                                item_fb, _match_episode)

def _guess_movie(item, item_fb):
    params = {'properties': ['playcount', 'year', 'title']}
    try:
        params['filter'] = {'year': item['year']}
    except (TypeError, KeyError):
        pass
    resp = _json_rpc('VideoLibrary.GetMovies', params)
    return _first_match_or_none('movie', item, resp.get('movies', []),
                                item_fb, _match_movie)

class KodiMonitor(xbmc.Monitor):
    """
    Tracks status and progress of video playbacks initiated by the addon and
    saves bookmarks and watched state for the associated items into the Kodi
    library.
    """

    PROP_PLAYBACK_TRACKING = 'tracking'

    def __init__(self, kodi_helper, log_fn=noop):
        super(KodiMonitor, self).__init__()
        self.kodi_helper = kodi_helper
        self.video_info = None
        self.progress = 0
        self.log = log_fn

    def is_initialized_playback(self):
        """
        Indicates if a playback was initiated by the netflix addon by
        checking the appropriate window property set by KodiHelper.
        """
        return self._is_playback_status(self.kodi_helper.PROP_PLAYBACK_INIT)

    def is_tracking_playback(self):
        """
        Indicates if an ongoing playback is actively tracked by an
        instance of this class.
        """
        return (self.video_info is not None and
                self._is_playback_status(self.PROP_PLAYBACK_TRACKING))

    @log
    def update_playback_progress(self):
        """
        Updates the internal progress status of a tracked playback
        and saves bookmarks to Kodi library.
        """
        if not self.is_tracking_playback():
            return None

        player_id = _get_active_video_player()
        try:
            progress = _json_rpc('Player.GetProperties', {
                'playerid': player_id,
                'properties': ['percentage', 'time']
            })
        except IOError:
            return None
        elapsed = (progress['time']['hours'] * 3600 +
                   progress['time']['minutes'] * 60 +
                   progress['time']['seconds'])
        self.progress = progress['percentage']
        return self._update_item_details({'resume': {'position': elapsed}})

    def onNotification(self, sender, method, data):
        """
        Callback for Kodi notifications that handles and dispatches playback
        started and playback stopped events.
        """
        # pylint: disable=unused-argument, invalid-name
        data = json.loads(unicode(data, 'utf-8', errors='ignore'))
        if method == 'Player.OnPlay':
            self._on_playback_started(data.get('item', None))
        elif method == 'Player.OnStop':
            self._on_playback_stopped()

    @log
    def _on_playback_started(self, item):
        player_id = _retry(_get_active_video_player, 5)

        if player_id is not None and self.is_initialized_playback():
            self.video_info = self._get_video_info(player_id, item)
            self.progress = 0
            xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
                self.kodi_helper.PROP_NETFLIX_PLAY,
                self.PROP_PLAYBACK_TRACKING)
            self.log('Tracking playback of {}'.format(self.video_info))
        else:
            # Clean up remnants from improperly stopped previous playbacks.
            # Clearing the window property does not work as expected, thus
            # we overwrite it with an arbitrary value
            xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
                self.kodi_helper.PROP_NETFLIX_PLAY, 'notnetflix')
            self.log('Not tracking playback: {}'
                     .format('Playback not initiated by netflix plugin'
                             if self.is_initialized_playback() else
                             'Unable to obtain active video player'))

    @log
    def _on_playback_stopped(self):
        if self.is_tracking_playback():
            if self.progress >= 90:
                new_playcount = self.video_info.get('playcount', 0) + 1
                self._update_item_details({'playcount': new_playcount,
                                           'resume': {'position': 0}})
                action = 'marking {} as watched.'.format(self.video_info)
            else:
                action = ('not marking {} as watched, progress too little'
                          .format(self.video_info))
            self.log('Tracked playback stopped: {}'.format(action))

        xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).setProperty(
            self.kodi_helper.PROP_NETFLIX_PLAY, 'stopped')
        self.video_info = None
        self.progress = 0

    @log
    def _get_video_info(self, player_id, fallback_data):
        info = _json_rpc('Player.GetItem',
                         {
                             'playerid': player_id,
                             'properties': ['playcount', 'title', 'year',
                                            'tvshowid', 'showtitle',
                                            'season', 'episode']
                         }).get('item', {})
        try:
            return {'dbtype': info['type'], 'dbid': info['id'],
                    'playcount': info.get('playcount', 0)}
        except KeyError:
            self.log('Guessing video info (fallback={})'.format(fallback_data),
                     xbmc.LOGWARNING)
            return (self._guess_episode(info, fallback_data) or
                    self._guess_movie(info, fallback_data))

    @log
    def _update_item_details(self, properties):
        method = ('VideoLibrary.Set{}Details'
                  .format(self.video_info['dbtype'].capitalize()))
        params = {'{}id'.format(self.video_info['dbtype']):
                  self.video_info['dbid']}
        params.update(properties)
        return _json_rpc(method, params)

    def _is_playback_status(self, status):
        return xbmcgui.Window(self.kodi_helper.TAGGED_WINDOW_ID).getProperty(
            self.kodi_helper.PROP_NETFLIX_PLAY) == status
<|endoftext|>