Graphiclious 0.1.0 → 0.1.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 (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__