tRuTag 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/ruby
2
+ # tRuTag
3
+ # Distributed under the Ruby License
4
+ # http://trutag.rubyforge.org
5
+ # written by: Jamal Hansen jh@rubyyot.com
6
+
7
+ # this script creates the tag cloud webpage from the tRuTag classes
8
+
9
+ require 'tRuTag_full'
10
+
11
+ outputfile = Trutag::find_home + "/tRuTagcloud.html"
12
+
13
+ output_to_file = TRUE
14
+
15
+ offline_mode = FALSE
16
+ run_config = FALSE
17
+
18
+ # Parse our arguments
19
+ if /-.*/.match(ARGV[0]) then
20
+ x = ARGV.shift
21
+ offline_mode = /.*o.*/i.match(x) != nil
22
+ run_config = /.*c.*/i.match(x) != nil
23
+ end
24
+
25
+ # read our config file
26
+ params = Trutag::get_params_from_yaml(run_config)
27
+
28
+ params['websites'].each_value { | v |
29
+ v['isoffline']=offline_mode}
30
+
31
+ output = Trutag::buildpage(params['websites'], !params['store_pwd'], params['style'])
32
+
33
+ if params.fetch('output_to_file', TRUE)
34
+ f = File.new(params.fetch('output_file', outputfile), "w")
35
+ f.print output
36
+ f.close
37
+ puts "Done."
38
+ else
39
+ $stdout.print output
40
+ end
41
+
42
+
43
+
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby
2
+ # tRuTag
3
+ # Distributed under the Ruby License
4
+ # http://trutag.rubyforge.org
5
+ # written by: Jamal Hansen jh@rubyyot.com
6
+
7
+ # this script creates the tag cloud from the tRuTag classes
8
+ # is is an example of a more lightweight applciation of tRuTag.
9
+ # You will need to replace YOUR_USERNAME and YOUR_PWD with valid values
10
+
11
+ require 'tRuTag'
12
+
13
+ profiles = Hash.new
14
+
15
+ # You can remove any of these lines or add them as you wish.
16
+ profiles['43Things']={ 'type' => '43Things', 'username' => 'jh'}
17
+ profiles['Unalog']={ 'type' => 'Yahoo2', 'username' => 'jh'}
18
+ #profiles['Delicious']={ 'type' => 'Delicious', 'username' => 'YOUR_USERNAME', 'pwd' => 'YOUR_PWD'}
19
+
20
+ profiles.each_value { |x|
21
+ if x['username'] == 'YOUR_USERNAME'
22
+ raise(ArgumentError, "Please replace username and password with valid values.")
23
+ end}
24
+
25
+ # This tells trutag where to link to when you click on the tag cloud
26
+ profiles['target']={ 'type' => 'target', :controller => 'tag', :action => 'tag_click', :url => 'http://rubyyot.com'}
27
+
28
+ # This script just spits it out. If you want to see it in use look at http://rubyyot.com/tag
29
+ $stdout.print Trutag::create_tag_cloud_for_rails_site(profiles)
30
+
@@ -0,0 +1,35 @@
1
+ body {font-family: helvetica, arial, sans-serif; font-size: 12px;}
2
+ a:link, a:visited {color: #511;}
3
+ #about {font-family: monospace; font-size: 12px; color: #fee; background-color: #511;}
4
+ #google {font-family: arial; font-size: 16px;}
5
+ #about a:link, a:visited {color: #bbf;}
6
+ #site_select {position: absolute; top: 10px; left: 82%;}
7
+ H2 {font-family: "Century Schoolbook L", serif; font-size: 16px;}
8
+ #cloud {border-right:2px dashed #000; width: 80%;}
9
+ span.level0 { font-size: 10px; line-height:15px;}
10
+ span.level1 { font-size: 12px; line-height:17px;}
11
+ span.level2 { font-size: 14px; line-height:19px;}
12
+ span.level3 { font-size: 16px; line-height:21px;}
13
+ span.level4 { font-size: 18px; line-height:23px;}
14
+ span.level5 { font-size: 20px; line-height:25px;}
15
+ span.level6 { font-size: 22px; line-height:27px;}
16
+ span.level7 { font-size: 24px; line-height:29px;}
17
+ span.level8 { font-size: 26px; line-height:31px;}
18
+ span.level9 { font-size: 28px; line-height:33px;}
19
+ span.level10 { font-size: 30px; line-height:35px;}
20
+ span.level11 { font-size: 32px; line-height:37px;}
21
+ span.level12 { font-size: 34px; line-height:39px;}
22
+ span.level13 { font-size: 36px; line-height:41px;}
23
+ span.level14 { font-size: 36px; line-height:41px;}
24
+ span.level15 { font-size: 36px; line-height:41px;}
25
+ span.level16 { font-size: 36px; line-height:41px;}
26
+ span.level17 { font-size: 36px; line-height:41px;}
27
+ span.level18 { font-size: 36px; line-height:41px;}
28
+ span.level19 { font-size: 38px; line-height:43px;}
29
+ span.level20 { font-size: 40px; line-height:35px;}
30
+ span.level21 { font-size: 42px; line-height:37px;}
31
+ span.level22 { font-size: 44px; line-height:39px;}
32
+ span.level23 { font-size: 46px; line-height:41px;}
33
+ span.level24 { font-size: 48px; line-height:42px;}
34
+ span.level25 { font-size: 50px; line-height:43px;}
35
+ span a:hover {color: #000; background-color: #fee;}
@@ -0,0 +1,57 @@
1
+ tRuTag is copyrighted free software by Jamal Hansen <jamal.hansen@gmail.com>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL, or the conditions below:
3
+
4
+ 1. You may make and give away verbatim copies of the source form of the
5
+ software without restriction, provided that you duplicate all of the
6
+ original copyright notices and associated disclaimers.
7
+
8
+ 2. You may modify your copy of the software in any way, provided that
9
+ you do at least ONE of the following:
10
+
11
+ a) place your modifications in the Public Domain or otherwise
12
+ make them Freely Available, such as by posting said
13
+ modifications to Usenet or an equivalent medium, or by allowing
14
+ the author to include your modifications in the software.
15
+
16
+ b) use the modified software only within your corporation or
17
+ organization.
18
+
19
+ c) rename any non-standard executables so the names do not conflict
20
+ with standard executables, which must also be provided.
21
+
22
+ d) make other distribution arrangements with the author.
23
+
24
+ 3. You may distribute the software in object code or executable
25
+ form, provided that you do at least ONE of the following:
26
+
27
+ a) distribute the executables and library files of the software,
28
+ together with instructions (in the manual page or equivalent)
29
+ on where to get the original distribution.
30
+
31
+ b) accompany the distribution with the machine-readable source of
32
+ the software.
33
+
34
+ c) give non-standard executables non-standard names, with
35
+ instructions on where to get the original software distribution.
36
+
37
+ d) make other distribution arrangements with the author.
38
+
39
+ 4. You may modify and include the part of the software into any other
40
+ software (possibly commercial). But some files in the distribution
41
+ are not written by the author, so that they are not under this terms.
42
+
43
+ They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
44
+ files under the ./missing directory. See each file for the copying
45
+ condition.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
57
+
@@ -0,0 +1,100 @@
1
+ tRuTag - The taggregator
2
+ By: Jamal Hansen
3
+ License: Ruby license
4
+ Email: jh[at]rubyyot.com
5
+ url: http://trutag.rubyforge.org
6
+
7
+
8
+ What do I need?
9
+ tRuTag is written in Ruby, so you will need to be able to run Ruby scripts. If you are not able to run Ruby scripts or would like to know more about this scripting language you can find the information here: http://www.ruby-lang.org. Otherwise you will need a computer with an Internet connection and a user account with at least one of the supported sites. tRuTag has full support for del.icio.us, 43Things.com and other popular tag based sites.
10
+
11
+ How to I run it?
12
+ Well, once you have Ruby, to install tRuTag simply go to your commandline and type:
13
+ gem install tRuTag
14
+ to run the basic script run:
15
+ makecloud.rb
16
+
17
+ What is it?
18
+ tRuTag was something I wrote because I was interested in tags and meta data, but was frustrated because tags end up clustered in a single site. It is difficult to break out of that site and look at the whole internet. I think that the whole purpose of tagging things is to be able to group them not by site, but by idea.
19
+
20
+ What sites are supported?
21
+ Well there are two types of support offered by tRuTag. The first is Input/Output, which means that if you supply the necessary information tRuTag will retrieve your tags and let you look up tags on the site. These sites as of v0.3 are:
22
+
23
+ Site Input Required
24
+ ======================================================================
25
+ 43things.com username
26
+ 43places.com username
27
+ del.icio.us username, password
28
+ Jots.com username, password
29
+ Yahoo! My Web 2.0 username
30
+ Dinnerbuzz.com username
31
+ Tagzania.com username
32
+ Unalog username
33
+ Flickr username
34
+
35
+ Also supported are the internationalized versions of 43Things which are
36
+
37
+ Site Input Required
38
+ ======================================================================
39
+ Cosas43.com username
40
+ Cose43.com username
41
+ Choses43.com username
42
+ Dinge43.com username
43
+ Coisas43.com username
44
+
45
+
46
+ The second type of support is on the output page. If you have an entry in your config file for a site without user information it will include the site in the options for the tag cloud output. These sites as of v0.3 include all of the input sites and:
47
+
48
+ Site
49
+ ======================================================================
50
+ AllConsuming.net
51
+ Technorati
52
+ Photobucket
53
+ Google
54
+ Simpy
55
+ Blinklist.com
56
+ Furl (you will need to log in manually)
57
+ GutenTag (creative-mobs.com)
58
+ Hatena (b.hatena.ne.jp)
59
+ Del.irio.us
60
+ Webshots (s.phpspot.org)
61
+ Livemark.jp
62
+ Podcast.net
63
+ Upcoming.org
64
+ Colr.org
65
+ TagCentral
66
+ Consumating
67
+ Blogmarks
68
+ Wists
69
+ SmugMug
70
+ Foundcity
71
+ Swik
72
+
73
+ What does it do?
74
+ tRuTag will aggregate the tags from your accounts on various websites. tRuTag will then generate a webpage (I use it as my homepage) that contains a tag cloud of all your tags from all your sites. You can then choose your target site (the input sites and others including Technocrati.com and Google are available) and click on the desired tag and be taken to the tag page for the site you selected.
75
+
76
+ How do I config?
77
+ As of this version a config script is run if one does not already exist. You will see it the first time you run makecloud.rb. It will be created in your home directory as .tRuTag. As I run a Linux system, I'm not sure exactly where that will be under windows. If you would like to run config again simply run makecloud with the -c option
78
+
79
+ Passwords
80
+ Passwords are a sensitive issue and one that I did not want to take lightly. If you decide to use a website that needs a password (del.icio.us, Jots) you have options available to you.
81
+
82
+ 1) Save them to your config file. You will be prompted for this option in the config script.
83
+ 2) Omit them from your config file and be prompted for them when you run makecloud.rb
84
+ 3) Omit them from your config file and pass them in as command line arguments. If you enter them manually a couple times, you will know the order they are in simply pas them in as arguments to makecloud.rb.
85
+ 4) If you are using tRuTag in your own application you can pass in the passwords directly. See makecloudfromarray for an example.
86
+
87
+
88
+ Options
89
+ There are 2 command line options available for makecloud.rb. If you use an argument that is not preceeded with a '-' it will assume that you are passing it passwords to your sites.
90
+
91
+ -o is offline mode and it will look for XML tag files on another location. This is really for advanced use only
92
+ -c will run the config script before generating the file.
93
+
94
+ Acknowledgements
95
+ To my wife and kids for letting me spend hours at a time on the PC.
96
+ To everyone downloading this script and writing about it in your blogs.
97
+ To Pat Eyler for r43 and listening to stupid questions.
98
+ To Scott Raymond for flickr.
99
+
100
+ I hope this explains the script. If you have questions or problems please feel free to email me: jh[at]rubyyot.com
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/ruby
2
+ # tRuTag
3
+ # Distributed under the Ruby License
4
+ # http://trutag.rubyforge.org
5
+ # written by: Jamal Hansen <jh@rubyyot.com>
6
+
7
+ # Wrapper for RoR, add this code to app\helpers\application_helper.rb
8
+
9
+ module ApplicationHelper
10
+ require 'tRuTag'
11
+
12
+ def self.append_features(controller)
13
+ controller.ancestors.include?(ActionController::Base) ?
14
+ controller.add_template_helper(self) : super
15
+ end
16
+
17
+ def build_trutag_cloud(profile_array, outputClass)
18
+ # hash_array is an array of hashes for instance to use Yahoo2 and del.icio.us you would use
19
+ # @profiles = Array.new()
20
+ # @profiles.push Profiles.new({ 'type' => 'Yahoo2', 'username' => 'YOUR_USER_NAME'})
21
+ # @profiles.push Profiles.new({ 'type' => 'Delicious', 'username' => 'YOUR_USER_NAME', 'pwd' => 'YOUR_PASSWORD'})
22
+
23
+ Trutag::create_tag_cloud_for_site(profiles, Profile.new({ 'type' => outputClass }))
24
+ end
25
+
26
+ def get_trutag_about(div_id)
27
+ Trutag.getAbout(div_id)
28
+ end
29
+ end
@@ -0,0 +1,413 @@
1
+ #!/usr/bin/ruby
2
+ # tRuTag
3
+ # Distributed under the Ruby License
4
+ # http://trutag.rubyforge.org
5
+ # written by: Jamal Hansen jh@rubyyot.com
6
+
7
+
8
+ require 'net/http'
9
+ require 'rexml/document'
10
+ require 'xmlrpc/client'
11
+ require 'cgi'
12
+ require 'rubygems'
13
+ require 'yaml'
14
+
15
+ module Trutag
16
+ $version = "0.5.0"
17
+ $agent = "tRuTag v" + $version
18
+
19
+ #This is the default user config file
20
+ $configfile='.tRuTag'
21
+ # This this determines how quickly the scale of the font is increased in the css
22
+ $css_level_ratio = 5
23
+ $css_level_max = 25
24
+ # This is the default url
25
+ $default_url = "#"
26
+ $offline=FALSE
27
+ $websites_file=File.dirname(__FILE__) + '/websites.yml'
28
+
29
+ def Trutag::get_profile(classname)
30
+ if classname == "" || classname == nil
31
+ classname ='Technorati'
32
+ end
33
+
34
+ Profile.new({ "type" => classname })
35
+ end
36
+
37
+ def Trutag::create_tag_cloud_for_rails_site(params)
38
+ tbin=Hash.new()
39
+ sites = YAML::load(File.open($websites_file))
40
+ params.each { | k, i |
41
+ if k != 'target' then
42
+ #This should be a hash of site data such as :
43
+ #{ 'type' => 'Delicious', 'username' => 'foo', 'pwd' => 'bar' }
44
+ if !sites.has_key?(k)
45
+ loggit(2, %{no entry for #{k} in websites.yml})
46
+ end
47
+
48
+ i.update(sites[k])
49
+ i['tbin']=tbin
50
+ Profile.new(i)
51
+ end }
52
+
53
+ # Now we should have a hash of all of our tags. Let make it happen!
54
+ Trutag.make_rails_cloud_from_tag_hash(tbin, params['target'])
55
+ end
56
+
57
+ def Trutag::make_rails_cloud_from_tag_hash(tbin, target)
58
+ output = ""
59
+ tbin.each { | key, value |
60
+ output << TagCloudMaker.all_tags_rails_href(key, value, target)}
61
+ output
62
+ end
63
+
64
+
65
+ def Trutag::getAbout(div_id)
66
+ TagCloudMaker.about(div_id)
67
+ end
68
+
69
+ def Trutag::loggit(severity, message)
70
+ severities=['message', 'warning', 'error']
71
+
72
+ if message != ""
73
+ $stderr.print %{tRuTag #{severities[severity]}: #{message}\n\tDescription:#{$!}\n}
74
+ else
75
+ $stderr.print %{tRuTag #{severities[severity]}: #{$!}\n}
76
+ end
77
+ end
78
+ end
79
+
80
+
81
+ class TagCloudMaker
82
+ def TagCloudMaker.tag(name, other)
83
+ %{<#{name}#{other}>#{yield}</#{name}>}
84
+ end
85
+
86
+ def TagCloudMaker.all_tags_rails_href(tag, count, phash)
87
+ if phash.has_key?(:url)
88
+ addStyle(tag, count, phash) {%{<a href="#{phash[:url]}/#{phash[:controller]}/#{phash[:action]}/#{CGI.escapeElement(tag)}" title="#{tag} : #{count} tag(s)" rel="tag">#{tag}</a>}}
89
+ else
90
+ addStyle(tag, count, phash) {%{<a href="##{tag}" onclick="go('#{tag}')" title="#{tag} : #{count} tag(s)">#{tag}</a>}}
91
+ end
92
+ end
93
+
94
+ def TagCloudMaker.addStyle(tag, count, phash)
95
+ style = phash.fetch('style', 'cloud')
96
+
97
+ case style
98
+ when 'sun'
99
+ %{<span class="level#{TagCloudMaker.find_level(count)}" style="position: absolute; left:#{Integer((rand*9) * (rand*9))}%; top:#{Integer((rand*10) * (rand*10))}%;">#{yield}</span> }
100
+ when 'pile'
101
+ %{<span class="level#{TagCloudMaker.find_level(count)}" style="position: absolute; left:#{Integer((rand*20) + (rand*20) + (rand*20) + (rand*20))}%; top:#{Integer((rand*20) + (rand*20) + (rand*20) + (rand*20) + (rand*20))}%;">#{yield}</span> }
102
+ when 'pile'
103
+ %{<span class="level#{TagCloudMaker.find_level(count)}" style="position: absolute; left:#{Integer((rand*20) + (rand*20) + (rand*20) + (rand*20))}%; top:#{Integer((rand*20) + (rand*20) + (rand*20) + (rand*20) + (rand*20))}%;">#{yield}</span> }
104
+ else
105
+ %{<span class="level#{TagCloudMaker.find_level(count)}">#{yield}</span> }
106
+ end
107
+ end
108
+
109
+ def TagCloudMaker.find_level(count)
110
+ out = Integer(count)./($css_level_ratio)
111
+ if out > $css_level_max
112
+ out = $css_level_max
113
+ end
114
+ String (out)
115
+ end
116
+
117
+ def TagCloudMaker.space_to_plus(input, space_replacement)
118
+ input.gsub(/ /, space_replacement)
119
+ end
120
+
121
+ def TagCloudMaker.about(div_id)
122
+ %{<div id="#{div_id}"><H2>About</H2>This page was created with the help of <a href="http://tRuTag.rubyforge.org">#{$agent}</a> an open source project created by <a href="mailto:jh[at]rubyyot[dot]com">Jamal Hansen</div>}
123
+ end
124
+ end
125
+
126
+ class Profile
127
+ # To create a profile object you will need to pass in a hash containing the following:
128
+ # type: classname of the corresponding site
129
+ # username: username if this is for input
130
+ # pwd: if it is necessary for the site.
131
+ # offline: (optional) The XML file to use instad of the URL
132
+ attr_reader :tbin
133
+
134
+ def initialize(prohash)
135
+ begin
136
+ # Funny I think this started as a case statement and then went to a const_get now it's a case statement again.
137
+ # In any case this is creating the Site object based on the data passed to us.
138
+ case prohash['type']
139
+ when '43Things', '43Cosas', '43Cose', '43Choses', '43Dinge', '43Coisas'
140
+ @site = RobotCoop.new(prohash)
141
+ when 'Yahoo2'
142
+ @site = Y2.new(prohash)
143
+ when 'Jots'
144
+ @site = Jts.new(prohash)
145
+ when 'Flickr'
146
+ @site = Flkr.new(prohash)
147
+ else
148
+ @site = Site.new(prohash)
149
+ end
150
+ rescue ArgumentError
151
+ Trutag::loggit(2, %{#{$!}})
152
+ end
153
+
154
+ if prohash.fetch('mode', 0) == 1
155
+ begin
156
+ add_tags(prohash['tbin'])
157
+ rescue SocketError
158
+ Trutag::loggit(2, %{IO failed: #{@site.attrib['sitename']}})
159
+ rescue Timeout::Error
160
+ Trutag::loggit(2, %{Timeout:#{@site.attrib['sitename']}})
161
+ rescue
162
+ Trutag::loggit(2, %{})
163
+ end
164
+ end
165
+ end
166
+
167
+ def space_replace(tag)
168
+ TagCloudMaker.space_to_plus(tag, @site.attrib['space_replacement'])
169
+ end
170
+
171
+ def add_tags(tbin)
172
+ if tbin == nil
173
+ tbin = Hash.new
174
+ end
175
+
176
+ begin
177
+ @site.add_tags(tbin)
178
+ rescue SocketError
179
+ Trutag::loggit(2, %{IO failed: #{@site.attrib['sitename']} #{$!}})
180
+ end
181
+ end
182
+
183
+ def base_all_tags_url
184
+ %{http://#{@site.attrib['url']}#{@site.attrib['all_tags_path']}}
185
+ end
186
+
187
+
188
+ def method_missing( name, *args )
189
+ begin
190
+ @site.__send__( name, *args )
191
+ rescue NoMethodError
192
+ Trutag::loggit(1, %{Could not find method Site.#{name}})
193
+ end
194
+ end
195
+ end
196
+
197
+ class Site
198
+ # This is a base class, you will want to instantiate a class that inherits from site.
199
+ #
200
+ # To create a site object you will need to pass in a hash containing the following:
201
+ # username: username if this is for input
202
+ # pwd: if it is necessary for the site.
203
+ # offline: (optional) The XML file to use instad of the URL
204
+
205
+ attr_reader :attrib
206
+
207
+ def initialize(params)
208
+ #$stderr.print params['sitename'] + "\n"
209
+ params.delete_if{ | k, v | v=="" || v==nil }
210
+
211
+
212
+ @attrib={ 'url' => %{www.#{params['sitename']}.com}, 'validcode' => %{200},
213
+ 'needsauth' => %{401}, 'all_tags_path' => %{/tag/}, 'all_tags_path_post_tag' => "",
214
+ 'xmlelement' => %{feed/tags/tag}, 'space_replacement' => '+'}
215
+
216
+ @attrib.update(params)
217
+
218
+ #$stderr.print(%{#{@attrib['sitename']} is using #{self.class} })
219
+ end
220
+
221
+ def add_tags(tbin)
222
+ required_attribute('username')
223
+ required_attribute('tag_api_page')
224
+ required_attribute('xmlelement')
225
+ required_attribute('parse_tags')
226
+
227
+ #get the UML
228
+ uml_page=get_uml
229
+
230
+ #parse the UML
231
+ begin
232
+ doc=REXML::Document.new uml_page
233
+ rescue Exception, REXML::ParseException
234
+ Trutag::loggit(2, %{Error parsing XML from: #{@attrib['sitename']}})
235
+ end
236
+
237
+ if doc != nil
238
+ # parse tags is found in websites.yml
239
+ # example ofthe string parsetags: {tbin[@attrib['tel'].text.downcase] = tbin.fetch(@attrib['tel'].text.downcase, 0) + Integer(@attrib['tel'].attributes['count'])}
240
+ # Ruby rocks!
241
+
242
+ doc.elements.each(@attrib['xmlelement']) do |element|
243
+ eval @attrib['parse_tags']
244
+ end
245
+ end
246
+ end
247
+
248
+ def get_uml
249
+ if @attrib.fetch('isoffline', FALSE)
250
+ if @attrib.has_key?('offline')
251
+ if File.exist?(@attrib['offline'])
252
+ data = File.open(@attrib['offline'], "r")
253
+ else
254
+ Trutag::loggit(1, %{#@attrib['offline'] does not exist})
255
+ end
256
+ else
257
+ Trutag::loggit(0, %{No offline file configured for class: #{self.class}})
258
+ end
259
+ else
260
+ required_attribute('url')
261
+ required_attribute('needsauth')
262
+ required_attribute('validcode')
263
+ required_attribute('username')
264
+ required_attribute('tag_api_page')
265
+
266
+ data = Net::HTTP.start(@attrib['url']) { |http|
267
+ subpage = @attrib['tag_api_page']
268
+
269
+ if @attrib.has_key?('api_key')
270
+ subpage = subpage.gsub(/<api_key>/, @attrib['api_key'])
271
+ end
272
+
273
+ if @attrib.has_key?('username')
274
+ subpage = subpage.gsub(/<username>/, @attrib['username'])
275
+ end
276
+
277
+ req = Net::HTTP::Get.new(subpage, {"tRuTag" => $agent})
278
+
279
+ if http.request(req).code == @attrib['needsauth'] then
280
+ required_attribute('pwd')
281
+ req.basic_auth(@attrib['username'], @attrib['pwd'])
282
+ end
283
+
284
+ if http.request(req).code != @attrib['validcode'] then
285
+ Trutag::loggit(1, %{Received response: #{http.request(req).code} - #{http.request(req).message} from #{@attrib['sitename']}})
286
+ end
287
+
288
+ http.request(req).body
289
+ }
290
+ end
291
+ data
292
+ end
293
+
294
+ def required_attribute(attribute)
295
+ if @attrib != nil
296
+ if !@attrib.has_key?(attribute) || @attrib[attribute] == nil
297
+ raise ArgumentError, %{#{@attrib['sitename']} requires attribute: #{attribute}}, caller
298
+ end
299
+ else
300
+ raise ArgumentError, %{#{self.class} @attrib == nil}
301
+ end
302
+ end
303
+ end
304
+
305
+ # for robot coop sites
306
+ class RobotCoop < Site
307
+ # By default the config.xml file uses the text API Key of 1234. Please replace this with your own API Key
308
+ def initialize(params)
309
+ #we could be a number of sites so lets require the truth
310
+ if !params.has_key?('url') || !params.has_key?('sitename') then
311
+ raise ArgumentError, %{Your RobotCoop site requires a sitename and url attribute}
312
+ end
313
+ super
314
+ end
315
+
316
+ def add_tags(tbin)
317
+ require_gem 'r43'
318
+ required_attribute('api_key')
319
+ required_attribute('username')
320
+
321
+ if @attrib.has_key?('international') && @attrib['international'] != nil
322
+ conn = R43::Connection.new(@attrib['api_key'], @attrib['international'])
323
+ else
324
+ conn = R43::Connection.new(@attrib['api_key'])
325
+ end
326
+
327
+ tags = conn.get_persons_tags(@attrib['username'])
328
+ tags.each { |i| tbin[i.name.downcase] = tbin.fetch(i.name.downcase, 0) + Integer(i.count)}
329
+ end
330
+ end
331
+
332
+ class Y2 < Site
333
+ def add_tags(tbin)
334
+ required_attribute("validcode")
335
+ required_attribute("username")
336
+ required_attribute("api_key")
337
+
338
+ if !@attrib.fetch('isoffline', FALSE)
339
+ @tagstotal=1;@tagsreturned=1;@first=0;
340
+
341
+ Net::HTTP.start(%{api.search.yahoo.com}, 80) { |http|
342
+ def nextrequest
343
+ # I'm not too excited about this looping mechanism. There must be a better way, probably much easier as well.
344
+ while !@stop
345
+ yield
346
+ @first += @tagsreturned
347
+ end
348
+ end
349
+
350
+ @stop=FALSE
351
+ nextrequest {
352
+
353
+ @response = http.get(%{/MyWebService/V1/tagSearch?appid=#{attrib['api_key']}&yahooid=#{attrib['username']}&results=50&start=#{@first+@tagsreturned}})
354
+
355
+ if @response.code==@attrib['validcode']
356
+ doc=REXML::Document.new @response.body
357
+ @tagstotal=doc.elements[1].attributes["totalResultsAvailable"]
358
+ @tagsreturned=doc.elements[1].attributes["totalResultsReturned"]
359
+ @first=doc.elements[1].attributes["firstResultPosition"]
360
+
361
+ doc.elements[1].each do |element|
362
+ tbin[element[0].text.downcase] = (tbin.fetch(element[0].text.downcase, 0) + Integer(element[1].text))
363
+ end
364
+
365
+ @stop = (@tagsreturned+@first >= @tagstotal)
366
+ else
367
+ @stop=TRUE
368
+ Trutag::loggit(1, %{Received response: #{@response.code} - #{@response.message} from #{@attrib['sitename']}})
369
+ end
370
+ }
371
+
372
+
373
+
374
+ }
375
+ end
376
+
377
+
378
+ end
379
+ end
380
+
381
+ class Jts < Site
382
+ def add_tags(tbin)
383
+ required_attribute('username')
384
+ required_attribute('pwd')
385
+
386
+ if !@attrib.fetch('isoffline', FALSE)
387
+ # Make an object to represent the XML-RPC server.
388
+ server = XMLRPC::Client.new( "www.jots.com", "/xmlrpc.cgi")
389
+
390
+ # Call the remote server and get our result
391
+ result = server.call('jots.getAccountTags', @attrib['username'], @attrib['pwd'])
392
+
393
+ # Convert the array to a hash
394
+ result.each { |x| tbin[x.downcase] = (tbin.fetch(x, 0) + 1) }
395
+ end
396
+ end
397
+ end
398
+
399
+ class Flkr < Site
400
+ def add_tags(tbin)
401
+ #using Flickr api wrapper
402
+ # gem install flickr
403
+ required_attribute('email')
404
+
405
+ require_gem 'flickr'
406
+
407
+ flickr = Flickr.new
408
+ user = flickr.users(@attrib['email'])
409
+ user.tags.each { |x| tbin[x.downcase] = tbin.fetch(x.downcase, 0) +1 }
410
+ end
411
+ end
412
+
413
+ #Simpy: { type: Simpy, sitename: Simpy, tag_api_page: /simpy/api/rest/GetTags.do?, all_tags_path: '/simpy/User.do?username=#{@attrib[''username'']}&src=trutag&q=', mode: 0, parse_tags: 'tbin[element.attributes[''tag''].downcase] = ( tbin.fetch(element.attributes[''tag''].downcase, 0) + Integer(element.attributes[''count'']))' }