Graphiclious 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/README.txt +1 -0
  2. data/doc/extern.gif +0 -0
  3. data/doc/index.html +42 -9
  4. data/doc/screenshots/original/{cornflower.html → 01-blue-style-1.html} +5 -5
  5. data/doc/screenshots/original/{blue-style-1.jpg → 01-blue-style-1.jpg} +0 -0
  6. data/doc/screenshots/original/{blue-style-1.html → 02-cornflower.html} +5 -5
  7. data/doc/screenshots/original/{cornflower.jpg → 02-cornflower.jpg} +0 -0
  8. data/doc/screenshots/original/{sample-graph.html → 03-sample-graph.html} +5 -5
  9. data/doc/screenshots/original/{sample-graph.jpg → 03-sample-graph.jpg} +0 -0
  10. data/doc/screenshots/original/04-basic-style-js.html +37 -0
  11. data/doc/screenshots/original/04-basic-style-js.jpg +0 -0
  12. data/doc/screenshots/original/05-custom-style.html +37 -0
  13. data/doc/screenshots/original/05-custom-style.jpg +0 -0
  14. data/doc/screenshots/original/06-custom-style-js.html +37 -0
  15. data/doc/screenshots/original/06-custom-style-js.jpg +0 -0
  16. data/doc/screenshots/original/07-user-interface.html +37 -0
  17. data/doc/screenshots/original/07-user-interface.jpg +0 -0
  18. data/doc/screenshots/original/{custom-style.html → 08-ftp-upload.html} +5 -5
  19. data/doc/screenshots/original/08-ftp-upload.jpg +0 -0
  20. data/doc/screenshots/thumb.html +22 -10
  21. data/doc/screenshots/thumb/{t_blue-style-1.jpg → t_01-blue-style-1.jpg} +0 -0
  22. data/doc/screenshots/thumb/{t_cornflower.jpg → t_02-cornflower.jpg} +0 -0
  23. data/doc/screenshots/thumb/{t_sample-graph.jpg → t_03-sample-graph.jpg} +0 -0
  24. data/doc/screenshots/thumb/t_04-basic-style-js.jpg +0 -0
  25. data/doc/screenshots/thumb/t_05-custom-style.jpg +0 -0
  26. data/doc/screenshots/thumb/t_06-custom-style-js.jpg +0 -0
  27. data/doc/screenshots/thumb/t_07-user-interface.jpg +0 -0
  28. data/doc/screenshots/thumb/t_08-ftp-upload.jpg +0 -0
  29. data/doc/style.css +7 -4
  30. data/javascript/cloud.js +236 -0
  31. data/javascript/index.htm +24 -0
  32. data/javascript/link.js +25 -0
  33. data/javascript/style.css +52 -0
  34. data/lib/graphiclious.rb +6 -1
  35. data/lib/graphiclious/delicious2yaml.rb +75 -16
  36. data/lib/graphiclious/environment.rb +14 -1
  37. data/lib/graphiclious/ftp_browser.rb +53 -0
  38. data/lib/graphiclious/gui.rb +78 -24
  39. data/lib/graphiclious/help.rb +1 -0
  40. data/lib/graphiclious/version.rb +1 -1
  41. data/lib/graphiclious/yaml-links2html.rb +79 -64
  42. data/lib/graphiclious/yaml-links2js.rb +159 -0
  43. metadata +36 -19
  44. data/doc/screenshots/original/custom-style.jpg +0 -0
  45. data/doc/screenshots/original/user-interface.html +0 -37
  46. data/doc/screenshots/original/user-interface.jpg +0 -0
  47. data/doc/screenshots/thumb/t_custom-style.jpg +0 -0
  48. data/doc/screenshots/thumb/t_user-interface.jpg +0 -0
@@ -0,0 +1,236 @@
1
+ // -*-javascript-*-
2
+ // $Id: cloud.js 28 2006-08-25 01:23:38Z wsdng $
3
+ //
4
+
5
+ // Cloud constructor computes everything we need
6
+ // @param links is an Array with Link objects
7
+ function Cloud(links, varname, content_id)
8
+ {
9
+ this.links = links;
10
+ this.links_for_tag = new Array();
11
+ this.num_links_for_tag = new Array();
12
+ this.filter = new Array(); // which tags are filtered?
13
+ this.num_filtered = 0;
14
+ this.max_count = 1;
15
+ this.tags = new Array();
16
+ this.varname = varname;
17
+ this.content_id = content_id;
18
+ this.filtered_links = new Array();
19
+ this.num_filtered_links = 0;
20
+ this.visible_links = new Array();
21
+
22
+ // init hashes
23
+ for(var i in links)
24
+ {
25
+ var link_tags = links[i].tags;
26
+ for(var t in link_tags)
27
+ {
28
+ var tag = link_tags[t];
29
+ this.links_for_tag[tag] = new Array();
30
+ this.num_links_for_tag[tag] = 0;
31
+ this.filter[tag] = false;
32
+ }
33
+ }
34
+
35
+ // fill hashes
36
+ for(var i in links)
37
+ {
38
+ var link = links[i];
39
+ for(var t in link.tags)
40
+ {
41
+ var tag = link.tags[t];
42
+ this.links_for_tag[tag].push(link);
43
+ this.num_links_for_tag[tag] = this.num_links_for_tag[tag] + 1;
44
+ }
45
+ }
46
+
47
+ // order tags and compute max_count
48
+ for(var tag in this.num_links_for_tag)
49
+ {
50
+ this.tags.push(tag);
51
+ if(this.num_links_for_tag[tag] > this.max_count)
52
+ {
53
+ this.max_count = this.num_links_for_tag[tag];
54
+ }
55
+ }
56
+ this.tags.sort();
57
+ }
58
+ new Cloud(new Array());
59
+
60
+ Cloud.prototype.MAX_STYLES = 10;
61
+
62
+ // We use a logarithmic scale to compute a fixed
63
+ // number of styles depending on link counts
64
+ function Cloud_downscale(val)
65
+ {
66
+ return Math.max(2 * Math.log(val), 1);
67
+ }
68
+ Cloud.prototype.downscale = Cloud_downscale;
69
+
70
+ function Cloud_get_style(num_links)
71
+ {
72
+ var ratio = this.downscale(num_links)/this.downscale(this.max_count);
73
+ var floating_size = (this.MAX_STYLES - 1) * ratio
74
+ var size = Math.min(Math.round(floating_size), this.MAX_STYLES);
75
+ return 'cloud-' + size;
76
+ }
77
+ Cloud.prototype.get_style = Cloud_get_style;
78
+
79
+ function Cloud_count_filtered_links_for_tags()
80
+ {
81
+ for(tag in this.num_links_for_tag)
82
+ {
83
+ this.num_links_for_tag[tag] = 0;
84
+ }
85
+ this.max_count = 0;
86
+ for(var i in this.filtered_links)
87
+ {
88
+ var link = this.filtered_links[i];
89
+ for(var t in link.tags)
90
+ {
91
+ var tag = link.tags[t];
92
+ this.num_links_for_tag[tag] = this.num_links_for_tag[tag] + 1;
93
+ }
94
+ }
95
+ for(var tag in this.num_links_for_tag)
96
+ {
97
+ if(this.num_links_for_tag[tag] > this.max_count)
98
+ {
99
+ this.max_count = this.num_links_for_tag[tag];
100
+ }
101
+ }
102
+ }
103
+ Cloud.prototype.count_filtered_links_for_tags = Cloud_count_filtered_links_for_tags;
104
+
105
+ function Cloud_get_cloud_node()
106
+ {
107
+ var div = document.createElement('div');
108
+ div.className = 'cloud';
109
+ var header = document.createElement('span');
110
+ header.appendChild(document.createTextNode("Choose tags:"));
111
+ header.className = 'header_cloud';
112
+ div.appendChild(header);
113
+ div.appendChild(document.createTextNode(" \n"));
114
+ for(var i in this.tags)
115
+ {
116
+ var tag = this.tags[i];
117
+ if(this.filter[tag] == false && this.num_links_for_tag[tag] > 0){
118
+ var span = document.createElement('span');
119
+ span.className = this.get_style(this.num_links_for_tag[tag]);
120
+ var tag_node = document.createTextNode(tag);
121
+ var ankor = document.createElement('a');
122
+ ankor.href = 'javascript:' + this.varname + ".add_filter('" + tag + "')";
123
+ ankor.appendChild(tag_node);
124
+ span.appendChild(ankor);
125
+ div.appendChild(span);
126
+ div.appendChild(document.createTextNode(" \n"));
127
+ }
128
+ }
129
+ return div;
130
+ }
131
+ Cloud.prototype.get_cloud_node = Cloud_get_cloud_node;
132
+
133
+ function Cloud_get_filter_node()
134
+ {
135
+ var div = document.createElement('div');
136
+ div.className = 'filter';
137
+ var header = document.createElement('span');
138
+ header.appendChild(document.createTextNode(
139
+ "Filtered tags (click on tag to remove it from list):"));
140
+ header.className = 'header_filter';
141
+ div.appendChild(header);
142
+ div.appendChild(document.createTextNode(" \n"));
143
+ for(var i in this.tags)
144
+ {
145
+ var tag = this.tags[i];
146
+ if(this.filter[tag] == true){
147
+ var span = document.createElement('span');
148
+ var tag_node = document.createTextNode(tag);
149
+ var ankor = document.createElement('a');
150
+ ankor.href = 'javascript:' + this.varname + ".remove_filter('" + tag + "')";
151
+ ankor.appendChild(tag_node);
152
+ span.appendChild(ankor);
153
+ div.appendChild(span);
154
+ div.appendChild(document.createTextNode(" \n"));
155
+ }
156
+ }
157
+ return div;
158
+ }
159
+ Cloud.prototype.get_filter_node = Cloud_get_filter_node;
160
+
161
+ function Cloud_filter_links()
162
+ {
163
+ this.filtered_links = new Array();
164
+ this.num_filtered_links = 0;
165
+ this.visible_links = new Array();
166
+ for(var l in this.links)
167
+ {
168
+ var link = links[l];
169
+ var matched = 0;
170
+ var unmatched = 0;
171
+ for(t in link.tags){
172
+ if(this.filter[link.tags[t]]){
173
+ matched++;
174
+ } else {
175
+ unmatched++;
176
+ }
177
+ }
178
+ if(matched == this.num_filtered){
179
+ this.filtered_links.push(link);
180
+ this.num_filtered_links++;
181
+ if(matched > unmatched){
182
+ this.visible_links.push(link);
183
+ }
184
+ }
185
+ }
186
+ this.count_filtered_links_for_tags();
187
+ }
188
+ Cloud.prototype.filter_links = Cloud_filter_links;
189
+
190
+ function Cloud_subst()
191
+ {
192
+ this.filter_links();
193
+ var content = document.getElementById(this.content_id);
194
+ var div = document.createElement('div');
195
+ if(this.num_filtered > 0){
196
+ div.appendChild(this.get_filter_node());
197
+ }
198
+ var list_to_show = this.visible_links;
199
+ if(this.num_filtered_links <= 10){
200
+ list_to_show = this.filtered_links;
201
+ } else {
202
+ div.appendChild(this.get_cloud_node());
203
+ }
204
+ var ul = document.createElement("ul");
205
+ ul.className = 'link_list';
206
+ for(var l in list_to_show)
207
+ {
208
+ var link = list_to_show[l];
209
+ var li = document.createElement("li");
210
+ ul.appendChild(li);
211
+ link.to_html(li);
212
+ }
213
+ div.appendChild(ul);
214
+ content.replaceChild(div, content.firstChild);
215
+ }
216
+ Cloud.prototype.subst = Cloud_subst;
217
+
218
+ function Cloud_add_filter(tag)
219
+ {
220
+ if(this.filter[tag] == false){
221
+ this.num_filtered++;
222
+ this.filter[tag] = true;
223
+ }
224
+ this.subst();
225
+ }
226
+ Cloud.prototype.add_filter = Cloud_add_filter;
227
+
228
+ function Cloud_remove_filter(tag)
229
+ {
230
+ if(this.filter[tag] == true){
231
+ this.num_filtered--;
232
+ this.filter[tag] = false;
233
+ }
234
+ this.subst();
235
+ }
236
+ Cloud.prototype.remove_filter = Cloud_remove_filter;
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
+ <!-- $Id: index.htm 29 2006-08-25 14:41:24Z wsdng $ -->
3
+ <html>
4
+ <head>
5
+ <link rel="stylesheet" type="text/css" href="style.css">
6
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
7
+ </head>
8
+ <body>
9
+ <h1>my bookmarks</h1>
10
+ <div class="main">
11
+ <noscript>Sorry, but this page requires javascript!</noscript>
12
+ <script src="link.js"></script>
13
+ <script src="_all.js"></script>
14
+ <script src="cloud.js"></script>
15
+ <div id="content">
16
+ <div></div>
17
+ </div>
18
+ </div>
19
+ <script>
20
+ <!--
21
+ cloud = new Cloud(links, 'cloud', 'content');
22
+ cloud.subst(links);
23
+ //-->
24
+ </script>
@@ -0,0 +1,25 @@
1
+ // -*-javascript-*-
2
+ // $Id: link.js 22 2006-08-19 20:29:12Z wsdng $
3
+
4
+ // Representing tagged hyperlink
5
+ function Link(href, tags, desc)
6
+ {
7
+ this.href = href;
8
+ this.tags = tags;
9
+ this.desc = desc;
10
+ }
11
+ new Link('', new Array(), '');
12
+
13
+ function Link_to_html(parent)
14
+ {
15
+ var ankor = document.createElement("a");
16
+ ankor.className = "extern"
17
+ ankor.href = this.href;
18
+ ankor.appendChild(document.createTextNode(this.desc));
19
+
20
+ parent.appendChild(ankor);
21
+ parent.appendChild(document.createElement("br"));
22
+ parent.appendChild(document.createTextNode('tags: ' + this.tags.join(", ")));
23
+ parent.appendChild(document.createElement("br"));
24
+ }
25
+ Link.prototype.to_html = Link_to_html;
@@ -0,0 +1,52 @@
1
+ .filter{
2
+ margin-bottom:1em;
3
+ }
4
+
5
+ .header_filter{
6
+ color:black;
7
+ font-weight:bold;
8
+ }
9
+
10
+ .cloud{
11
+ margin-bottom:1em;
12
+ }
13
+
14
+ .header_cloud{
15
+ color:white;
16
+ background-color:black;
17
+ font-weight:bold;
18
+ }
19
+
20
+ .link_list{
21
+ }
22
+
23
+ .cloud-1{
24
+ font-size:0.8em
25
+ }
26
+ .cloud-2{
27
+ font-size:0.9em
28
+ }
29
+ .cloud-3{
30
+ font-size:1.0em
31
+ }
32
+ .cloud-4{
33
+ font-size:1.1em
34
+ }
35
+ .cloud-5{
36
+ font-size:1.2em
37
+ }
38
+ .cloud-6{
39
+ font-size:1.3em
40
+ }
41
+ .cloud-7{
42
+ font-size:1.4em
43
+ }
44
+ .cloud-8{
45
+ font-size:1.5em
46
+ }
47
+ .cloud-9{
48
+ font-size:1.6em
49
+ }
50
+ .cloud-10{
51
+ font-size:1.7em
52
+ }
data/lib/graphiclious.rb CHANGED
@@ -6,6 +6,7 @@ require 'getoptlong'
6
6
  getOpt = GetoptLong.new(["--user", "-u", GetoptLong::REQUIRED_ARGUMENT],
7
7
  ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
8
8
  ["--gui", "-g", GetoptLong::NO_ARGUMENT],
9
+ ["--nomap", "-m", GetoptLong::NO_ARGUMENT],
9
10
  ["--noupdate", "-l", GetoptLong::NO_ARGUMENT],
10
11
  ["--nohtml", "-o", GetoptLong::NO_ARGUMENT],
11
12
  ["--bundles", "-b", GetoptLong::NO_ARGUMENT],
@@ -46,12 +47,14 @@ password = opts["--password"]
46
47
 
47
48
  if opts["--gui"]
48
49
  require 'graphiclious/gui'
49
- application = Fox::FXApp.new("Graphiclious", "Sascha D?rdelmann")
50
+ application = Fox::FXApp.new("Graphiclious", "Sascha Drdelmann")
50
51
  window = GraphicliousMainWindow.new(application, user, password)
51
52
  window.setOptionFetch(!opts["--noupdate"])
52
53
  window.setOptionGenerate(!opts["--nohtml"])
53
54
  window.setOptionDelicious(opts["--delicious"])
54
55
  window.setOptionBundles(opts["--bundles"])
56
+ window.setOptionGraphViews(!opts["--nomap"])
57
+ window.setOptionGraphThumbs(!opts["--nomap"])
55
58
  application.addSignal("SIGINT", window.method(:onCmdQuit))
56
59
  application.create
57
60
  application.run
@@ -70,6 +73,8 @@ else
70
73
  require 'graphiclious/yaml-links2html'
71
74
  exporter = YamlLinksToHtml.new
72
75
  exporter.link_to_delicious_if_possible = opts["--delicious"]
76
+ exporter.build_graph_thumbs = !opts["--nomap"]
77
+ exporter.include_graph_views = !opts["--nomap"]
73
78
  exporter.run
74
79
  end
75
80
  end
@@ -2,6 +2,7 @@
2
2
  #$Id: delicious2yaml.rb,v 1.8 2006/03/07 23:39:04 wsdng Exp $
3
3
 
4
4
  require_gem 'Rubilicious'
5
+ require 'net/https'
5
6
 
6
7
  if(Rubilicious::VERSION == '0.1.5')
7
8
  class Rubilicious
@@ -16,6 +17,48 @@ if(Rubilicious::VERSION == '0.1.5')
16
17
  end
17
18
  end
18
19
 
20
+ class Rubilicious
21
+ #
22
+ # Low-level HTTPS GET.
23
+ # SDo used the tip at
24
+ # http://ruby.about.com/od/tutorials/ss/delicious_tags_4.htm
25
+ # to get Rubilicious code working
26
+ def https_get(url)
27
+ # get proxy info
28
+ proxy_host, proxy_port = find_http_proxy
29
+ # $stderr.puts "DEBUG: proxy: host = #{proxy_host}, port = #{proxy_port}"
30
+
31
+ # get host, port, and base URI for API queries
32
+ uri = URI::parse(@base_uri)
33
+ base = uri.request_uri
34
+
35
+ # prepend base to url
36
+ url = "#{base}/#{url}"
37
+
38
+ # connect to delicious
39
+ http = Net::HTTP.Proxy(proxy_host, proxy_port).new(uri.host, uri.port)
40
+ http.use_ssl = true
41
+ http.start
42
+
43
+ # get URL, check for error
44
+ resp = http.get(url, @headers)
45
+ unless resp.code =~ /2\d{2}/
46
+ puts base
47
+ puts url
48
+ raise "HTTP #{resp.code}: #{resp.message}"
49
+ end
50
+
51
+ # close HTTP connection, return response
52
+ http.finish
53
+ resp.body
54
+ end
55
+
56
+ # del.icio.us-API change 08/2006!
57
+ def http_get(url)
58
+ https_get(url)
59
+ end
60
+ end
61
+
19
62
  require 'yaml'
20
63
  require 'graphiclious/utf8'
21
64
 
@@ -33,6 +76,8 @@ class Delicious2Yaml
33
76
 
34
77
  def create_interface
35
78
  @interface = Rubilicious.new(@user, @password)
79
+ @interface.base_uri = 'https://api.del.icio.us/v1'
80
+ @interface
36
81
  end
37
82
 
38
83
  def set_working_dir(new_working_dir)
@@ -173,15 +218,38 @@ class Delicious2Yaml
173
218
 
174
219
  # store links as yaml file, delete previously stored links
175
220
  # if overwrite == true (default)
176
- def store_new(newLinks, overwrite=true)
177
- return false if !newLinks || newLinks.empty?
178
- cache = overwrite ? Hash.new : get_locally_stored_links
179
- newLinks.each do
221
+ def store_new(new_links, overwrite=true)
222
+ return false if !new_links || new_links.empty?
223
+ old = get_locally_stored_links
224
+ result = Hash.new
225
+ result.replace(old) unless overwrite
226
+ diff = Hash.new
227
+ new_links.each do
180
228
  |link|
181
- # writeLineOnProtokoll "\tGot #{link['href']}"
182
- cache[link['hash']] = Graphiclious.link_with_utf8_strings(link)
229
+ result_link = Graphiclious.link_with_utf8_strings(link)
230
+ key = link['hash']
231
+ if(result_link) != old[key]
232
+ diff[key] = result_link
233
+ end
234
+ result[key] = result_link
183
235
  end
184
- store_links(cache)
236
+ create_output_dir
237
+ if(old.size > result.size)
238
+ writeLineOnProtokoll "Possible error:"
239
+ writeLineOnProtokoll "There have been more links deleted than added!"
240
+ File.open("#{file_base}.old.yaml", 'w') { |out|
241
+ YAML.dump(old, out)
242
+ }
243
+ writeLineOnProtokoll "Wrote backup-file #{file_base}.old.yaml"
244
+ end
245
+ File.open("#{file_base}.diff.yaml", 'w') { |out|
246
+ YAML.dump(diff, out)
247
+ }
248
+ File.open("#{file_base}.yaml", 'w') { |out|
249
+ YAML.dump(result, out)
250
+ }
251
+ writeLineOnProtokoll "#{diff.keys.size.to_s} links new or changed"
252
+ writeLineOnProtokoll "#{result.keys.size.to_s} links availiable"
185
253
  true
186
254
  end
187
255
 
@@ -195,15 +263,6 @@ class Delicious2Yaml
195
263
  end
196
264
  cache
197
265
  end
198
-
199
- # store given links into delicious*.yaml file
200
- def store_links(cache)
201
- create_output_dir
202
- File.open("#{file_base}.yaml", 'w') { |out|
203
- YAML.dump(cache, out)
204
- }
205
- writeLineOnProtokoll "#{cache.keys.size.to_s} links availiable"
206
- end
207
266
  end
208
267
 
209
268
  if $0 == __FILE__