From: Mike Frysinger Date: Sun, 17 Feb 2013 05:00:35 +0000 (-0500) Subject: initial extension X-Git-Tag: v1.0 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=a98f3ef6a42ca6883b68136d1e87246627f30a9e;p=chrome-ext%2Fweb-power-switch.git initial extension --- a98f3ef6a42ca6883b68136d1e87246627f30a9e diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4c4ffc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/common.js b/common.js new file mode 100644 index 0000000..1b35a75 --- /dev/null +++ b/common.js @@ -0,0 +1,15 @@ +// Written by Mike Frysinger . Released into the public domain. Suck it. + +var storage = chrome.storage.sync; + +var settings_keys = [ + 'url', + 'user', + 'pass', +]; + +var settings_defaults = { + 'url': 'http://192.168.0.100', + 'user': 'admin', + 'pass': '1234', +}; diff --git a/images/outlet-128x128.png b/images/outlet-128x128.png new file mode 100644 index 0000000..e5719d2 Binary files /dev/null and b/images/outlet-128x128.png differ diff --git a/images/outlet-19x19.png b/images/outlet-19x19.png new file mode 100644 index 0000000..114b4b8 Binary files /dev/null and b/images/outlet-19x19.png differ diff --git a/images/outlet-38x38.png b/images/outlet-38x38.png new file mode 100644 index 0000000..fbeb052 Binary files /dev/null and b/images/outlet-38x38.png differ diff --git a/images/outlet.svg b/images/outlet.svg new file mode 100644 index 0000000..1623599 --- /dev/null +++ b/images/outlet.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/makedist.sh b/makedist.sh new file mode 100755 index 0000000..76be818 --- /dev/null +++ b/makedist.sh @@ -0,0 +1,42 @@ +#!/bin/bash -e +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +case $1 in +-h|--help) + echo "Usage: $0 [rev]" + exit 0 + ;; +esac + +json_value() { + local key=$1 + sed -n -r \ + -e '/^[[:space:]]*"'"${key}"'"/s|.*:[[:space:]]*"([^"]*)",?$|\1|p' \ + manifest.json +} + +PN=$(json_value name | sed 's:[[:space:]]:_:g' | tr '[:upper:]' '[:lower:]') +PV=$(json_value version) +rev=${1:-0} +PVR="${PV}.${rev}" +P="${PN}-${PVR}" + +rm -rf "${P}" +mkdir "${P}" + +while read line ; do + [[ ${line} == */* ]] && mkdir -p "${P}/${line%/*}" + ln "${line}" "${P}/${line}" +done < <(sed 's:#.*::' manifest.files) +cp manifest.json "${P}/" + +sed -i \ + -e '/"version"/s:"[^"]*",:"'${PVR}'",:' \ + "${P}/manifest.json" + +zip="${P}.zip" +zip -r "${zip}" "${P}" +rm -rf "${P}" +du -b "${zip}" diff --git a/manifest.files b/manifest.files new file mode 100644 index 0000000..aae31cb --- /dev/null +++ b/manifest.files @@ -0,0 +1,9 @@ +images/outlet-128x128.png +images/outlet-19x19.png +images/outlet-38x38.png +images/outlet.svg +common.js +options.html +options.js +popup.html +popup.js diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..23da87f --- /dev/null +++ b/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 2, + "minimum_chrome_version": "22", + "name": "Web Power Switch Manager", + "version": "1.0", + "description": "Quickly control Web Power Switches", + "icons": { + "128": "images/outlet-128x128.png" + }, + "browser_action": { + "default_icon": { + "19": "images/outlet-19x19.png", + "38": "images/outlet-38x38.png" + }, + "default_title": "Control Your Switch", + "default_popup": "popup.html" + }, + "options_page": "options.html", + "permissions": [ + "storage", + "http://*/" + ] +} diff --git a/options.html b/options.html new file mode 100644 index 0000000..849f183 --- /dev/null +++ b/options.html @@ -0,0 +1,24 @@ + + + + + +Web Power Switch Manager Options + + + + + + + + + + + + + + + +
URL:
User:
Pass:
+ + diff --git a/options.js b/options.js new file mode 100644 index 0000000..3464826 --- /dev/null +++ b/options.js @@ -0,0 +1,17 @@ +// Written by Mike Frysinger . Released into the public domain. Suck it. + +function update_settings() { + var setting = {}; + setting[this.id] = this.value; + storage.set(setting); +} + +window.onload = function() { + storage.get(settings_keys, function(settings) { + settings_keys.forEach(function(key) { + var field = document.getElementById(key); + field.value = settings[key] || settings_defaults[key]; + field.oninput = update_settings; + }); + }); +}; diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..fa89f3e --- /dev/null +++ b/popup.html @@ -0,0 +1,32 @@ + + + + + +Web Power Switch Manager + + + + + + +
Loading...
+
+ + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..a88ed94 --- /dev/null +++ b/popup.js @@ -0,0 +1,142 @@ +// Written by Mike Frysinger . Released into the public domain. Suck it. + +var url_base, user, pass; + +function fetchpage(url, callback) { + url = url_base + '/' + url; + + var xhr = new XMLHttpRequest(); + xhr.setstatus = false; + try { + xhr.onreadystatechange = function(state) { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + callback(xhr, state); + } else { + xhr.setstatus = true; + setstatus('Could not connect; check settings'); + console.log('connect error', state); + } + } + } + xhr.onerror = function(error) { + if (!xhr.setstatus) + setstatus('onerror; see console'); + console.log('xhr error:', error); + } + + console.log('fetching', url) + xhr.withCredentials = true; + xhr.open('GET', url, true, user, pass); + xhr.responseType = 'document'; + // The user/pass options above don't seem to work, so do it ourselves. + xhr.setRequestHeader('Authorization', 'Basic ' + btoa(user + ':' + pass)); + xhr.send(); + } catch(e) { + setstatus('Exception; see console'); + console.log('exception:', e); + } +} + +function onoff(o) { + return o.toUpperCase() === 'ON' ? 'OFF' : 'ON'; +} + +function toggleit(button) { + var outlet_num = button.id; + var old_status = button.data; + var new_status = onoff(button.data); + var url = 'outlet?' + outlet_num + '=' + new_status; + + fetchpage(url, function(xhr, state) { + console.log('switch ' + outlet_num + ': ' + old_status + ' -> ' + new_status); + button.value = 'Switch ' + old_status; + button.data = new_status; + }); +} +function toggle() { + toggleit(this); +} + +function toggle_confirmed() { + clearTimeout(this.timeout); + this.onclick = toggle_confirm; + toggleit(this); +} + +function toggle_confirm() { + var button = this; + this.onclick = toggle_confirmed; + this.oldvalue = this.value; + this.value = 'Confirm!?'; + this.timeout = setTimeout(function() { + button.value = button.oldvalue; + button.onclick = toggle_confirm; + }, 5000); +} + +function trim(str) { + return str.replace(/^\s+|\s+$/, ''); +} + +function initpopup(xhr, state) { + var tbl = document.getElementById('buttons'); + var row, cell, button; + + console.log(xhr, state); + + // There is no clean API for extracting the current state. + // Example result: + /* + 1 + Outlet 1 + OFF + Switch ON + + + + */ + + var tr, trs = state.currentTarget.responseXML.querySelectorAll('tr'); + for (var i = 0; tr = trs[i]; ++i) { + if (tr.bgColor != '#F4F4F4') + continue; + + var outlet_num = trim(tr.children[0].innerText); + var outlet_name = trim(tr.children[1].innerText); + var current_status = trim(tr.children[2].innerText); + var new_status = trim(tr.children[3].innerText); + var confirmable = tr.children[3].children[0].hasAttribute('onclick'); + + row = tbl.insertRow(-1); + cell = row.insertCell(-1); + cell.innerText = outlet_name + ':'; + cell = row.insertCell(-1); + button = document.createElement('input'); + button.type = 'button'; + button.id = outlet_num; + button.value = new_status; + button.data = current_status; + button.onclick = confirmable ? toggle_confirm : toggle; + cell.appendChild(button); + } + + setstatus(); +} + +function setstatus(msg) { + var status = document.getElementById('status'); + status.innerText = msg; + status.style.visibility = msg ? '' : 'hidden'; + status.style.float = msg ? '' : 'left'; + status.style.position = msg ? '' : 'absolute'; +} + +document.addEventListener('DOMContentLoaded', function() { + storage.get(settings_keys, function(settings) { + url_base = settings['url'] || settings_defaults['url']; + user = settings['user'] || settings_defaults['user']; + pass = settings['pass'] || settings_defaults['pass']; + fetchpage('index.htm', initpopup); + }); +});