cinch-lastfm-ng 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 152993ef98f4f263a40182239f4e8b26b330794a
4
+ data.tar.gz: 2e21e9d1705a3f3716493547e8fae317d11698b0
5
+ SHA512:
6
+ metadata.gz: 78d2bfa57e5e6e5459b80f4a0699639901f583959b45acb2012a7c41ed68fc5c10a21e198e8e090ae21bcf8872525d1c4c0bcfaf2a984fb0f7a59b49af1e2403
7
+ data.tar.gz: 217ddf8274a0faed2880cce4125e69cfbc35bc0d2db78952a8e5a430ce801e20fc31c090a5702457db4466b18562ce3c850eed50f144d26731a680832c146739
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Lilian Jónsdóttir
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ Last.fm Plugin for Cinch
2
+ ========================
3
+ Display recently played tracks, search artists, display top
4
+ artists/albums/tracks from specified time period, search tags, display profile
5
+ information, etc.
6
+
7
+ Usage
8
+ -----
9
+
10
+ install the gem with *gem install Cinch-Automode*, and
11
+ add it to your bot like so:
12
+
13
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ruby
14
+ require 'cinch'
15
+ require 'cinch/plugins/automode'
16
+
17
+ bot = Cinch::Bot.new do
18
+ configure do |c|
19
+ c.server = 'your server'
20
+ c.nick = 'your nick'
21
+ c.realname = 'your realname'
22
+ c.user = 'your user'
23
+ c.channels = ['#yourchannel']
24
+ c.plugins.plugins = [Cinch::Plugins::Automode]
25
+ end
26
+ end
27
+
28
+ bot.start
29
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30
+
31
+ Contained Commands
32
+ ------------------
33
+
34
+ **[automode (on|off)]**
35
+
36
+ Enable/disable the plugin in the current channel. Default is off.
37
+
38
+ **[add (op|halfop|voice) nick user@host]**
39
+
40
+ Add nick with user@host to the auto-(op|halfop|voice) list
41
+
42
+ **[del (op|halfop|voice) nick user@host]**
43
+
44
+ Delete nick with user@host from the auto-(op|halfop|voice) list
45
+
46
+ **[add channel (op|halfop|voice)]**
47
+
48
+ Add the entire channel to the list, so anyone who joins gets the mode.
49
+
50
+ **[del channel (op|halfop|voice)]**
51
+
52
+ Delete the channel from the mode list.
53
+
54
+ License
55
+ -------
56
+
57
+ Licensed under The MIT License (MIT)
58
+
59
+ Please see LICENSE
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,48 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ $LOAD_PATH.push('lib')
4
+ require 'cinch/plugins/lastfm/version.rb'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'cinch-lastfm-ng'
8
+ s.version = Cinch::Lastfm::VERSION.dup
9
+ s.licenses = ['MIT']
10
+ s.date = '2016-05-22'
11
+ s.summary = 'Lastfm plugin for Cinch'
12
+ s.email = 'lilian.jonsdottir@gmail.com'
13
+ s.homepage = 'https://github.com/lilyseki/Cinch-Lastfm'
14
+ s.authors = ['Lily Jónsdóttir']
15
+
16
+ s.description = <<-EOF
17
+ Display recently played tracks, search artists, display top
18
+ artists/albums/tracks from specified time period, search tags, display profile
19
+ information, etc.
20
+ EOF
21
+
22
+ dependencies = [
23
+ [:runtime, 'sequel', '~> 4.34'],
24
+ [:runtime, 'nokogiri', '~> 1.6'],
25
+ [:runtime, 'time_diff', '~> 0.3'],
26
+ [:runtime, 'addressable', '~> 2.4']
27
+ ]
28
+
29
+ s.files = Dir['**/*']
30
+ s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
31
+ s.executables = Dir['bin/*'].map { |f| File.basename(f) }
32
+ s.require_paths = ['lib']
33
+
34
+ ## Make sure you can build the gem on older versions of RubyGems too:
35
+ s.rubygems_version = '2.5.1'
36
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
37
+ s.specification_version = 3 if s.respond_to? :specification_version
38
+
39
+ dependencies.each do |type, name, version|
40
+ if s.respond_to?("add_#{type}_dependency")
41
+ s.send("add_#{type}_dependency", name, version)
42
+ else
43
+ s.add_dependency(name, version)
44
+ end
45
+ end
46
+ end
47
+
48
+ # vim:tabstop=2 softtabstop=2 expandtab shiftwidth=2 smarttab foldmethod=syntax:
@@ -0,0 +1,5 @@
1
+ module Cinch
2
+ module Lastfm
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,522 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding=utf-8
3
+ require 'sequel' # SQLite 3 database
4
+ require 'nokogiri' # Decoding XML/HTML from lastfm api
5
+ require 'cgi' # Escaping/Unescaping HTML entities
6
+ require 'time_diff' # Calculating difference in times
7
+ require 'httparty' # Better HTTP Opening
8
+ require 'addressable/uri'
9
+ require 'webrick/httputils' # Fix for unicode URLs
10
+
11
+ module Cinch
12
+ module Plugins
13
+ # Last.fm plugin
14
+ class Lastfm
15
+ include Cinch::Plugin
16
+
17
+ def initialize(*args)
18
+ super
19
+ @base_url = 'http://ws.audioscrobbler.com/2.0/?api_key='
20
+ @api_key = config[:api_key]
21
+ @api_url = "#{@base_url}#{@api_key}&method="
22
+ # @db = Sequel.sqlite('riria.db')
23
+ filename = "#{@bot.nick.downcase}.db"
24
+ @db = Sequel.sqlite(filename)
25
+ end
26
+
27
+ private
28
+
29
+ def get_user(nick)
30
+ return nil if @db[:lastfm].where(nick: nick).empty?
31
+ usernick = @db[:lastfm].where(nick: nick).first[:username]
32
+ usernick
33
+ end
34
+
35
+ # Remove stupid pointless tags
36
+ def stupid_tags(tagarray)
37
+ tagarray.delete('seen live') # Worst tag on all of last.fm
38
+ tagarray.delete('indie')
39
+
40
+ tagarray
41
+ end
42
+
43
+ # Debug shit
44
+ def header(title)
45
+ puts '=' * 10 + " #{title} " + '=' * 10
46
+ end
47
+
48
+ public
49
+
50
+ # And now onto the commands
51
+ match(/np(?: (.+))?/, method: :np)
52
+ def np(m, query = nil)
53
+ method = 'user.getRecentTracks'
54
+
55
+ user = query.nil? ? get_user(m.user.nick) : get_user(query.strip)
56
+ user = query.nil? ? m.user.nick : query.strip unless user
57
+
58
+ ac = '&autocorrect=1'
59
+ request = "#{@api_url}#{method}&user=#{user}"
60
+
61
+ # Last tracks
62
+ begin
63
+ page = HTTParty.get(Addressable::URI.parse(request))
64
+ doc = Nokogiri::XML(page.body)
65
+ # puts "Fetching #{request}"
66
+
67
+ if doc.xpath('//lfm')[0]['status'] == 'failed'
68
+ puts request
69
+ puts doc
70
+ m.reply "Error: #{doc.xpath('//error')[0].text}"
71
+ return
72
+ end
73
+ nowplaying = doc.xpath('//track')[0]['nowplaying']
74
+
75
+ whenplayed = doc.xpath('//track//date')[0]['uts'].to_i unless nowplaying
76
+
77
+ artist = doc.xpath('//track//artist')[0].text
78
+ title = doc.xpath('//track//name')[0].text
79
+ rescue NoMethodError
80
+ m.reply('No tracks found or username doesn\'t exist!')
81
+ return
82
+ end
83
+
84
+ begin
85
+ album = doc.xpath('//track//album')[0].text
86
+ puts "album = #{album}"
87
+ rescue NoMethodError
88
+ album = nil
89
+ end
90
+
91
+ album = nil if album == ''
92
+
93
+ # Track info
94
+ begin
95
+ header 'TRACK INFO'
96
+ doop = WEBrick::HTTPUtils.escape_form(artist)
97
+ pood = WEBrick::HTTPUtils.escape_form(title)
98
+ # puts doop
99
+ trackreq = "#{@api_url}track.getInfo&artist=#{doop}&track=#{pood}&user=#{user}#{ac}"
100
+ puts "trackreq: #{trackreq}"
101
+ query = trackreq.force_encoding('binary')
102
+ puts "query: #{query}"
103
+ page = HTTParty.get(Addressable::URI.parse(query))
104
+ trackdoc = Nokogiri::XML(page.body)
105
+
106
+ if trackdoc.xpath('//lfm')[0]['status'] == 'failed'
107
+ begin
108
+ m.reply error_code(trackdoc.xpath('//error')['code'].to_i)
109
+ return
110
+ rescue TypeError
111
+ puts 'derp'
112
+ end
113
+ end
114
+ header 'trackdoc'
115
+ puts trackdoc
116
+ header 'end trackdoc'
117
+ # listeners = trackdoc.xpath('//track//listeners').text
118
+ # playcount = trackdoc.xpath('//track//playcount').text
119
+ userpc = trackdoc.xpath('//track//userplaycount').text
120
+ loved = trackdoc.xpath('//track//userloved').text.to_i
121
+ # trackinfo = true
122
+ userplayed = true
123
+ puts userpc
124
+ header 'END TRACK INFO'
125
+ # rescue OpenURI::HTTPError
126
+ # trackinfo = false
127
+ rescue NoMethodError
128
+ userplayed = false
129
+ end
130
+
131
+ # Artist info
132
+ begin
133
+ doop = WEBrick::HTTPUtils.escape_form(artist)
134
+ # puts doop
135
+ artistreq = "#{@api_url}artist.getInfo#{ac}&artist=#{doop}&user=#{user}"
136
+ query = artistreq.force_encoding('binary')
137
+ page = HTTParty.get(Addressable::URI.parse(query))
138
+ artistdoc = Nokogiri::XML(page.body)
139
+ # puts "Fetching #{query}"
140
+ if artistdoc.xpath('//lfm')[0]['status'] == 'failed'
141
+ m.reply error_code(artistdoc.xpath('//error')[0]['code'].to_i)
142
+ return
143
+ end
144
+ artistinfo = false
145
+ toptags = artistdoc.xpath('//tags//tag//name')
146
+ tags = []
147
+ toptags.each { |i| tags << i.text }
148
+ tags = stupid_tags(tags)
149
+ artistinfo = true unless tags.empty?
150
+
151
+ rescue NoMethodError
152
+ artistinfo = false
153
+ end
154
+
155
+ unless nowplaying
156
+ future = if whenplayed > Time.now.to_i
157
+ true
158
+ else
159
+ false
160
+ end
161
+ end
162
+
163
+ output = nowplaying ? '♫' : '♪'
164
+ output << " #{artist} :: #{title}"
165
+ output << " [#{album}]" if album
166
+ output << ' ♥' unless loved.zero?
167
+ unless nowplaying
168
+ output << ' :: in ' + Time.diff(Time.at(whenplayed), Time.now)[:diff].to_s if future
169
+ output << ' :: ' + Time.diff(Time.at(whenplayed), Time.now)[:diff].to_s + ' ago' unless future
170
+ end
171
+ # output << ' ::' if nowplaying
172
+ output << " :: #{userpc} plays" if userplayed && !userpc.empty?
173
+ # output << " #{playcount} by #{listeners} others." if trackinfo
174
+ if artistinfo
175
+ len = tags.length >= 3 ? 3 : tags.length
176
+ output << ' :: '
177
+ tags.first(len).each_with_index do |i, j|
178
+ output.concat j == len - 1 ? i.to_s : "#{i}, "
179
+ end
180
+ output << ' ::'
181
+ else
182
+ output << ' :: no tags ::'
183
+ end
184
+ m.reply output
185
+ end
186
+
187
+ match(/artist(?: (.+))?/, method: :artist_search)
188
+ match(/plays(?: (.+))?/, method: :artist_search)
189
+ def artist_search(m, query)
190
+ method = 'artist.getInfo'
191
+ specific_user = false
192
+
193
+ list = query.split
194
+ if list.include?('-user')
195
+ specific_user = true
196
+ user_index = list.index('-user')
197
+ band = if user_index.zero?
198
+ list[user_index + 2..-1]
199
+ else
200
+ list[0..user_index - 1] + list[user_index + 2..-1]
201
+ end
202
+ query = band.join ' '
203
+ puts query
204
+ user = list[user_index + 1]
205
+ user = get_user(user) unless get_user(user).nil?
206
+ else
207
+ user = get_user(m.user.nick)
208
+ user = m.user.nick if user.nil? || user.empty?
209
+ end
210
+
211
+ artist = query.force_encoding('binary')
212
+ artist = WEBrick::HTTPUtils.escape_form(artist)
213
+ ac = '&autocorrect=1'
214
+
215
+ artistreq = "#{@api_url}#{method}#{ac}&artist=#{artist}&user=#{user}"
216
+ page = HTTParty.get(Addressable::URI.parse(artistreq))
217
+ doc = Nokogiri::XML(page.body)
218
+ puts "Fetching #{artistreq}"
219
+
220
+ begin
221
+ a = doc.xpath('//artist//name')[0].text
222
+ toptags = doc.xpath('//tags//tag//name')
223
+ listeners = doc.xpath('//stats//listeners').text
224
+ playcount = doc.xpath('//stats//playcount').text
225
+ rescue NoMethodError
226
+ m.reply('Artist not found!')
227
+ return
228
+ end
229
+ begin
230
+ userpc = doc.xpath('//stats//userplaycount').text
231
+ userpc = nil if userpc == ''
232
+ rescue NoMethodError
233
+ userpc = nil
234
+ end
235
+
236
+ tags = []
237
+ toptags.each { |i| tags << i.text }
238
+ tags = stupid_tags(tags)
239
+
240
+ len = tags.length >= 3 ? 3 : tags.length
241
+ notags = tags.empty? ? true : false
242
+
243
+ output = a.to_s
244
+ if notags
245
+ output << ' :: no tags'
246
+ else
247
+ output << ' :: '
248
+ tags.first(len).each_with_index do |i, j|
249
+ output.concat j == len - 1 ? i.to_s : "#{i}, "
250
+ end
251
+ end
252
+ output.concat userpc ? " :: #{userpc} plays" : ' :: '
253
+ output << " by #{user} :: " if specific_user && userpc
254
+ output << ' :: ' if userpc && !specific_user
255
+ output << "#{playcount} by #{listeners} others ::"
256
+ m.reply output
257
+ end
258
+
259
+ # Currently broken per Last.fm
260
+ match(/compare(?: (.+))?/, method: :compare)
261
+ def compare(m, user1, user2 = nil)
262
+ method = 'tasteometer.compare'
263
+ user2 = get_user(m.user.nick) unless user2
264
+
265
+ creq = "#{@api_url}#{method}&type1=user&type2=user&value1=#{user1}&value2=&#{user2}"
266
+ puts creq
267
+ page = HTTParty.get(Addressable::URI.parse(creq))
268
+ doc = Nokogiri::XML(page.body)
269
+ if doc.xpath('//lfm')[0]['status'] == 'failed'
270
+ m.reply("#{doc.xpath('//error')[0]['code']}: #{doc.xpath('//error').text}")
271
+ # return
272
+ end
273
+ puts doc
274
+ end
275
+
276
+ # My probably lousy attempt at not reusing code
277
+ match(/topartists(:? (.+))?/, method: :top_artists)
278
+ def top_artists(m, p)
279
+ tops(m, 'user.getTopArtists', p, 'artists')
280
+ end
281
+
282
+ match(/toptracks(:? (.+))?/, method: :top_tracks)
283
+ def top_tracks(m, p)
284
+ tops(m, 'user.getTopTracks', p, 'tracks')
285
+ end
286
+
287
+ match(/topalbums(:? (.+))?/, method: :top_albums)
288
+ def top_albums(m, p)
289
+ tops(m, 'user.getTopAlbums', p, 'albums')
290
+ end
291
+
292
+ def tops(m, meth, period, type)
293
+ # method = 'user.getTopArtists'
294
+ method = meth
295
+ period = 'overall' if period.nil?
296
+
297
+ period.strip!
298
+ list = period.split
299
+ if list.include?('-user')
300
+ user_index = list.index('-user')
301
+ per = if user_index.zero?
302
+ list[user_index + 2..-1]
303
+ else
304
+ list[0..user_index - 1] + list[user_index + 2..-1]
305
+ end
306
+ period = per.join ' '
307
+ user = list[user_index + 1]
308
+ else
309
+ user = get_user(m.user.nick)
310
+ user = m.user.nick if user.nil? || user.empty?
311
+ end
312
+
313
+ case period
314
+ when '7d', '7day'
315
+ period = '7day'
316
+ str = '7 days'
317
+ when '1m', '1month'
318
+ period = '1month'
319
+ str = '1 month'
320
+ when '3m', '3month'
321
+ period = '3month'
322
+ str = '3 months'
323
+ when '6m', 'month'
324
+ period = '6month'
325
+ str = '6 months'
326
+ when '1y', '1year', '12m', '12month'
327
+ period = '12month'
328
+ str = '1 year'
329
+ else
330
+ period = 'overall'
331
+ str = period
332
+ end
333
+
334
+ urlget = "#{@api_url}#{method}&period=#{period}&user=#{user}&limit=10"
335
+ puts urlget
336
+ page = HTTParty.get(Addressable::URI.parse(urlget))
337
+ doc = Nokogiri::XML(page.body)
338
+ # puts "doc: #{doc.text}"
339
+
340
+ # This will only ever be true for 'overall'
341
+ output = if str == period
342
+ "#{str.capitalize} top #{type} "
343
+ else
344
+ "Top #{type} of the past #{str} "
345
+ end
346
+
347
+ # process the doc differently depending on query type (artists, tracks,
348
+ # albums, tags, etc.) There's probably a less shitty way to do this but
349
+ # oh well, I tried to not be redundant a bunch
350
+ if method == 'user.getTopArtists'
351
+ artists = []
352
+ plays_in_period = []
353
+ doc.xpath('//topartists//name').each { |i| artists << i.text }
354
+ doc.xpath('//topartists//playcount').each { |i| plays_in_period << i.text }
355
+
356
+ # Combine the two arrays into a single hash.
357
+ artplays = Hash[artists.zip(plays_in_period)]
358
+ puts "Artists: #{artists}: #{artists.class}"
359
+ puts "Artplays: #{artplays}: #{artplays.class}"
360
+
361
+ len = artplays.length >= 5 ? 5 : artplays.length
362
+ artplays.first(len).each_with_index do |(name, plays), i|
363
+ puts "name: #{name} :: plays: #{plays}, i: #{i}"
364
+ output << ":: #{name} (#{plays})"
365
+ output.concat i == len - 1 ? ' ::' : ' '
366
+ end
367
+ elsif method == 'user.getTopTracks'
368
+ artists = []
369
+ tracks = []
370
+ track_plays = []
371
+ doc.xpath('//artist//name').each { |i| artists << i.text }
372
+ doc.xpath('/lfm/toptracks/track/name').each { |i| tracks << i.text }
373
+ doc.xpath('//track//playcount').each { |i| track_plays << i.text }
374
+
375
+ puts "Artists: #{artists.length}, #{artists}"
376
+ puts "Tracks: #{tracks.length}, #{tracks}"
377
+ puts "Playcount: #{track_plays.length}, #{track_plays}"
378
+
379
+ unless artists.length == tracks.length && track_plays.length == tracks.length
380
+ # Something went horribly wrong, abort!
381
+ m.reply('Fission mailed!')
382
+ return
383
+ end
384
+ len = tracks.length >= 5 ? 5 : tracks.length
385
+ len.times do |i|
386
+ output << ":: #{artists[i]} - #{tracks[i]} (#{track_plays[i]})"
387
+ output.concat i == len - 1 ? ' ::' : ' '
388
+ end
389
+ elsif method == 'user.getTopAlbums'
390
+ artists = []
391
+ albums = []
392
+ album_plays = []
393
+ doc.xpath('//artist//name').each { |i| artists << i.text }
394
+ doc.xpath('/lfm/topalbums/album/name').each { |i| albums << i.text }
395
+ doc.xpath('//album//playcount').each { |i| album_plays << i.text }
396
+
397
+ puts "Artists: #{artists.length}, #{artists}"
398
+ puts "Albums: #{albums.length}, #{albums}"
399
+ puts "Playcount: #{album_plays.length}, #{album_plays}"
400
+
401
+ unless artists.length == albums.length && album_plays.length == albums.length
402
+ # Something went horribly wrong, abort!
403
+ m.reply('Fission mailed!')
404
+ return
405
+ end
406
+ len = albums.length >= 5 ? 5 : albums.length
407
+ len.times do |i|
408
+ output << ":: #{artists[i]} - #{albums[i]} (#{album_plays[i]})"
409
+ output.concat i == len - 1 ? ' ::' : ' '
410
+ end
411
+ end
412
+
413
+ m.reply output
414
+ end
415
+
416
+ # This doesn't seem to work either. Thanks last.fm
417
+ match(/toptags(:? (.+))?/, method: :top_tags)
418
+ def top_tags(m, u)
419
+ user = u.nil? ? get_user(m.user.nick) : get_user(u.strip)
420
+ user = u.nil? ? m.user.nick : u.strip unless user
421
+
422
+ method = 'user.getTopTags'
423
+ urlget = "#{@api_url}#{method}&user=#{user}&limit=10"
424
+ puts urlget
425
+ page = HTTParty.get(Addressable::URI.parse(urlget))
426
+ doc = Nokogiri::XML(page.body)
427
+
428
+ tags = []
429
+ counts = []
430
+
431
+ doc.xpath('//name').each { |i| tags << i }
432
+ doc.xpath('//count').each { |i| counts << i }
433
+ output = "#{user}'s most used tags "
434
+
435
+ tagusage = Hash[tags.zip(counts)]
436
+
437
+ len = tagusage.length >= 5 ? 5 : tagusage.length
438
+ tagusage.first(len).each_with_index do |(name, plays), i|
439
+ puts "name: #{name} :: plays: #{plays}, i: #{i}"
440
+ output << ":: #{name} (#{plays})"
441
+ output.concat i == len - 1 ? ' ::' : ' '
442
+ end
443
+ output = 'User has not tagged anything!' if tags.empty? || counts.empty?
444
+ m.reply output
445
+ end
446
+
447
+ match(/tag(:? (.+))?/, method: :tag_search)
448
+ def tag_search(m, query)
449
+ method = 'tag.getInfo'
450
+ urlget = "#{@api_url}#{method}&tag=#{query.strip}"
451
+ puts urlget
452
+ page = HTTParty.get(Addressable::URI.parse(urlget))
453
+ doc = Nokogiri::XML(page.body)
454
+
455
+ num_used = doc.xpath('//tag//total').text
456
+ name = doc.xpath('//tag//name').text
457
+ # Clean up the summary: remove HTML tags, truncate, etc.
458
+ summary = doc.xpath('//tag//wiki//summary').text.gsub(%r{<\/?[^>]*>}, '')
459
+ summary.sub!('Read more on Last.fm.', '')
460
+ summary = if summary.length > 220
461
+ summary[0..220] + '...'
462
+ else
463
+ summary
464
+ end
465
+ summary = '???' if summary.strip.empty?
466
+ output = "#{name} :: Used: #{num_used} times :: #{summary} ::"
467
+ output += " http://www.last.fm/tag/#{name} ::"
468
+ m.reply output
469
+ end
470
+
471
+ match(/profile(:? (.+))?/, method: :profile)
472
+ def profile(m, query)
473
+ method = 'user.getInfo'
474
+
475
+ user = query.nil? ? get_user(m.user.nick) : get_user(query.strip)
476
+ user = query.nil? ? m.user.nick : query.strip unless user
477
+
478
+ # Fetch the data
479
+ url = "#{@api_url}#{method}&user=#{user}"
480
+ page = HTTParty.get(Addressable::URI.parse(url))
481
+ doc = Nokogiri::XML(page.body)
482
+
483
+ realname = doc.xpath('//realname').text
484
+ realname = 'No name' if realname.empty?
485
+ gender = doc.xpath('//gender').text
486
+ playcount = doc.xpath('//playcount').text
487
+ userurl = doc.xpath('//url').text
488
+ country = doc.xpath('//country').text
489
+ country = 'Nowhere' if country.empty?
490
+ reg = doc.xpath('//registered')[0]['unixtime']
491
+ regdate = DateTime.strptime(reg, '%s')
492
+
493
+ output = "#{user} :: #{realname} / #{gender} / #{country}"
494
+ output << " :: Plays: #{playcount}"
495
+ output << " :: Registered on: #{regdate.day} #{regdate.strftime('%b')} #{regdate.year}"
496
+ output << " :: #{userurl}"
497
+ m.reply(output)
498
+ end
499
+
500
+ match(/fmset(?: (.+))?/, method: :fmset)
501
+ def fmset(m, username = nil)
502
+ m.reply 'You need to input a username to set your username' && return if username.nil?
503
+ username = username.strip
504
+ if @db[:lastfm].where(nick: m.user.nick).empty?
505
+ @db[:lastfm].insert(nick: m.user.nick, username: username)
506
+ else
507
+ uid = @db[:lastfm].where(nick: m.user.nick).first[:id]
508
+ @db[:lastfm].where(id: uid).update(username: username)
509
+ end
510
+ m.reply "#{m.user.nick} is now #{username}!"
511
+ end
512
+
513
+ match(/fmget(?: (.+))?/, method: :fmget)
514
+ def fmget(m)
515
+ user = get_user(m.user.nick)
516
+ m.reply user ? "#{m.user.nick} is #{user}!" : 'I don\'t know your username!'
517
+ end
518
+ end
519
+ end
520
+ end
521
+
522
+ # vim:tabstop=2 softtabstop=2 expandtab shiftwidth=2 smarttab foldmethod=syntax:
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cinch-lastfm-ng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lily Jónsdóttir
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.34'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.34'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: time_diff
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: addressable
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.4'
69
+ description: |
70
+ Display recently played tracks, search artists, display top
71
+ artists/albums/tracks from specified time period, search tags, display profile
72
+ information, etc.
73
+ email: lilian.jonsdottir@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - LICENSE
79
+ - README.md
80
+ - VERSION
81
+ - cinch-lastfm-ng.gemspec
82
+ - lib/cinch/plugins/lastfm.rb
83
+ - lib/cinch/plugins/lastfm/version.rb
84
+ homepage: https://github.com/lilyseki/Cinch-Lastfm
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.5.1
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Lastfm plugin for Cinch
108
+ test_files: []
109
+ has_rdoc: