Graphiclious 0.1.0

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 (50) hide show
  1. data/README.txt +126 -0
  2. data/Rakefile +28 -0
  3. data/bin/graphiclious +3 -0
  4. data/doc/cloud.jpg +0 -0
  5. data/doc/index.html +32 -0
  6. data/doc/screenshots/default.css +44 -0
  7. data/doc/screenshots/original/blue-style-1.html +37 -0
  8. data/doc/screenshots/original/blue-style-1.jpg +0 -0
  9. data/doc/screenshots/original/cornflower.html +37 -0
  10. data/doc/screenshots/original/cornflower.jpg +0 -0
  11. data/doc/screenshots/original/custom-style.html +37 -0
  12. data/doc/screenshots/original/custom-style.jpg +0 -0
  13. data/doc/screenshots/original/sample-graph.html +37 -0
  14. data/doc/screenshots/original/sample-graph.jpg +0 -0
  15. data/doc/screenshots/original/user-interface.html +37 -0
  16. data/doc/screenshots/original/user-interface.jpg +0 -0
  17. data/doc/screenshots/thumb.html +46 -0
  18. data/doc/screenshots/thumb/t_blue-style-1.jpg +0 -0
  19. data/doc/screenshots/thumb/t_cornflower.jpg +0 -0
  20. data/doc/screenshots/thumb/t_custom-style.jpg +0 -0
  21. data/doc/screenshots/thumb/t_sample-graph.jpg +0 -0
  22. data/doc/screenshots/thumb/t_user-interface.jpg +0 -0
  23. data/doc/style.css +60 -0
  24. data/gemspec.rb +45 -0
  25. data/lib/graphiclious.rb +78 -0
  26. data/lib/graphiclious/delicious2yaml.rb +235 -0
  27. data/lib/graphiclious/dot_attributes.rb +35 -0
  28. data/lib/graphiclious/environment.rb +36 -0
  29. data/lib/graphiclious/gui.rb +260 -0
  30. data/lib/graphiclious/help.rb +22 -0
  31. data/lib/graphiclious/require_fox.rb +12 -0
  32. data/lib/graphiclious/url_graph.rb +135 -0
  33. data/lib/graphiclious/utf8.rb +19 -0
  34. data/lib/graphiclious/version.rb +8 -0
  35. data/lib/graphiclious/yaml-links2html.rb +476 -0
  36. data/options.yaml +7 -0
  37. data/styles/blue-style-1/dot-attributes.yaml +21 -0
  38. data/styles/blue-style-1/extern.gif +0 -0
  39. data/styles/blue-style-1/style.css +128 -0
  40. data/styles/cornflower/cornflower.png +0 -0
  41. data/styles/cornflower/dot-attributes.yaml +21 -0
  42. data/styles/cornflower/extern.gif +0 -0
  43. data/styles/cornflower/h3.gif +0 -0
  44. data/styles/cornflower/menuitem.png +0 -0
  45. data/styles/cornflower/menuselected.png +0 -0
  46. data/styles/cornflower/style.css +149 -0
  47. data/styles/cornflower/tr-edge.png +0 -0
  48. data/test/test_delicious2yaml.rb +97 -0
  49. data/wickie +249 -0
  50. metadata +119 -0
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2
+ "http://www.w3.org/TR/html4/strict.dtd">
3
+ <html>
4
+
5
+ <head>
6
+ <meta name="GENERATOR" content="XnView">
7
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
8
+ <meta http-equiv="Content-Language" content="en-us">
9
+ <title>Graphiclious screenshots</title>
10
+ <link rel="stylesheet" type="text/css" href="default.css">
11
+ </head>
12
+
13
+ <body>
14
+ <h1>Graphiclious</h1>
15
+ <p>
16
+ <a href="../index.html">Back to Homepage</a>
17
+ </p>
18
+ <table cellpadding="10" cellspacing="0">
19
+ <tr><td>
20
+ <a href="original/blue-style-1.html"><img src="thumb/t_blue-style-1.jpg" alt="blue-style-1.jpg" width="100" height="81"></a>
21
+ <div>blue-style-1</div>
22
+ </td>
23
+ <td>
24
+ <a href="original/cornflower.html"><img src="thumb/t_cornflower.jpg" alt="cornflower.jpg" width="100" height="63"></a>
25
+ <div>cornflower</div>
26
+ </td>
27
+ <td>
28
+ <a href="original/custom-style.html"><img src="thumb/t_custom-style.jpg" alt="custom-style.jpg" width="100" height="77"></a>
29
+ <div>custom-style</div>
30
+ </td>
31
+ </tr>
32
+ <tr>
33
+ <td>
34
+ <a href="original/sample-graph.html"><img src="thumb/t_sample-graph.jpg" alt="sample-graph.jpg" width="100" height="61"></a>
35
+ <div>sample-graph</div>
36
+ </td>
37
+ <td>
38
+ <a href="original/user-interface.html"><img src="thumb/t_user-interface.jpg" alt="user-interface.jpg" width="81" height="100"></a>
39
+ <div>user-interface</div>
40
+ </td>
41
+ </tr>
42
+ </table>
43
+
44
+ <p><i>This thumbnail page was generated by <a href="http://www.xnview.com">XnView</a></i></p>
45
+ </body>
46
+ </html>
data/doc/style.css ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ #3333AA => dunkel
3
+ #91B1EE => himmel = 145/177/238
4
+ #E2EAF9 => hell
5
+
6
+ */
7
+
8
+ /** Basic paragraph styles
9
+ */
10
+ body {
11
+ color:#FFFFFF;
12
+ background:#91B1EE url(cloud.jpg) no-repeat top left;
13
+ border-width:medium;
14
+ border-top-color:#FFFFFF;
15
+ border-bottom-color:#000000;
16
+ border-left-color:#FFFFFF;
17
+ border-right-color:#000000;
18
+ }
19
+ h1 {
20
+ color:#3333AA;
21
+ padding:20px;
22
+ }
23
+ div.main {
24
+ width:70%;
25
+ vertical-align:top;
26
+ color:#000000;
27
+ background-color:#E2EAF9;
28
+ margin:0px;
29
+ margin-left:20px;
30
+ padding:20px;
31
+ }
32
+ img {
33
+ border-style:none;
34
+ }
35
+ ul {
36
+ list-style-type:square;
37
+ }
38
+ /* Basic link style
39
+ */
40
+ a:link {
41
+ color:black;
42
+ text-decoration:underline;
43
+ }
44
+ a:visited {
45
+ color:#555555;
46
+ text-decoration:underline;
47
+ }
48
+ a:hover {
49
+ color:black;
50
+ text-decoration:underline;
51
+ }
52
+ a:active {
53
+ color:black;
54
+ text-decoration:none;
55
+ }
56
+
57
+ .extern {
58
+ background: transparent url(extern.gif) no-repeat top left;
59
+ padding-left:12px;
60
+ }
data/gemspec.rb ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/ruby
2
+ #$Id: gemspec.rb,v 1.1 2005/04/07 20:41:21 wsdng Exp $
3
+
4
+ require 'rubygems'
5
+ require 'lib/graphiclious/version.rb'
6
+
7
+ summary = String.new
8
+ summary <<
9
+ 'Create an html image map pointing to generated
10
+ static html pages from your del.icio.us links.
11
+
12
+ Uses Rubilicious and Graphviz.
13
+
14
+ Interface done with FXRuby'
15
+
16
+ spec = Gem::Specification.new do |s|
17
+ s.name = "Graphiclious"
18
+ s.version = Graphiclious.version
19
+ s.author = "Sascha D�rdelmann"
20
+ s.email = "wsdngatrubyforge at hinterkattentuffel.de"
21
+ s.homepage = "http://rubyforge.org/projects/rgl/"
22
+ s.platform = Gem::Platform::RUBY
23
+ s.summary = summary
24
+ s.files = Dir.glob("**/*").reject { |f|
25
+ f =~ /~$/ || f =~ /\.gem/
26
+ }
27
+ s.require_path = "lib"
28
+ s.executables = Dir.glob("bin/*").reject { |globFile|
29
+ globFile =~ /~$/
30
+ }.collect { |f|
31
+ File.basename(f)
32
+ }
33
+ s.has_rdoc = false
34
+ s.add_dependency("Rubilicious")
35
+ s.add_dependency("rgl")
36
+ end
37
+
38
+ if $0 == __FILE__
39
+ Gem::manage_gems
40
+ gem = Gem::Builder.new(spec).build
41
+ cmd = "gem install #{gem}"
42
+ puts "Please run: #{cmd}"
43
+ end
44
+
45
+
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ #$Id: graphiclious.rb,v 1.9 2006/03/03 22:19:23 monora Exp $
3
+
4
+ require 'getoptlong'
5
+
6
+ getOpt = GetoptLong.new(["--user", "-u", GetoptLong::REQUIRED_ARGUMENT],
7
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
8
+ ["--gui", "-g", GetoptLong::NO_ARGUMENT],
9
+ ["--noupdate", "-l", GetoptLong::NO_ARGUMENT],
10
+ ["--nohtml", "-o", GetoptLong::NO_ARGUMENT],
11
+ ["--bundles", "-b", GetoptLong::NO_ARGUMENT],
12
+ ["--version", "-v", GetoptLong::NO_ARGUMENT],
13
+ ["--delicious", "-d", GetoptLong::NO_ARGUMENT],
14
+ ["--help", "-h", GetoptLong::NO_ARGUMENT])
15
+
16
+ opts = Hash.new
17
+ getOpt.each do |opt, arg|
18
+ opts[opt] = arg && !arg.empty? ? arg : true
19
+ end
20
+
21
+ # undocumented debug option
22
+ if $DEBUG # $DEBUG == true ?
23
+ require 'yaml'
24
+ File.open("options.yaml", 'w') { |out|
25
+ YAML.dump(opts, out)
26
+ }
27
+ end
28
+
29
+ if opts["--version"]
30
+ require 'graphiclious/version'
31
+ puts Graphiclious.version
32
+ end
33
+
34
+ def printHelpUsageOn(io_stream)
35
+ require 'graphiclious/help'
36
+ io_stream.puts Graphiclious.help
37
+ end
38
+
39
+ if opts["--help"]
40
+ printHelpUsageOn($stdout)
41
+ exit
42
+ end
43
+
44
+ user = opts["--user"]
45
+ password = opts["--password"]
46
+
47
+ if opts["--gui"]
48
+ require 'graphiclious/gui'
49
+ application = Fox::FXApp.new("Graphiclious", "Sascha D?rdelmann")
50
+ window = GraphicliousMainWindow.new(application, user, password)
51
+ window.setOptionFetch(!opts["--noupdate"])
52
+ window.setOptionGenerate(!opts["--nohtml"])
53
+ window.setOptionDelicious(opts["--delicious"])
54
+ window.setOptionBundles(opts["--bundles"])
55
+ application.addSignal("SIGINT", window.method(:onCmdQuit))
56
+ application.create
57
+ application.run
58
+ else
59
+ unless (user && password) || opts["--noupdate"]
60
+ printHelpUsageOn($stderr)
61
+ exit
62
+ end
63
+ unless opts["--noupdate"]
64
+ require 'graphiclious/delicious2yaml'
65
+ importer = Delicious2Yaml.new(user, password)
66
+ importer.run
67
+ importer.fetch_and_store_bundles if opts["--bundles"]
68
+ end
69
+ unless opts["--nohtml"]
70
+ require 'graphiclious/yaml-links2html'
71
+ exporter = YamlLinksToHtml.new
72
+ exporter.link_to_delicious_if_possible = opts["--delicious"]
73
+ exporter.run
74
+ end
75
+ end
76
+
77
+
78
+
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env ruby
2
+ #$Id: delicious2yaml.rb,v 1.8 2006/03/07 23:39:04 wsdng Exp $
3
+
4
+ require_gem 'Rubilicious'
5
+
6
+ if(Rubilicious::VERSION == '0.1.5')
7
+ class Rubilicious
8
+ def all(tag = nil)
9
+ args = [(tag ? "tag=#{tag.uri_escape}" : nil)]
10
+ get('posts/all?' << args.compact.join('&amp;'), 'post').map do |e|
11
+ e['time'] = Time::from_iso8601(e['time'])
12
+ e['tags'] = e['tag'].split(/\s/) # wrong in 1.5
13
+ e # missing in 1.5
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ require 'yaml'
20
+ require 'graphiclious/utf8'
21
+
22
+ class Delicious2Yaml
23
+
24
+ MODES = {:a_recent => 'update recent', :b_all => 'fetch all' }
25
+
26
+ def initialize(user_string, password_string)
27
+ @working_dir = Dir.getwd
28
+ @user = user_string
29
+ @password = password_string
30
+ @interface = create_interface
31
+ @mode = :b_all
32
+ end
33
+
34
+ def create_interface
35
+ @interface = Rubilicious.new(@user, @password)
36
+ end
37
+
38
+ def set_working_dir(new_working_dir)
39
+ @working_dir = new_working_dir
40
+ end
41
+
42
+ def set_mode(new_mode)
43
+ unless MODES.has_key?(new_mode)
44
+ raise("Sorry, this mode is not possible")
45
+ return
46
+ end
47
+ @mode = new_mode
48
+ end
49
+
50
+ def set_protocol_block(aProc)
51
+ @protocol_block = aProc
52
+ end
53
+
54
+ def writeLineOnProtokoll(lineString)
55
+ if @protocol_block.nil?
56
+ puts(lineString)
57
+ else
58
+ @protocol_block.call(lineString)
59
+ end
60
+ end
61
+
62
+ # this is the main doit, just like update but with
63
+ # basic exception handling
64
+ # returns true if update was necessary and successful
65
+ def run
66
+ begin
67
+ update
68
+ true
69
+ rescue StandardError => bang
70
+ writeLineOnProtokoll "Error: #{bang}"
71
+ false
72
+ rescue
73
+ writeLineOnProtokoll "Error, maybe try again later?"
74
+ false
75
+ end
76
+ end
77
+
78
+ # get links from del.icio.us and add them to the
79
+ # locally stored links
80
+ # you'll have to edit the delicious*.yaml file to delete a link
81
+ # (or delete the file to get a clean copy next time)
82
+ def update
83
+ fetch_and_store_links
84
+ fetch_and_store_bundles
85
+ end
86
+
87
+ protected
88
+
89
+ def file_base
90
+ File.join(output_path, 'delicious')
91
+ end
92
+
93
+ def output_path
94
+ File.join(@working_dir, @user)
95
+ end
96
+
97
+ # wait a constant time between two requests to del.icio.us
98
+ def delay
99
+ sleep(1)
100
+ end
101
+
102
+ # create output-directory if necessary
103
+ def create_output_dir
104
+ Dir.mkdir(output_path) unless File.directory?(output_path)
105
+ end
106
+
107
+ # compare the last change time given by del.icio.us against
108
+ # the last update time which is stored in a yaml-file
109
+ def update_necessary?
110
+ writeLineOnProtokoll("Check for updates for #{@user} now.")
111
+
112
+ @time = @interface.update
113
+ if File.exists?("#{file_base}.time")
114
+ last_time = File.open("#{file_base}.time", 'r') { |io|
115
+ YAML.load(io)
116
+ }
117
+ end
118
+ writeLineOnProtokoll "Last entry was #{@time.to_s}"
119
+ writeLineOnProtokoll "Last update was #{last_time.to_s}"
120
+ !last_time || @time > last_time
121
+ end
122
+
123
+ # will write the file *.time containing member @time in yaml format
124
+ def store_time
125
+ create_output_dir
126
+ File.open("#{file_base}.time", 'w') { |out|
127
+ YAML.dump(@time, out)
128
+ }
129
+ end
130
+
131
+ # Get some or all the user's links from del.icio.us depending
132
+ # on the chosen mode
133
+ def fetch_and_store_links
134
+ method(@mode).call
135
+ end
136
+
137
+ # Get the user's bundles from del.icio.us, a bundle is a group of
138
+ # tags. Note that, this method will not fetch any link.
139
+ def fetch_and_store_bundles
140
+ delay
141
+ bundles = @interface.bundles
142
+ create_output_dir
143
+ File.open(File.join(output_path, 'bundles.yaml'), 'w') { |out|
144
+ YAML.dump(bundles, out)
145
+ }
146
+ writeLineOnProtokoll "#{bundles.keys.size.to_s} bundles availiable"
147
+ true
148
+ end
149
+
150
+ # each mode is one method
151
+
152
+ # Mode a_recent will use the recent method to fetch the newest
153
+ # links and add them to the previously stored ones.
154
+ # It will fetch the links without caring if there is anything
155
+ # new to fetch since last time.
156
+ # It might overwrite but will not delete any previously stored links
157
+ def a_recent
158
+ writeLineOnProtokoll "Requesting recent changes"
159
+ store_new(@interface.recent, false)
160
+ end
161
+
162
+ # Mode b_all will use the all method to fetch all
163
+ # links and replace the previously stored ones.
164
+ # It will fetch the links only if there is anything
165
+ # new since the last fetch with this method.
166
+ def b_all
167
+ return false unless update_necessary?
168
+ writeLineOnProtokoll "Requesting all at once"
169
+ return false unless store_new(@interface.all, true)
170
+ store_time if @time
171
+ true
172
+ end
173
+
174
+ # store links as yaml file, delete previously stored links
175
+ # 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
180
+ |link|
181
+ # writeLineOnProtokoll "\tGot #{link['href']}"
182
+ cache[link['hash']] = Graphiclious.link_with_utf8_strings(link)
183
+ end
184
+ store_links(cache)
185
+ true
186
+ end
187
+
188
+ # get all of the user's links from delicious*.yaml file
189
+ def get_locally_stored_links
190
+ cache = Hash.new
191
+ if File.exist?("#{file_base}.yaml")
192
+ cache = File.open("#{file_base}.yaml", 'r') { |io|
193
+ YAML.load(io)
194
+ }
195
+ end
196
+ cache
197
+ 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
+ end
208
+
209
+ if $0 == __FILE__
210
+ def get_string_from_user
211
+ gets[0..-2]
212
+ end
213
+
214
+ def get_password_from_user
215
+ get_string_from_user
216
+ end
217
+
218
+ if ARGV.size > 0
219
+ user = ARGV[0]
220
+ else
221
+ puts "del.icio.us user?"
222
+ user = get_string_from_user
223
+ end
224
+ exit(1) if !user || user.empty?
225
+
226
+ if ARGV.size > 1
227
+ password = ARGV[1]
228
+ else
229
+ puts "password for #{user}?\n(Attention: will be shown)"
230
+ password = get_password_from_user
231
+ end
232
+ exit(1) if !password || password.empty?
233
+
234
+ Delicious2Yaml.new(user, password).run
235
+ end