tRuTag 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/makecloud.rb +43 -0
- data/bin/makecloudfromarray.rb +30 -0
- data/css/tRuTag.css +35 -0
- data/doc/LICENSE.txt +57 -0
- data/doc/README.txt +100 -0
- data/doc/RoRwrapper +29 -0
- data/lib/tRuTag.rb +413 -0
- data/lib/tRuTag_full.rb +234 -0
- data/lib/websites.yml +35 -0
- data/sampleout/tRuTagcloud.html +3331 -0
- data/tRuTag.gemspec +30 -0
- data/test/xml/43Places.xml +17 -0
- data/test/xml/43Things.xml +17 -0
- data/test/xml/Delicious.xml +288 -0
- data/test/xml/dinnerbuzz.xml +20 -0
- data/test/xml/tagzania.xml +49 -0
- metadata +78 -0
data/bin/makecloud.rb
ADDED
@@ -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
|
+
|
data/css/tRuTag.css
ADDED
@@ -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;}
|
data/doc/LICENSE.txt
ADDED
@@ -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
|
+
|
data/doc/README.txt
ADDED
@@ -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
|
data/doc/RoRwrapper
ADDED
@@ -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
|
data/lib/tRuTag.rb
ADDED
@@ -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'']))' }
|