Graphiclious 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +126 -0
- data/Rakefile +28 -0
- data/bin/graphiclious +3 -0
- data/doc/cloud.jpg +0 -0
- data/doc/index.html +32 -0
- data/doc/screenshots/default.css +44 -0
- data/doc/screenshots/original/blue-style-1.html +37 -0
- data/doc/screenshots/original/blue-style-1.jpg +0 -0
- data/doc/screenshots/original/cornflower.html +37 -0
- data/doc/screenshots/original/cornflower.jpg +0 -0
- data/doc/screenshots/original/custom-style.html +37 -0
- data/doc/screenshots/original/custom-style.jpg +0 -0
- data/doc/screenshots/original/sample-graph.html +37 -0
- data/doc/screenshots/original/sample-graph.jpg +0 -0
- data/doc/screenshots/original/user-interface.html +37 -0
- data/doc/screenshots/original/user-interface.jpg +0 -0
- data/doc/screenshots/thumb.html +46 -0
- data/doc/screenshots/thumb/t_blue-style-1.jpg +0 -0
- data/doc/screenshots/thumb/t_cornflower.jpg +0 -0
- data/doc/screenshots/thumb/t_custom-style.jpg +0 -0
- data/doc/screenshots/thumb/t_sample-graph.jpg +0 -0
- data/doc/screenshots/thumb/t_user-interface.jpg +0 -0
- data/doc/style.css +60 -0
- data/gemspec.rb +45 -0
- data/lib/graphiclious.rb +78 -0
- data/lib/graphiclious/delicious2yaml.rb +235 -0
- data/lib/graphiclious/dot_attributes.rb +35 -0
- data/lib/graphiclious/environment.rb +36 -0
- data/lib/graphiclious/gui.rb +260 -0
- data/lib/graphiclious/help.rb +22 -0
- data/lib/graphiclious/require_fox.rb +12 -0
- data/lib/graphiclious/url_graph.rb +135 -0
- data/lib/graphiclious/utf8.rb +19 -0
- data/lib/graphiclious/version.rb +8 -0
- data/lib/graphiclious/yaml-links2html.rb +476 -0
- data/options.yaml +7 -0
- data/styles/blue-style-1/dot-attributes.yaml +21 -0
- data/styles/blue-style-1/extern.gif +0 -0
- data/styles/blue-style-1/style.css +128 -0
- data/styles/cornflower/cornflower.png +0 -0
- data/styles/cornflower/dot-attributes.yaml +21 -0
- data/styles/cornflower/extern.gif +0 -0
- data/styles/cornflower/h3.gif +0 -0
- data/styles/cornflower/menuitem.png +0 -0
- data/styles/cornflower/menuselected.png +0 -0
- data/styles/cornflower/style.css +149 -0
- data/styles/cornflower/tr-edge.png +0 -0
- data/test/test_delicious2yaml.rb +97 -0
- data/wickie +249 -0
- metadata +119 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#$Id: utf8.rb,v 1.2 2005/05/05 13:37:59 wsdng Exp $
|
3
|
+
|
4
|
+
module Graphiclious
|
5
|
+
def self.utf8_as_string(aString)
|
6
|
+
return aString.unpack("U*").pack("C*")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.string_as_utf8(aString)
|
10
|
+
aString.unpack("C*").pack("U*")
|
11
|
+
end
|
12
|
+
|
13
|
+
# Convert link as provided by del.icio.us via rubilicious
|
14
|
+
# to link containing utf8 strings for description and extended
|
15
|
+
# information
|
16
|
+
def self.link_with_utf8_strings(link)
|
17
|
+
link
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,476 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#$Id: yaml-links2html.rb,v 1.20 2006/03/09 22:57:52 wsdng Exp $
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'ftools'
|
6
|
+
require 'graphiclious/environment'
|
7
|
+
require 'graphiclious/url_graph'
|
8
|
+
|
9
|
+
class YamlLinksToHtml
|
10
|
+
DEL_ICIO_US_URL = "http://del.icio.us"
|
11
|
+
STYLES_FOLDER = File.join(GRAPHICLIOUS_PATH, "styles")
|
12
|
+
MAX_STYLES_IN_CLOUD = 10
|
13
|
+
CLOUD_STYLES = (1..MAX_STYLES_IN_CLOUD).collect{ |size| 'cloud-' + size.to_s }
|
14
|
+
|
15
|
+
attr_accessor(:link_to_delicious_if_possible, :use_bundles, :include_graph_views, :build_graph_thumbs, :include_private)
|
16
|
+
|
17
|
+
# Lazy require things which some users won't use
|
18
|
+
def check_prerequisites
|
19
|
+
require 'RMagick' if @build_graph_thumbs
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.guess_styles
|
23
|
+
guess_styles_within(STYLES_FOLDER)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.guess_styles_within(folder)
|
27
|
+
Dir[File.join(folder, '*', 'dot-attributes.yaml')].collect {
|
28
|
+
|filename|
|
29
|
+
File.dirname(filename)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.guess_users_within(folder)
|
34
|
+
Dir[File.join(folder, '*', 'delicious.yaml')].collect {
|
35
|
+
|filename|
|
36
|
+
File.dirname(filename)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_working_dir(new_working_dir)
|
41
|
+
@working_dir = new_working_dir
|
42
|
+
set_user(@user)
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_user(user)
|
46
|
+
@user = user
|
47
|
+
@input_file = File.join(@working_dir, @user, 'delicious.yaml')
|
48
|
+
@html_output_path = File.join(@working_dir, @user, 'html')
|
49
|
+
@bundles_file = File.join(@working_dir, @user, 'bundles.yaml')
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_style style
|
53
|
+
@style = style
|
54
|
+
@dot_attribut_file = "#{@style}/dot-attributes.yaml"
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize
|
58
|
+
@include_private = false
|
59
|
+
@working_dir = Dir.getwd
|
60
|
+
set_style(YamlLinksToHtml.guess_styles[0])
|
61
|
+
set_user(YamlLinksToHtml.guess_users_within(@working_dir)[0])
|
62
|
+
@link_to_delicious_if_possible = false
|
63
|
+
@use_bundles = false
|
64
|
+
@include_graph_views = false
|
65
|
+
@build_graph_thumbs = @include_graph_views
|
66
|
+
end
|
67
|
+
|
68
|
+
def copy_style_to_user
|
69
|
+
['dot-attributes.yaml', '*.jpg', '*.png', '*.gif', '*.css'].each do
|
70
|
+
|pattern|
|
71
|
+
Dir[File.join(@style, pattern)].each do
|
72
|
+
|template_file|
|
73
|
+
write_line_on_protokol("Copy #{template_file} to #{@user}")
|
74
|
+
File.copy(template_file, File.join(@working_dir, @user))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_protocol_block(aProc)
|
80
|
+
@protocol_block = aProc
|
81
|
+
end
|
82
|
+
|
83
|
+
def write_line_on_protokol(lineString)
|
84
|
+
puts lineString
|
85
|
+
unless @protocol_block.nil?
|
86
|
+
@protocol_block.call(lineString)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# methods for html-generation
|
91
|
+
|
92
|
+
def os_file_join(dir, file)
|
93
|
+
if RUBY_PLATFORM =~ /win32/
|
94
|
+
File.join(dir, file).gsub(File::SEPARATOR, "\\")
|
95
|
+
else
|
96
|
+
File.join(dir, file)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def downscale(val)
|
101
|
+
(2 * Math.log(val)).round
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_cloud_style(val, maxval)
|
105
|
+
quot = downscale(maxval)
|
106
|
+
quot = 1 if quot == 0
|
107
|
+
index = (MAX_STYLES_IN_CLOUD - 1) * downscale(val) / quot
|
108
|
+
if(index >= MAX_STYLES_IN_CLOUD)
|
109
|
+
puts "Corrected index of cloud style for #{val} from #{index} to #{MAX_STYLES_IN_CLOUD}"
|
110
|
+
index = MAX_STYLES_IN_CLOUD
|
111
|
+
end
|
112
|
+
CLOUD_STYLES[index]
|
113
|
+
end
|
114
|
+
|
115
|
+
def delicious_tag_url(tag1, *other_tags)
|
116
|
+
url = "#{DEL_ICIO_US_URL}/tag/#{tag1}"
|
117
|
+
other_tags.each { |tag| url = "#{url}+#{tag}" }
|
118
|
+
url + '?settagview=cloud'
|
119
|
+
end
|
120
|
+
|
121
|
+
def delicious_user_url(tag1, *other_tags)
|
122
|
+
url = "#{DEL_ICIO_US_URL}/#{@user}/#{tag1}"
|
123
|
+
other_tags.each { |tag| url = "#{url}+#{tag}" }
|
124
|
+
url + '?settagview=cloud'
|
125
|
+
end
|
126
|
+
|
127
|
+
def write_html_head_on(fp)
|
128
|
+
fp.puts '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'
|
129
|
+
fp.puts '<html><head>'
|
130
|
+
fp.puts '<meta http-equiv="content-type" content="text/html; charset=UTF-8">'
|
131
|
+
fp.puts '<link rel="stylesheet" type="text/css" href="../style.css">'
|
132
|
+
fp.puts '</head><body>'
|
133
|
+
end
|
134
|
+
|
135
|
+
def write_html_tail_on(fp)
|
136
|
+
fp.puts '</body></html>'
|
137
|
+
end
|
138
|
+
|
139
|
+
def menuitem(name, id, url)
|
140
|
+
if(name == id)
|
141
|
+
"<div class=\"menuselected\">#{name}</div>"
|
142
|
+
else
|
143
|
+
"<div class=\"menuitem\"><a href=\"#{url}\">#{name}</a></div>"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def link_index_on(fp, id='none', bundles={})
|
148
|
+
fp.puts '<div class="mainmenu">'|| @checkBundles.checked?
|
149
|
+
fp.puts menuitem('cloud (all)', id, 'index.htm')
|
150
|
+
unless bundles.empty?
|
151
|
+
bundles.keys.sort.each do
|
152
|
+
|bundle|
|
153
|
+
unless bundle == 'unbundled'
|
154
|
+
fp.puts menuitem(bundle, id, "bundle_#{bundle}.htm")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
unless bundles['unbundled'].empty?
|
158
|
+
fp.puts menuitem('unbundled', id, "bundle_unbundled.htm")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
fp.puts '</div>'
|
162
|
+
end
|
163
|
+
|
164
|
+
def write_overview(filename, cloud_name, list, bundles, links_by_tag)
|
165
|
+
valid_list = list.reject { |tag|
|
166
|
+
links_by_tag[tag].nil? # doesn't make sense but seems to be possible
|
167
|
+
}
|
168
|
+
File.open(File.join(@html_output_path, filename), 'w') do
|
169
|
+
| fp |
|
170
|
+
write_html_head_on(fp)
|
171
|
+
fp.puts "<h1>Tag overview: #{cloud_name}</h1>"
|
172
|
+
link_index_on(fp, cloud_name, bundles)
|
173
|
+
fp.puts '<div class="main">'
|
174
|
+
fp.puts "<h3>Tags, size representing number of links</h3>"
|
175
|
+
max_num_links = valid_list.collect{ |tag| links_by_tag[tag].size }.max
|
176
|
+
valid_list.each do
|
177
|
+
|tag|
|
178
|
+
style = get_cloud_style(links_by_tag[tag].size, max_num_links)
|
179
|
+
fp.puts(UrlGraph.node_ankor(tag, style))
|
180
|
+
end
|
181
|
+
if(@include_graph_views)
|
182
|
+
name = cloud_name_to_graph_name(cloud_name)
|
183
|
+
fp.puts "<h3>Graph of tag relations</h3>"
|
184
|
+
|
185
|
+
link_desc = if(@build_graph_thumbs)
|
186
|
+
"<img src=\"#{convert_to_thumbnail_filename(name + '.gif')}\">"
|
187
|
+
else
|
188
|
+
'view it'
|
189
|
+
end
|
190
|
+
fp.puts "<a href=\"#{name}.htm\">#{link_desc}</a>"
|
191
|
+
fp.puts '</div>'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def sorted_links(links)
|
197
|
+
links.sort { |l1, l2| l1['description'] <=> l2['description'] }
|
198
|
+
end
|
199
|
+
|
200
|
+
def write_link_on(link, fp, skip_tags = [])
|
201
|
+
fp.puts(UrlGraph.ankor(link['href'], link['description']))
|
202
|
+
info = link['extended']
|
203
|
+
if info
|
204
|
+
fp.puts('<br>')
|
205
|
+
fp.puts("#{info}")
|
206
|
+
end
|
207
|
+
other_tags = link['tags'].reject { |t| skip_tags.include?(t) }
|
208
|
+
unless other_tags.empty?
|
209
|
+
fp.puts('<br>')
|
210
|
+
fp.puts('More tags: ')
|
211
|
+
other_tags.each { |t|
|
212
|
+
fp.puts(UrlGraph.node_ankor(t))
|
213
|
+
}
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# create an empty graph with dot attributes of chosen style
|
218
|
+
def init_tag_graph
|
219
|
+
@tag_graph = UrlGraph.new
|
220
|
+
if File.exists?(@dot_attribut_file)
|
221
|
+
@tag_graph.fixed_dot_attributes = File.open(@dot_attribut_file, 'r') { |io|
|
222
|
+
YAML.load(io)
|
223
|
+
}
|
224
|
+
else
|
225
|
+
# write out the default-attribute-file to make
|
226
|
+
# things easy to configure
|
227
|
+
File.open(@dot_attribut_file, 'w') { |out|
|
228
|
+
YAML.dump(@tag_graph.fixed_dot_attributes, out)
|
229
|
+
}
|
230
|
+
write_line_on_protokol "Wrote #{@dot_attribut_file}, change to adopt different style."
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def load_links
|
235
|
+
# load yaml-file containing links as a hash
|
236
|
+
cache = File.open(@input_file, 'r') { |io|
|
237
|
+
YAML.load(io)
|
238
|
+
}
|
239
|
+
links = cache.values
|
240
|
+
unless(@include_private)
|
241
|
+
links = links.reject { |l| l['shared'] =~ /no/ }
|
242
|
+
end
|
243
|
+
@links_by_tag = Hash.new
|
244
|
+
@links_by_edge = Hash.new
|
245
|
+
links.each do
|
246
|
+
|link|
|
247
|
+
tagsOfLink = link['tags']
|
248
|
+
n = tagsOfLink.size - 1
|
249
|
+
(0..n).each do
|
250
|
+
|i|
|
251
|
+
tag = tagsOfLink[i]
|
252
|
+
unless @links_by_tag.has_key?(tag)
|
253
|
+
@links_by_tag[tag] = Array.new
|
254
|
+
@tag_graph.add_vertex(tag)
|
255
|
+
end
|
256
|
+
@links_by_tag[tag].push(link)
|
257
|
+
(i+1..n).each do
|
258
|
+
|j|
|
259
|
+
otherTag = tagsOfLink[j]
|
260
|
+
# write_line_on_protokol "\t#{tag}<->#{otherTag}"
|
261
|
+
@tag_graph.add_edge(tag, otherTag)
|
262
|
+
edge_name = UrlGraph.edge_name(tag, otherTag)
|
263
|
+
unless @links_by_edge.has_key?(edge_name)
|
264
|
+
@links_by_edge[edge_name] = Array.new
|
265
|
+
end
|
266
|
+
@links_by_edge[edge_name].push(link)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# load bundles file
|
272
|
+
@bundles = {}
|
273
|
+
if @use_bundles
|
274
|
+
@bundles = File.open(@bundles_file, 'r') { |io|
|
275
|
+
YAML.load(io)
|
276
|
+
}
|
277
|
+
set_of_unbundled_tags = {}
|
278
|
+
@tag_graph.each { |tag| set_of_unbundled_tags[tag] = tag }
|
279
|
+
@bundles.keys.each { |bundle|
|
280
|
+
@bundles[bundle].each { |tag|
|
281
|
+
set_of_unbundled_tags.delete(tag)
|
282
|
+
}
|
283
|
+
}
|
284
|
+
@bundles['unbundled'] = set_of_unbundled_tags.values.sort
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def fatal(msg)
|
289
|
+
write_line_on_protokol(msg)
|
290
|
+
exit(1)
|
291
|
+
end
|
292
|
+
|
293
|
+
def thumbnail(filename)
|
294
|
+
thumb_name = convert_to_thumbnail_filename(filename)
|
295
|
+
write_line_on_protokol("Writing thumbnail #{thumb_name} for #{filename}")
|
296
|
+
img = Magick::Image.read(filename)[0]
|
297
|
+
thumb = img.thumbnail(100, 100)
|
298
|
+
thumb.write(thumb_name)
|
299
|
+
end
|
300
|
+
|
301
|
+
# name.extension will result in name.thumb.extension
|
302
|
+
def convert_to_thumbnail_filename(filename)
|
303
|
+
parts = filename.split('.')
|
304
|
+
ext = parts.pop
|
305
|
+
parts[0..-1].push('thumb').push(ext).join('.')
|
306
|
+
end
|
307
|
+
|
308
|
+
def do_graphviz(tag_graph, cloud_name)
|
309
|
+
return unless @include_graph_views
|
310
|
+
name = cloud_name_to_graph_name(cloud_name)
|
311
|
+
# Write Graphviz-File
|
312
|
+
tmpDotFile = 'graph.dot~'
|
313
|
+
tag_graph.print_dotted_on_file(tmpDotFile)
|
314
|
+
write_line_on_protokol "Wrote #{tmpDotFile} for temporary use, feel free to delete later."
|
315
|
+
|
316
|
+
# Use Graphviz to create HTML with client-side imagemap
|
317
|
+
os_gif_file = os_file_join(@html_output_path, "#{name}.gif")
|
318
|
+
dot_command = "dot -Tgif #{tmpDotFile} -o #{os_gif_file}"
|
319
|
+
system(dot_command) || fatal("Error can't execute #{dot_command}\nPlease check your graphviz installation")
|
320
|
+
write_line_on_protokol "Wrote #{os_gif_file}."
|
321
|
+
graph_htm = File.join(@html_output_path, "#{name}.htm")
|
322
|
+
os_graph_htm = os_file_join(@html_output_path, "#{name}.htm")
|
323
|
+
File.open(graph_htm, 'w') { |fp|
|
324
|
+
write_html_head_on(fp)
|
325
|
+
fp.puts("<h1>Tag graph: #{cloud_name} </h1>")
|
326
|
+
link_index_on(fp, '', @bundles)
|
327
|
+
fp.puts '<div class="main">'
|
328
|
+
fp.puts '<IMG SRC="' + "#{name}.gif" + '" USEMAP=#UrlGraph>'
|
329
|
+
fp.puts '</div>'
|
330
|
+
}
|
331
|
+
dot_command = "dot -Tcmapx #{tmpDotFile} -o graph.htm~"
|
332
|
+
system(dot_command) || fatal("Failed system call: #{dot_command}")
|
333
|
+
File.open(graph_htm, 'a') { |fp|
|
334
|
+
File.open('graph.htm~'){ |fp2| fp2.each_line { |line| fp.puts(line) }}
|
335
|
+
write_html_tail_on(fp)
|
336
|
+
}
|
337
|
+
write_line_on_protokol "Wrote #{os_graph_htm} (which uses #{os_gif_file})."
|
338
|
+
|
339
|
+
return unless @build_graph_thumbs
|
340
|
+
gif_file = File.join(@html_output_path, "#{name}.gif")
|
341
|
+
thumbnail(gif_file)
|
342
|
+
end
|
343
|
+
|
344
|
+
def cloud_name_to_graph_name(cloud)
|
345
|
+
UrlGraph.tag2file(cloud) + '__go'
|
346
|
+
end
|
347
|
+
|
348
|
+
def write_all_overviews
|
349
|
+
# Create a file containing a cloud of all tags
|
350
|
+
list = @links_by_tag.keys.sort
|
351
|
+
filename = 'index.htm'
|
352
|
+
cloud_name = 'cloud (all)'
|
353
|
+
write_overview(filename, cloud_name, list, @bundles, @links_by_tag)
|
354
|
+
do_graphviz(@tag_graph, cloud_name)
|
355
|
+
|
356
|
+
# The same for all bundles
|
357
|
+
@bundles.keys.each do
|
358
|
+
| bundle |
|
359
|
+
list = @bundles[bundle]
|
360
|
+
filename = "bundle_#{bundle}.htm"
|
361
|
+
cloud_name = bundle
|
362
|
+
write_overview(filename, cloud_name, list, @bundles, @links_by_tag)
|
363
|
+
@tag_graph.filter_set = Set.new(list)
|
364
|
+
do_graphviz(@tag_graph, cloud_name)
|
365
|
+
@tag_graph.filter_set = nil
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
# Create one Html-File for each tag
|
370
|
+
def write_single_tag_files
|
371
|
+
@links_by_tag.keys.sort.each do
|
372
|
+
|tag|
|
373
|
+
File.open(File.join(@html_output_path, UrlGraph.node_url(tag)), 'w') do
|
374
|
+
|fp|
|
375
|
+
write_html_head_on(fp)
|
376
|
+
fp.puts "<h1>Tag: #{tag}</h1>"
|
377
|
+
link_index_on(fp, 'none', @bundles)
|
378
|
+
fp.puts '<div class="main">'
|
379
|
+
fp.puts "<h3>Subcategories for tag #{tag}</h3>"
|
380
|
+
subcloud = @tag_graph.adjacent_vertices(tag).sort
|
381
|
+
max_num_links = subcloud.collect{ |n| @links_by_edge[UrlGraph.edge_name(tag, n)].size }.max
|
382
|
+
subcloud.each do
|
383
|
+
|neighbor|
|
384
|
+
edge_name = UrlGraph.edge_name(tag, neighbor)
|
385
|
+
edgePage = UrlGraph.edge_url(tag, neighbor)
|
386
|
+
style = get_cloud_style(@links_by_edge[edge_name].size, max_num_links)
|
387
|
+
fp.puts(UrlGraph.intern_ankor(UrlGraph.edge_url(tag, neighbor), neighbor, style))
|
388
|
+
end
|
389
|
+
list = @links_by_tag[tag].select { |l| l['tags'].size == 1 }
|
390
|
+
unless list.empty?
|
391
|
+
fp.puts("<h3>Links with the single tag #{tag}</h3>")
|
392
|
+
fp.puts('<ul>')
|
393
|
+
sorted_links(list).each do
|
394
|
+
|link|
|
395
|
+
fp.puts('<li>')
|
396
|
+
write_link_on(link, fp, [tag])
|
397
|
+
fp.puts('</li>')
|
398
|
+
end
|
399
|
+
fp.puts('</ul>')
|
400
|
+
end
|
401
|
+
if @link_to_delicious_if_possible
|
402
|
+
fp.puts("<h3>#{UrlGraph.ankor(DEL_ICIO_US_URL, 'del.icio.us')} links with tag #{tag}</h3>")
|
403
|
+
fp.puts(UrlGraph.ankor(delicious_user_url(tag), "#{@user}"))
|
404
|
+
fp.puts(UrlGraph.ankor(delicious_tag_url(tag), "all"))
|
405
|
+
end
|
406
|
+
fp.puts '</div>'
|
407
|
+
write_html_tail_on(fp)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
write_line_on_protokol "Wrote one html-file for each tag to directory #{@html_output_path}."
|
411
|
+
end
|
412
|
+
|
413
|
+
def write_double_tag_files
|
414
|
+
# Create one Html-File for each edge between two tags
|
415
|
+
@tag_graph.each_edge do
|
416
|
+
|tag1,tag2|
|
417
|
+
edge_name = UrlGraph.edge_name(tag1, tag2)
|
418
|
+
edge_url = UrlGraph.edge_url(tag1, tag2)
|
419
|
+
File.open(File.join(@html_output_path, edge_url), 'w') do
|
420
|
+
|fp|
|
421
|
+
write_html_head_on(fp)
|
422
|
+
fp.puts "<h1>Tags: #{tag1} AND #{tag2}</h1>"
|
423
|
+
link_index_on(fp, 'none', @bundles)
|
424
|
+
fp.puts '<div class="main">'
|
425
|
+
ankor1 = UrlGraph.node_ankor(tag1)
|
426
|
+
ankor2 = UrlGraph.node_ankor(tag2)
|
427
|
+
fp.puts "<h3>Links for tag combination #{ankor1}/#{ankor2}</h3>"
|
428
|
+
fp.puts '<ul>'
|
429
|
+
sorted_links(@links_by_edge[edge_name]).each do
|
430
|
+
|link|
|
431
|
+
fp.puts('<li>')
|
432
|
+
write_link_on(link, fp, [tag1, tag2])
|
433
|
+
fp.puts('<br></li>')
|
434
|
+
end
|
435
|
+
fp.puts '</ul>'
|
436
|
+
if @link_to_delicious_if_possible
|
437
|
+
fp.puts("<h3>#{UrlGraph.ankor(DEL_ICIO_US_URL, 'del.icio.us')} links with tag combination #{ankor1}/#{ankor2}</h3>")
|
438
|
+
fp.puts(UrlGraph.ankor(delicious_user_url(tag1, tag2), @user))
|
439
|
+
fp.puts(UrlGraph.ankor(delicious_tag_url(tag1, tag2), 'all'))
|
440
|
+
end
|
441
|
+
fp.puts '</div>'
|
442
|
+
write_html_tail_on(fp)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
write_line_on_protokol "Wrote one html-file for each combination of two tags to directory #{@html_output_path}."
|
446
|
+
end
|
447
|
+
|
448
|
+
# make all run-variables garbage collectable
|
449
|
+
def reset_build_state
|
450
|
+
@tag_graph = nil
|
451
|
+
@links_by_tag = nil
|
452
|
+
@links_by_edge = nil
|
453
|
+
@bundles = nil
|
454
|
+
end
|
455
|
+
|
456
|
+
# run the complete batch
|
457
|
+
def run
|
458
|
+
unless File.exists?(@input_file)
|
459
|
+
raise "Missing input file #{@input_file}"
|
460
|
+
end
|
461
|
+
check_prerequisites
|
462
|
+
Dir.mkdir(@html_output_path) unless File.directory?(@html_output_path)
|
463
|
+
copy_style_to_user unless @user == @style
|
464
|
+
init_tag_graph
|
465
|
+
load_links
|
466
|
+
write_all_overviews
|
467
|
+
write_single_tag_files
|
468
|
+
write_double_tag_files
|
469
|
+
reset_build_state
|
470
|
+
write_line_on_protokol "Finished."
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
if $0 == __FILE__
|
475
|
+
YamlLinksToHtml.new.run
|
476
|
+
end
|