twitterscrobble 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +12 -0
- data/PostInstall.txt +1 -0
- data/README.txt +82 -0
- data/Rakefile +4 -0
- data/bin/twitterscrobble +21 -0
- data/lib/twitterscrobble/preferences.rb +208 -0
- data/lib/twitterscrobble/status_line.rb +75 -0
- data/lib/twitterscrobble/twitter_scrobbler.rb +55 -0
- data/lib/twitterscrobble/version.rb +9 -0
- data/lib/twitterscrobble.rb +4 -0
- data/test/test_helper.rb +2 -0
- data/test/test_twitterscrobble.rb +11 -0
- metadata +82 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Nicholas E. Rabenau
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
PostInstall.txt
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
bin/twitterscrobble
|
8
|
+
lib/twitterscrobble.rb
|
9
|
+
lib/twitterscrobble/preferences.rb
|
10
|
+
lib/twitterscrobble/status_line.rb
|
11
|
+
lib/twitterscrobble/twitter_scrobbler.rb
|
12
|
+
lib/twitterscrobble/version.rb
|
data/PostInstall.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
For more information on twitterscrobble, see http://twitterscrobble.rubyforge.org
|
data/README.txt
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
= twitterscrobble
|
2
|
+
|
3
|
+
* http://twitterscrobble.rubyforge.org
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
This application posts recently played tracks from last.fm to Twitter.
|
8
|
+
|
9
|
+
== SYNOPSIS:
|
10
|
+
|
11
|
+
twitterscrobble [options]
|
12
|
+
|
13
|
+
For help use:
|
14
|
+
|
15
|
+
twitterscrobble -h
|
16
|
+
|
17
|
+
The following command reads all most recently played tracks from a last.fm account
|
18
|
+
and posts them to Twitter. All settings are read from the preferences file.
|
19
|
+
|
20
|
+
twitterscrobble
|
21
|
+
|
22
|
+
The following command prints the status line of recent tracks to stdout (not posting to Twitter), assuming a history value of 0 and not saving state.
|
23
|
+
|
24
|
+
twitterscrobble --no-post --history 0 --no-save
|
25
|
+
|
26
|
+
The following posts all recent tracks and store user names and password in the preferences file. This is suitable as the initial invocation, as it creates the preferences file for later invocation without the user detail.
|
27
|
+
|
28
|
+
twitterscrobble --scrobbler-user foo --twitter-user FooBar --twitter-password bar
|
29
|
+
|
30
|
+
== REQUIREMENTS:
|
31
|
+
|
32
|
+
* twitter
|
33
|
+
* scrobbler
|
34
|
+
* shorturl
|
35
|
+
|
36
|
+
== INSTALL:
|
37
|
+
|
38
|
+
* sudo gem install twitterscrobble
|
39
|
+
|
40
|
+
This script is probably run best from CRON:
|
41
|
+
|
42
|
+
$> crontab -l
|
43
|
+
# m h dom mon dow command
|
44
|
+
* * * * * /home/nerab/projects/atom2nntp/workspace/twitterscrobble/bin/twitterscrobble --loglevel warn --logfile /home/nerab/.twitterscrobble/twitterscrobble.log
|
45
|
+
|
46
|
+
The entry to the user's crontab can be made with
|
47
|
+
|
48
|
+
crontab -e
|
49
|
+
|
50
|
+
This will invoke the default editor for making changes to the user's crontab.
|
51
|
+
|
52
|
+
The library will announce itself as "twitterscrobble" on Twitter (by sending the appropriate source parameter). The twitter gem
|
53
|
+
still has a bug about this, so the source parameter will not work until {this bug}[http://jnunemaker.lighthouseapp.com/projects/14843/tickets/11-source-parameter-does-not-get-through#ticket-11-1] has been fixed.
|
54
|
+
|
55
|
+
= Author
|
56
|
+
|
57
|
+
Nicolas E. Rabenau, nerab@gmx.at
|
58
|
+
|
59
|
+
== LICENSE:
|
60
|
+
|
61
|
+
(The MIT License)
|
62
|
+
|
63
|
+
Copyright (c) 2008 Nicholas E. Rabenau
|
64
|
+
|
65
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
66
|
+
a copy of this software and associated documentation files (the
|
67
|
+
'Software'), to deal in the Software without restriction, including
|
68
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
69
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
70
|
+
permit persons to whom the Software is furnished to do so, subject to
|
71
|
+
the following conditions:
|
72
|
+
|
73
|
+
The above copyright notice and this permission notice shall be
|
74
|
+
included in all copies or substantial portions of the Software.
|
75
|
+
|
76
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
77
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
78
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
79
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
80
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
81
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
82
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/bin/twitterscrobble
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Nicholas E. Rabenau on 2008-8-14.
|
4
|
+
# Copyright (c) 2008. All rights reserved.
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'rubygems'
|
8
|
+
rescue LoadError
|
9
|
+
# no rubygems to load, so we fail silently
|
10
|
+
end
|
11
|
+
|
12
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
13
|
+
require 'twitterscrobble'
|
14
|
+
|
15
|
+
begin
|
16
|
+
prefs = Twitterscrobble::Preferences.new
|
17
|
+
Twitterscrobble::TwitterScrobbler.new(prefs).update
|
18
|
+
prefs.save
|
19
|
+
rescue
|
20
|
+
$stderr.puts "\nError: #{$!}"
|
21
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'optparse'
|
3
|
+
require 'logger'
|
4
|
+
require 'active_support'
|
5
|
+
|
6
|
+
module Twitterscrobble
|
7
|
+
|
8
|
+
class SimpleLogger < Logger
|
9
|
+
def format_message(severity, timestamp, progname, msg)
|
10
|
+
"#{timestamp.to_s(:db)} #{severity} #{msg}\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Preferences
|
15
|
+
PREFERENCES_FILE_NAME = "preferences.yaml"
|
16
|
+
APP_NAME = "twitterscrobble"
|
17
|
+
TO_BE_SAVED = [:history, :twitter_user, :scrobbler_user, :twitter_password]
|
18
|
+
|
19
|
+
attr_reader :logger
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
parsed_args = parse_args
|
23
|
+
|
24
|
+
begin
|
25
|
+
if !parsed_args[:stateless]
|
26
|
+
@cfg = YAML.load(File.open(full_prefs_file_path))
|
27
|
+
else
|
28
|
+
@cfg = {}
|
29
|
+
end
|
30
|
+
rescue
|
31
|
+
@cfg = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
@cfg.merge!(parsed_args) # args override cfg
|
35
|
+
|
36
|
+
if @cfg[:logfile]
|
37
|
+
@logger = SimpleLogger.new(@cfg[:logfile])
|
38
|
+
else
|
39
|
+
@logger = SimpleLogger.new(STDOUT)
|
40
|
+
end
|
41
|
+
|
42
|
+
if @cfg[:loglevel]
|
43
|
+
@logger.level = @cfg[:loglevel]
|
44
|
+
else
|
45
|
+
@logger.level = Logger::WARN
|
46
|
+
end
|
47
|
+
|
48
|
+
@logger.debug("Command line preferences: #{parsed_args.reject{|k,v| k == :twitter_password}.inspect}")
|
49
|
+
@logger.debug("Effective preferences after merging in preferences file #{full_prefs_file_path}:")
|
50
|
+
@logger.debug(@cfg.reject{|k,v| k == :twitter_password}.inspect)
|
51
|
+
|
52
|
+
if 0 < check_required_args.size
|
53
|
+
msg = ""
|
54
|
+
msg << "Required argument#{'s' if 1 < check_required_args.size} #{check_required_args.join(', ')} "
|
55
|
+
msg << "not found in preferences or command line parameters."
|
56
|
+
raise msg
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def save
|
61
|
+
unless @cfg[:no_save]
|
62
|
+
Dir.mkdir(preferences_dir) if !File.exist?(preferences_dir)
|
63
|
+
|
64
|
+
File.open(full_prefs_file_path, 'w') do |out|
|
65
|
+
save_cfg = @cfg.reject{|k, v| !TO_BE_SAVED.include?(k)}
|
66
|
+
@logger.debug("Writing preferences: #{save_cfg.reject{|k,v| k == :twitter_password}.inspect}")
|
67
|
+
YAML.dump(save_cfg, out)
|
68
|
+
end
|
69
|
+
|
70
|
+
File.new(full_prefs_file_path).chmod(0600)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# delegates reading of attributes to @cfg
|
75
|
+
def method_missing(methodname, *args)
|
76
|
+
@cfg[methodname]
|
77
|
+
end
|
78
|
+
|
79
|
+
def history=(history_stamp)
|
80
|
+
@cfg[:history] = history_stamp
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def check_required_args
|
85
|
+
missing = []
|
86
|
+
|
87
|
+
if @cfg[:twitter_user].blank?
|
88
|
+
missing << "twitter-user"
|
89
|
+
end
|
90
|
+
|
91
|
+
if @cfg[:twitter_password].blank?
|
92
|
+
missing << "twitter-password"
|
93
|
+
end
|
94
|
+
|
95
|
+
if @cfg[:scrobbler_user].blank?
|
96
|
+
missing << "scrobbler-user"
|
97
|
+
end
|
98
|
+
missing
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# some code taken from http://redshift.sourceforge.net/preferences/doc/classes/Preferences.src/M000002.html
|
103
|
+
# which is under the Ruby license (which is MIT compatible, I believe)
|
104
|
+
def preferences_dir
|
105
|
+
dir = nil
|
106
|
+
app_name = APP_NAME
|
107
|
+
|
108
|
+
case RUBY_PLATFORM
|
109
|
+
when /win32/
|
110
|
+
dir =
|
111
|
+
ENV['APPDATA'] || # C:\Documents and Settings\name\Application Data
|
112
|
+
ENV['USERPROFILE'] || # C:\Documents and Settings\name
|
113
|
+
ENV['HOME']
|
114
|
+
else
|
115
|
+
dir = ENV['HOME'] || File.expand_path('~')
|
116
|
+
app_name = "." << APP_NAME
|
117
|
+
end
|
118
|
+
|
119
|
+
unless dir
|
120
|
+
raise EnvError, "Can't determine a preferences directory."
|
121
|
+
end
|
122
|
+
|
123
|
+
File.join(dir, app_name)
|
124
|
+
end
|
125
|
+
|
126
|
+
def parse_args
|
127
|
+
options = {}
|
128
|
+
|
129
|
+
op = OptionParser.new do |opts|
|
130
|
+
|
131
|
+
#
|
132
|
+
# general flags
|
133
|
+
#
|
134
|
+
|
135
|
+
opts.on("-h", "--help", "Prints this help text and exits") do |v|
|
136
|
+
puts op.to_s
|
137
|
+
exit
|
138
|
+
end
|
139
|
+
|
140
|
+
opts.on("-v", "--version", "Prints the version of this script and exits") do |v|
|
141
|
+
puts "#{Twitterscrobble.name}, v.#{VERSION::STRING}"
|
142
|
+
exit
|
143
|
+
end
|
144
|
+
|
145
|
+
opts.on("-q", "--quiet", "Don't write anything to stdout") do |v|
|
146
|
+
options[:quiet] = true
|
147
|
+
end
|
148
|
+
|
149
|
+
opts.on("-f <logfile>", "--logfile <logfile>", "Specify the name of the log file") do |v|
|
150
|
+
options[:logfile] = v
|
151
|
+
end
|
152
|
+
|
153
|
+
level_map = {:debug => Logger::DEBUG, :info => Logger::INFO, :warn => Logger::WARN, :error => Logger::ERROR, :fatal => Logger::FATAL}
|
154
|
+
opts.on("-l LEVEL", "--loglevel LEVEL", level_map, "Specify the log level (#{level_map.keys.join(', ')})") do |t|
|
155
|
+
options[:loglevel] = t
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# user data
|
160
|
+
#
|
161
|
+
|
162
|
+
opts.on("--scrobbler-user MANDATORY", "Username for which recent tracks are pulled off last.fm") do |v|
|
163
|
+
options[:scrobbler_user] = v
|
164
|
+
end
|
165
|
+
|
166
|
+
opts.on("--twitter-user MANDATORY", "Twitter user the recent tracks are posted to") do |v|
|
167
|
+
options[:twitter_user] = v
|
168
|
+
end
|
169
|
+
|
170
|
+
opts.on("--twitter-password MANDATORY", "Twitter password") do |v|
|
171
|
+
options[:twitter_password] = v
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# behavioral flags
|
176
|
+
#
|
177
|
+
|
178
|
+
opts.on("-n", "--no-post", "Do not post status line to Twitter, instead write it to stdout.") do |v|
|
179
|
+
options[:no_post] = true
|
180
|
+
end
|
181
|
+
|
182
|
+
opts.on("-HMANDATORY", "--history MANDATORY", "assume the supplied history value") do |v|
|
183
|
+
options[:history] = v
|
184
|
+
end
|
185
|
+
|
186
|
+
opts.on("-mMANDATORY", "--max MANDATORY", "post only the <max> most recent songs") do |v|
|
187
|
+
options[:max] = v.to_i
|
188
|
+
end
|
189
|
+
|
190
|
+
opts.on("-s", "--stateless", "Do not read and write preferences file, implies --no-save") do |v|
|
191
|
+
options[:stateless] = true
|
192
|
+
options[:no_save] = true
|
193
|
+
end
|
194
|
+
|
195
|
+
opts.on("--no-save", "do not write preferences file") do |v|
|
196
|
+
options[:no_save] = true
|
197
|
+
end
|
198
|
+
end
|
199
|
+
op.parse!
|
200
|
+
|
201
|
+
options
|
202
|
+
end
|
203
|
+
|
204
|
+
def full_prefs_file_path
|
205
|
+
File.join(preferences_dir, PREFERENCES_FILE_NAME)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'shorturl'
|
2
|
+
|
3
|
+
module Twitterscrobble
|
4
|
+
class StatusLine
|
5
|
+
TWITTER_MAX_MSG_LEN = 140
|
6
|
+
|
7
|
+
def initialize(track)
|
8
|
+
@track = track
|
9
|
+
end
|
10
|
+
|
11
|
+
# TODO
|
12
|
+
# The algorithm to use the maximum number of characters is not the best yet.
|
13
|
+
# We should also try to cut down single fields that are overly long in favor of
|
14
|
+
# not loosing another short field.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
#
|
18
|
+
# track.name = "A"
|
19
|
+
# track.artist = "Very long artist name that is close to the maximum length of the whole line"
|
20
|
+
#
|
21
|
+
# The algorithm below would just return "A", but a better version would return "Very long ... - A".
|
22
|
+
#
|
23
|
+
#
|
24
|
+
def to_s
|
25
|
+
status = with_name
|
26
|
+
|
27
|
+
if with_artist.length <= TWITTER_MAX_MSG_LEN
|
28
|
+
status = with_artist
|
29
|
+
end
|
30
|
+
|
31
|
+
if with_album.length <= TWITTER_MAX_MSG_LEN
|
32
|
+
status = with_album
|
33
|
+
end
|
34
|
+
|
35
|
+
if with_url.length <= TWITTER_MAX_MSG_LEN
|
36
|
+
status = with_url
|
37
|
+
end
|
38
|
+
|
39
|
+
# if status.length > TWITTER_MAX_MSG_LEN # still too long, enforce length restriction
|
40
|
+
# status = "#{status[1, 137]}..."
|
41
|
+
# end
|
42
|
+
|
43
|
+
status
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def with_name
|
48
|
+
"Now playing: #{CGI::escapeHTML(@track.name)}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def with_artist
|
52
|
+
if @track.artist.blank?
|
53
|
+
with_name
|
54
|
+
else
|
55
|
+
"Now playing: #{CGI::escapeHTML(@track.artist)} - #{CGI::escapeHTML(@track.name)}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def with_album
|
60
|
+
if @track.album.blank?
|
61
|
+
with_artist
|
62
|
+
else
|
63
|
+
"#{with_artist} (from #{CGI::escapeHTML(@track.album)})"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def with_url
|
68
|
+
if @track.url.blank?
|
69
|
+
with_album
|
70
|
+
else
|
71
|
+
"#{with_album} #{ShortURL.shorten(@track.url)}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'scrobbler'
|
2
|
+
require 'twitter'
|
3
|
+
|
4
|
+
module Twitterscrobble
|
5
|
+
#
|
6
|
+
# Read the latest tracks of a user from last.fm and post them to Twitter.
|
7
|
+
#
|
8
|
+
class TwitterScrobbler
|
9
|
+
TWITTER_SOURCE_PARAM = "twitterscrobble"
|
10
|
+
|
11
|
+
def initialize(prefs)
|
12
|
+
@prefs = prefs
|
13
|
+
@logger = @prefs.logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def update
|
17
|
+
@logger.info("Reading recent tracks for #{@prefs.scrobbler_user}")
|
18
|
+
|
19
|
+
# Order by date_uts so that we can rely on tracks being steady
|
20
|
+
tracks = Scrobbler::User.new(@prefs.scrobbler_user).recent_tracks.sort{|x,y| x.date_uts <=> y.date_uts }
|
21
|
+
|
22
|
+
if !@prefs.max.blank? && 0 < @prefs.max
|
23
|
+
@logger.info("Limiting number of posted songs to #{@prefs.max}")
|
24
|
+
tracks = tracks[@prefs.max * -1, @prefs.max]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Filter already posted tracks
|
28
|
+
tracks.reject!{|track|
|
29
|
+
if track.date_uts.to_i <= @prefs.history.to_i
|
30
|
+
@logger.info("Skipping #{track.artist} - #{track.name} because #{track.date_uts.to_i} <= #{@prefs.history.to_i}")
|
31
|
+
true
|
32
|
+
end
|
33
|
+
}
|
34
|
+
|
35
|
+
@logger.info("No new tracks since #{Time.at(@prefs.history.to_i).to_s}") if 0 == tracks.size
|
36
|
+
|
37
|
+
tracks.each{|track|
|
38
|
+
status = StatusLine.new(track)
|
39
|
+
|
40
|
+
begin
|
41
|
+
if @prefs.no_post
|
42
|
+
puts status
|
43
|
+
else
|
44
|
+
@logger.info("Posting new status: '#{status}'")
|
45
|
+
Twitter::Base.new(@prefs.twitter_user, @prefs.twitter_password).update(status, {:source => TWITTER_SOURCE_PARAM})
|
46
|
+
end
|
47
|
+
|
48
|
+
@prefs.history = track.date_uts.to_i
|
49
|
+
rescue
|
50
|
+
@logger.error("Error: #{$!}")
|
51
|
+
end
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: twitterscrobble
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas E. Rabenau
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-22 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.7.0
|
24
|
+
version:
|
25
|
+
description: Posts recently played tracks from last.fm to Twitter.
|
26
|
+
email:
|
27
|
+
- nerab@gmx.at
|
28
|
+
executables:
|
29
|
+
- twitterscrobble
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- History.txt
|
34
|
+
- License.txt
|
35
|
+
- Manifest.txt
|
36
|
+
- PostInstall.txt
|
37
|
+
- README.txt
|
38
|
+
files:
|
39
|
+
- History.txt
|
40
|
+
- License.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- PostInstall.txt
|
43
|
+
- README.txt
|
44
|
+
- Rakefile
|
45
|
+
- bin/twitterscrobble
|
46
|
+
- lib/twitterscrobble.rb
|
47
|
+
- lib/twitterscrobble/preferences.rb
|
48
|
+
- lib/twitterscrobble/status_line.rb
|
49
|
+
- lib/twitterscrobble/twitter_scrobbler.rb
|
50
|
+
- lib/twitterscrobble/version.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://twitterscrobble.rubyforge.org
|
53
|
+
post_install_message: |
|
54
|
+
For more information on twitterscrobble, see http://twitterscrobble.rubyforge.org
|
55
|
+
|
56
|
+
rdoc_options:
|
57
|
+
- --main
|
58
|
+
- README.txt
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: twitterscrobble
|
76
|
+
rubygems_version: 1.2.0
|
77
|
+
signing_key:
|
78
|
+
specification_version: 2
|
79
|
+
summary: Posts recently played tracks from last.fm to Twitter.
|
80
|
+
test_files:
|
81
|
+
- test/test_helper.rb
|
82
|
+
- test/test_twitterscrobble.rb
|