ruku 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +96 -0
  3. data/Rakefile +33 -0
  4. data/bin/ruku +50 -0
  5. data/lib/ruku/clients/simple.rb +232 -0
  6. data/lib/ruku/clients/tk.rb +36 -0
  7. data/lib/ruku/clients/web.rb +117 -0
  8. data/lib/ruku/clients/web_static/css/ruku.css +196 -0
  9. data/lib/ruku/clients/web_static/images/box-medium.png +0 -0
  10. data/lib/ruku/clients/web_static/images/box-small.png +0 -0
  11. data/lib/ruku/clients/web_static/images/remote/back-over.png +0 -0
  12. data/lib/ruku/clients/web_static/images/remote/back.png +0 -0
  13. data/lib/ruku/clients/web_static/images/remote/down-over.png +0 -0
  14. data/lib/ruku/clients/web_static/images/remote/down.png +0 -0
  15. data/lib/ruku/clients/web_static/images/remote/fwd-over.png +0 -0
  16. data/lib/ruku/clients/web_static/images/remote/fwd.png +0 -0
  17. data/lib/ruku/clients/web_static/images/remote/home-over.png +0 -0
  18. data/lib/ruku/clients/web_static/images/remote/home.png +0 -0
  19. data/lib/ruku/clients/web_static/images/remote/left-over.png +0 -0
  20. data/lib/ruku/clients/web_static/images/remote/left.png +0 -0
  21. data/lib/ruku/clients/web_static/images/remote/pause-over.png +0 -0
  22. data/lib/ruku/clients/web_static/images/remote/pause.png +0 -0
  23. data/lib/ruku/clients/web_static/images/remote/right-over.png +0 -0
  24. data/lib/ruku/clients/web_static/images/remote/right.png +0 -0
  25. data/lib/ruku/clients/web_static/images/remote/select-over.png +0 -0
  26. data/lib/ruku/clients/web_static/images/remote/select.png +0 -0
  27. data/lib/ruku/clients/web_static/images/remote/space1.png +0 -0
  28. data/lib/ruku/clients/web_static/images/remote/space2.png +0 -0
  29. data/lib/ruku/clients/web_static/images/remote/space3.png +0 -0
  30. data/lib/ruku/clients/web_static/images/remote/up-over.png +0 -0
  31. data/lib/ruku/clients/web_static/images/remote/up.png +0 -0
  32. data/lib/ruku/clients/web_static/images/spacer.gif +0 -0
  33. data/lib/ruku/clients/web_static/index.html +203 -0
  34. data/lib/ruku/clients/web_static/js/jquery-1.4.2.js +154 -0
  35. data/lib/ruku/clients/web_static/js/ruku.js +447 -0
  36. data/lib/ruku/remote.rb +138 -0
  37. data/lib/ruku/remotes.rb +78 -0
  38. data/lib/ruku/storage.rb +77 -0
  39. data/lib/ruku.rb +5 -0
  40. data/ruku.gemspec +31 -0
  41. data/test/helper.rb +11 -0
  42. data/test/js/qunit.css +119 -0
  43. data/test/js/qunit.js +1069 -0
  44. data/test/js/runner.html +29 -0
  45. data/test/js/test_remote.js +37 -0
  46. data/test/js/test_remote_manager.js +186 -0
  47. data/test/js/test_remote_menu.js +208 -0
  48. data/test/js/test_util.js +15 -0
  49. data/test/test_remote.rb +89 -0
  50. data/test/test_remotes.rb +144 -0
  51. data/test/test_simple_client.rb +166 -0
  52. data/test/test_simple_storage.rb +70 -0
  53. data/test/test_web_client.rb +46 -0
  54. data/test/test_yaml_storage.rb +54 -0
  55. metadata +156 -0
@@ -0,0 +1,196 @@
1
+ body {
2
+ background-color: #ddd;
3
+ font-size: 75%;
4
+ color: #222;
5
+ font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
6
+ text-align: center;
7
+ margin: 0;
8
+ padding: 0;
9
+ }
10
+
11
+ .buttonLink {
12
+ text-decoration: none;
13
+ color: #999;
14
+ border: 1px solid #999;
15
+ padding-left: 2px;
16
+ padding-right: 2px;
17
+ cursor: pointer;
18
+ }
19
+
20
+ .buttonLink:hover {
21
+ background-color: #ddd;
22
+ }
23
+
24
+ #topBar {
25
+ position: relative;
26
+ width: 320px;
27
+ margin-left: auto;
28
+ margin-right: auto;
29
+ background-color: #555;
30
+ padding-top: 6px;
31
+ padding-bottom: 7px;
32
+ }
33
+
34
+ #listRemotesButton {
35
+ position: absolute;
36
+ left: 8px;
37
+ color: #ccc;
38
+ text-decoration: none;
39
+ border: 1px solid #ccc;
40
+ padding: 2px;
41
+ border-radius: 2px;
42
+ }
43
+
44
+ #listRemotesButton:hover {
45
+ background-color: #777;
46
+ }
47
+
48
+ #activeRemoteTitle {
49
+ color: #eee;
50
+ font-size: 125%;
51
+ font-weight: bold;
52
+ }
53
+
54
+ #remote {
55
+ margin-left: auto;
56
+ margin-right: auto;
57
+ }
58
+
59
+ #remoteMenuContainer {
60
+ position: absolute;
61
+ top: 0px;
62
+ left: 0px;
63
+ width: 100%;
64
+ height: 100%;
65
+ overflow: hidden;
66
+ }
67
+
68
+ #remoteMenu {
69
+ position: relative;
70
+ width: 290px;
71
+ margin: auto;
72
+ margin-top: 50px;
73
+ padding: 8px;
74
+ background-color: #fff;
75
+ border: 3px solid #999;
76
+ overflow: auto;
77
+ z-index: 1002;
78
+ }
79
+
80
+ #remoteMenu .title {
81
+ width: 100%;
82
+ font-size: 100%;
83
+ padding-bottom: 8px;
84
+ margin-left: auto;
85
+ margin-right: auto;
86
+ border-bottom: 1px solid black;
87
+ text-align: center;
88
+ font-weight: bold;
89
+ }
90
+
91
+ #remoteMenu #closeButton {
92
+ position: absolute;
93
+ top: 4px;
94
+ right: 4px;
95
+ }
96
+
97
+ #remoteMenu #scanButton {
98
+ position: absolute;
99
+ top: 4px;
100
+ left: 4px;
101
+ }
102
+
103
+ #remoteMenu .remote {
104
+ margin-top: 8px;
105
+ }
106
+
107
+ #remoteMenu .remote > div {
108
+ display: inline-block;
109
+ }
110
+
111
+ #remoteMenu .activeRemoteRadio {
112
+ position: relative;
113
+ top: -15px;
114
+ left: -15px;
115
+ }
116
+
117
+ #remoteMenu .remote .info {
118
+ position: relative;
119
+ top: -5px;
120
+ }
121
+
122
+ #remoteMenu .remote .name {
123
+ border: 1px solid white;
124
+ font-size: 110%;
125
+ }
126
+
127
+ #remoteMenu .remote .over {
128
+ border: 1px solid black;
129
+ }
130
+
131
+ #remoteMenu .remote .host {
132
+ font-size: 90%;
133
+ color: orange;
134
+ text-align: left;
135
+ margin-left: 5px;
136
+ }
137
+
138
+ #remoteMenu .noRemotesMessage {
139
+ margin-top: 10px;
140
+ border: none;
141
+ }
142
+
143
+ #firstBoxInfo .message {
144
+ text-align: center;
145
+ font-weight: bold;
146
+ font-size: 125%;
147
+ margin-top: 10px;
148
+ }
149
+
150
+ #firstBoxInfo .boxInfo {
151
+ height: 90px;
152
+ }
153
+
154
+ #firstBoxInfo img, #firstBoxInfo .details {
155
+ float: left;
156
+ }
157
+
158
+ #firstBoxInfo img {
159
+ margin-top: 20px;
160
+ margin-left: 35px;
161
+ }
162
+
163
+ #firstBoxInfo .details {
164
+ margin-top: 30px;
165
+ margin-left: 20px;
166
+ }
167
+
168
+ #firstBoxInfo .details .name {
169
+ font-size: 130%;
170
+ }
171
+
172
+ #firstBoxInfo .details .host {
173
+ margin-top: 10px;
174
+ color: orange;
175
+ }
176
+
177
+ #firstBoxInfo .menu {
178
+ margin-top: 8px;
179
+ text-align: center;
180
+ }
181
+
182
+ #firstBoxInfo .menu .moreButton {
183
+ margin-left: 10px;
184
+ }
185
+
186
+ #manualAddBox {
187
+ margin-top: 20px;
188
+ }
189
+
190
+ #manualAddBox input {
191
+ margin-right: 5px;
192
+ }
193
+
194
+ .button {
195
+ cursor: pointer;
196
+ }
@@ -0,0 +1,203 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
+ "http://www.w3.org/TR/html4/loose.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
6
+
7
+ <!-- A little iPhone stuff -->
8
+ <meta name = "viewport" content = "width = device-width">
9
+ <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no">
10
+
11
+ <title>Ruku</title>
12
+ <link rel="stylesheet" href="css/ruku.css" type="text/css" media="screen" charset="utf-8" />
13
+ <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
14
+ <script type="text/javascript" src="js/ruku.js"></script>
15
+ <script type="text/javascript" charset="utf-8">
16
+ $(function() {
17
+ var remoteMenu = RUKU.createRemoteMenu($("#remoteMenu"), $("#activeRemoteTitle"));
18
+ remoteMenu.load();
19
+
20
+ $("#listRemotesButton").click(function() {
21
+ if ($("#remoteMenu").is(":visible")) {
22
+ remoteMenu.hide();
23
+ } else {
24
+ remoteMenu.listRemotes();
25
+ }
26
+ return false;
27
+ });
28
+
29
+ // Grab the command name from the src attribute of a command button
30
+ function name(elem) {
31
+ return elem.attr("src").split("/")[2].replace(".png", "").replace("-over", "");
32
+ }
33
+
34
+ // Grab a command button by the command name
35
+ function findByName(name) {
36
+ var elem;
37
+ $(".button").each(function() {
38
+ if ($(this).attr("src").indexOf(name) !== -1) {
39
+ elem = $(this);
40
+ return false;
41
+ }
42
+ });
43
+ return elem;
44
+ }
45
+
46
+ // Set a command button image to its highlighted form
47
+ function highlight(name) {
48
+ var elem = findByName(name);
49
+ if (elem && elem.attr("src").indexOf("-over") === -1) {
50
+ elem.attr("src", elem.attr("src").replace(name, name + "-over"));
51
+ }
52
+ }
53
+
54
+ // Set a command button image to its non-highlighted form
55
+ function unhighlight(name) {
56
+ var elem = findByName(name);
57
+ if (elem && elem.attr("src").indexOf(name + "-over") !== -1) {
58
+ elem.attr("src", elem.attr("src").replace(name + "-over", name));
59
+ }
60
+ }
61
+
62
+ // Set a command button image to its highlighted form for a moment, then back to non-highlighted
63
+ function flash(name) {
64
+ highlight(name);
65
+ window.setTimeout(function() {
66
+ unhighlight(name);
67
+ }, 200);
68
+ }
69
+
70
+ $(".button").hover(
71
+ function() {
72
+ $(this).attr("src", $(this).attr("src").replace(name($(this)), name($(this)) + "-over"));
73
+ },
74
+ function() {
75
+ $(this).attr("src", $(this).attr("src").replace(name($(this)) + "-over", name($(this))));
76
+ }
77
+ );
78
+
79
+ $(".button").click(function() {
80
+ var remote = remoteMenu.getActiveRemote();
81
+ if (remote) {
82
+ remote[name($(this))]();
83
+ }
84
+ return false;
85
+ });
86
+
87
+ // Make sure we can just use the keyboard for everything
88
+ var codes = {
89
+ "13":"select", // enter
90
+ "27":"home", // esc
91
+ "32":"pause", // space
92
+ "36":"home", // home
93
+ "37":"left",
94
+ "38":"up",
95
+ "39":"right",
96
+ "40":"down",
97
+ "66":"back", // b
98
+ "70":"fwd", // f
99
+
100
+ // Everybody loves vi!
101
+ "72":"left", // h
102
+ "74":"down", // j
103
+ "75":"up", // k
104
+ "76":"right" // l
105
+ };
106
+ $(document).keydown(function(event) {
107
+ // Do not repond to keyboard events when menu is open
108
+ if ($("#remoteMenu").is(":visible")) {
109
+ return;
110
+ }
111
+
112
+ var code = event.which;
113
+ if (code) {
114
+ var prop;
115
+ for (prop in codes) {
116
+ if (codes.hasOwnProperty(prop)) {
117
+ var cmd = codes[code];
118
+ if (cmd) {
119
+ var remote = remoteMenu.getActiveRemote();
120
+ if (remote) {
121
+ remote[cmd]();
122
+ flash(cmd);
123
+ }
124
+ break;
125
+ }
126
+ }
127
+ }
128
+ }
129
+ });
130
+ });
131
+ </script>
132
+ </head>
133
+ <body>
134
+ <div id="remoteMenuContainer" style="display:none;">
135
+ <div id="remoteMenu" style="display:none;">
136
+ <a id="closeButton" class="buttonLink" href="#">X close</a>
137
+ <a id="scanButton" class="buttonLink" href="#">scan for boxes</a>
138
+ <div class="title">Remotes Setup</div>
139
+ <div id="remoteList"></div>
140
+ <div id="firstBoxInfo" style="display:none;"></div>
141
+ </div>
142
+ </div>
143
+
144
+ <div id="topBar">
145
+ <a id="listRemotesButton" href="#">setup</a>
146
+ <div id="activeRemoteTitle">&nbsp;</div>
147
+ </div>
148
+ <table id="remote" width="320" height="369" border="0" cellpadding="0" cellspacing="0">
149
+ <tr>
150
+ <td colspan="2">
151
+ <img class="button" src="images/remote/home.png" width="82" height="104" alt=""></td>
152
+ <td colspan="5">
153
+ <img class="button" src="images/remote/up.png" width="151" height="104" alt=""></td>
154
+ <td colspan="2">
155
+ <img src="images/remote/space1.png" width="87" height="104" alt=""></td>
156
+ </tr>
157
+ <tr>
158
+ <td colspan="3">
159
+ <img class="button" src="images/remote/left.png" width="117" height="90" alt=""></td>
160
+ <td colspan="3">
161
+ <img class="button" src="images/remote/select.png" width="85" height="90" alt=""></td>
162
+ <td colspan="3">
163
+ <img class="button" src="images/remote/right.png" width="118" height="90" alt=""></td>
164
+ </tr>
165
+ <tr>
166
+ <td rowspan="2">
167
+ <img src="images/remote/space2.png" width="59" height="174" alt=""></td>
168
+ <td colspan="7">
169
+ <img class="button" src="images/remote/down.png" width="199" height="85" alt=""></td>
170
+ <td rowspan="2">
171
+ <img src="images/remote/space3.png" width="62" height="174" alt=""></td>
172
+ </tr>
173
+ <tr>
174
+ <td colspan="3">
175
+ <img class="button" src="images/remote/back.png" width="71" height="89" alt=""></td>
176
+ <td>
177
+ <img class="button" src="images/remote/pause.png" width="59" height="89" alt=""></td>
178
+ <td colspan="3">
179
+ <img class="button" src="images/remote/fwd.png" width="69" height="89" alt=""></td>
180
+ </tr>
181
+ <tr>
182
+ <td>
183
+ <img src="images/spacer.gif" width="59" height="1" alt=""></td>
184
+ <td>
185
+ <img src="images/spacer.gif" width="23" height="1" alt=""></td>
186
+ <td>
187
+ <img src="images/spacer.gif" width="35" height="1" alt=""></td>
188
+ <td>
189
+ <img src="images/spacer.gif" width="13" height="1" alt=""></td>
190
+ <td>
191
+ <img src="images/spacer.gif" width="59" height="1" alt=""></td>
192
+ <td>
193
+ <img src="images/spacer.gif" width="13" height="1" alt=""></td>
194
+ <td>
195
+ <img src="images/spacer.gif" width="31" height="1" alt=""></td>
196
+ <td>
197
+ <img src="images/spacer.gif" width="25" height="1" alt=""></td>
198
+ <td>
199
+ <img src="images/spacer.gif" width="62" height="1" alt=""></td>
200
+ </tr>
201
+ </table>
202
+ </body>
203
+ </html>