Class: Lyrics

Inherits:
Object
  • Object
show all
Defined in:
lib/lyrics/lyrics.rb

Defined Under Namespace

Classes: FetchPageData, Request, Response, Suggestion

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cleanup_lyrics = true, logger = nil) ⇒ Lyrics

Returns a new instance of Lyrics.



209
210
211
212
213
214
215
# File 'lib/lyrics/lyrics.rb', line 209

def initialize( cleanup_lyrics=true, logger=nil )
	super()
	@cleanup_lyrics = cleanup_lyrics
	@logger = logger
	@tabulation = nil
	@skip_tabulation = false
end

Instance Attribute Details

#cleanup_lyricsObject

Returns the value of attribute cleanup_lyrics.



206
207
208
# File 'lib/lyrics/lyrics.rb', line 206

def cleanup_lyrics
  @cleanup_lyrics
end

Class Method Details

.build_google_feeling_lucky_url(artist, title = nil) ⇒ Object

default implementation, overide if there is a more accurate expression for a specific site



520
521
522
523
524
525
# File 'lib/lyrics/lyrics.rb', line 520

def Lyrics.build_google_feeling_lucky_url( artist, title=nil )
	query = Strings.google_search_quote( artist )
	query << " " << Strings.google_search_quote( title ) if title
	query << " lyrics"
	return Strings.build_google_feeling_lucky_url( query, self.site_host() )
end

.build_song_add_url(request) ⇒ Object



249
250
251
# File 'lib/lyrics/lyrics.rb', line 249

def Lyrics.build_song_add_url( request )
	return nil
end

.known_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


257
258
259
# File 'lib/lyrics/lyrics.rb', line 257

def Lyrics.known_url?( url )
	return url.index( "http://#{site_host}" ) == 0
end

.lyrics_test_dataObject

NOTE: if possible use popular song that are likely to be indexed by google. We are not testing here how good or complete a site is but if the site plugin is behaving as expected. We part from the assumption that every plugin should be able to get lyrics and suggestions for the values returned here.



535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'lib/lyrics/lyrics.rb', line 535

def Lyrics.lyrics_test_data()
	return [
		Request.new( "Nirvana", "Smells Like Teen Spirit", "Nevermind" ),
		Request.new( "Radiohead", "Optimistic", "Kid A" ),
		Request.new( "Massive Attack", "Protection", "Protection" ),
		Request.new( "Pearl Jam", "Porch", "Ten" ),
# 			Request.new( "The Cranberries", "Linger", "Everybody Else Is Doing It, So Why Can't We?" ),
# 			Request.new( "Radiohead", "Idioteque", "Kid A" ),
# 			Request.new( "Radiohead", "How To Disappear Completely","stitle"=>"How To Dissapear", "Kid A" ),
# 			Request.new( "Pearl Jam", "Love Boat Captain", "Riot Act" ),
# 			Request.new( "Blur", "No Distance Left To Run", "13" ),
# 			Request.new( "Opeth", "Hope Leaves", "Damnation" ),
# 			Request.new( "Megadeth", "À tout le monde", "Youthanasia" ),
# 			Request.new( "Metallica", "Master of Puppets", "Master of Puppets" ),
# 			Request.new( "Lacuna Coil", "Heaven's a Lie", "Comalies" ),
# 			Request.new( "Pearl Jam", "Porch", "Ten" ),
# 			Request.new( "Portishead", "Wandering Star", "Dummy" ),
	]
end

.suggestions_test_dataObject



559
560
561
# File 'lib/lyrics/lyrics.rb', line 559

def Lyrics.suggestions_test_data()
	return lyrics_test_data()
end

Instance Method Details

#build_google_feeling_lucky_url(artist, title = nil) ⇒ Object



527
528
529
# File 'lib/lyrics/lyrics.rb', line 527

def build_google_feeling_lucky_url( artist, title=nil )
	return self.class.build_google_feeling_lucky_url( artist, title )
end

#build_lyrics_fetch_data(request) ⇒ Object

Returns a FetchPageData instance



270
271
272
# File 'lib/lyrics/lyrics.rb', line 270

def build_lyrics_fetch_data( request )
	return FetchPageData.new( nil )
end

#build_song_add_url(request) ⇒ Object



253
254
255
# File 'lib/lyrics/lyrics.rb', line 253

def build_song_add_url( request )
	return self.class.build_song_add_url( request )
end

#build_suggestions_fetch_data(request) ⇒ Object

Returns a FetchPageData instance



380
381
382
# File 'lib/lyrics/lyrics.rb', line 380

def build_suggestions_fetch_data( request )
	return FetchPageData.new( nil )
end

#decrease_tabulation_levelObject



237
238
239
# File 'lib/lyrics/lyrics.rb', line 237

def decrease_tabulation_level()
	@logger.decrease_tabulation_level() if @logger
end

#fetch_lyrics_page(fetch_data) ⇒ Object

Returns the lyrics page body (or nil if it couldn’t be retrieved) and the corresponding url (or nil)



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/lyrics/lyrics.rb', line 275

def fetch_lyrics_page( fetch_data )

	return nil, nil if ! fetch_data.url

	log( "Fetching lyrics page... ", 0 )
	if fetch_data.post_data
		response, url = HTTP.fetch_page_post( fetch_data.url, fetch_data.post_data, fetch_data.headers_data )
	else
		response, url = HTTP.fetch_page_get( fetch_data.url, fetch_data.headers_data )
	end

	if response && response.body()
		log( "OK" )
		log( response.body(), 2 ) if verbose_log?
		return response.body(), url
	else
		log( "ERROR" )
		return nil, url
	end

end

#fetch_suggestions_page(fetch_data) ⇒ Object

Returns the lyrics page body (nil if it couldn’t be retrieved) and the response url



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/lyrics/lyrics.rb', line 385

def fetch_suggestions_page( fetch_data )

	return nil, nil if ! fetch_data.url

	log( fetch_data.to_s() + "\nFetching suggestions page... ", 0 )

	if fetch_data.post_data
		response, url = HTTP.fetch_page_post( fetch_data.url, fetch_data.post_data, fetch_data.headers_data )
	else
		response, url = HTTP.fetch_page_get( fetch_data.url, fetch_data.headers_data )
	end

	if response && response.body()
		log( "OK" )
		log( response.body(), 2 ) if verbose_log?
		return response.body(), url
	else
		log( "ERROR" )
		return nil, url
	end

end

#increase_tabulation_levelObject



233
234
235
# File 'lib/lyrics/lyrics.rb', line 233

def increase_tabulation_level()
	@logger.increase_tabulation_level() if @logger
end

#known_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


261
262
263
# File 'lib/lyrics/lyrics.rb', line 261

def known_url?( url )
	return self.class.known_url?( url )
end

#log(message, new_lines = 1) ⇒ Object



229
230
231
# File 'lib/lyrics/lyrics.rb', line 229

def log( message, new_lines=1 )
	@logger.log( message, new_lines ) if @logger
end

#log?Boolean

Returns:

  • (Boolean)


217
218
219
# File 'lib/lyrics/lyrics.rb', line 217

def log?()
	return @logger != nil
end

#logger=(logger) ⇒ Object



225
226
227
# File 'lib/lyrics/lyrics.rb', line 225

def logger=( logger )
	@logger = logger
end

#lyrics_direct_search(request) ⇒ Object

Returns a Lyrics::Response object



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/lyrics/lyrics.rb', line 310

def lyrics_direct_search( request )

	fetch_data = build_lyrics_fetch_data( request )

	log(
		site_name().upcase() + "\n" +
		"Attempting LYRICS DIRECT SEARCH...\n" +
		request.to_s() + "\n" +
		fetch_data.to_s()
	)

	page_body, page_url = fetch_lyrics_page( fetch_data )

	response = Response.new( request )

	if page_body
		if lyrics_page_valid?( request, page_body, page_url )
			log( "Parsing lyrics... ", 0 )
			response.url = page_url
			parse_lyrics( response, page_body )
			log( response.lyrics ? "LYRICS FOUND" : "LYRICS NOT FOUND" )
			log( response.to_s() )
			log( " - parsed lyrics:\n[#{lyrics_data.lyrics}" ) if verbose_log?
			response.lyrics = Strings.cleanup_lyrics( response.lyrics ) if response.lyrics && @cleanup_lyrics
		else
			log( "LYRICS PAGE IS INVALID" )
		end
	end

	return response

end

#lyrics_from_suggestions(request, suggestions = nil) ⇒ Object



478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/lyrics/lyrics.rb', line 478

def lyrics_from_suggestions( request, suggestions=nil )

	log( site_name().upcase() + "\nSearching LYRICS FROM SUGGESTIONS..." )

	suggestions = suggestions( request ) if suggestions == nil

	normalized_artist, normalized_title = Strings.normalize( request.artist ), Strings.normalize( request.title )

	log( "Scanning suggestions... ", 0 )
	suggestions.each() do |suggestion|
		next if ! suggestion.is_a?( Suggestion )
		if Strings.normalize( suggestion.artist ) == normalized_artist &&
		   Strings.normalize( suggestion.title ) == normalized_title
			log( "MATCH FOUND\n" + suggestion.to_s() )
			# TODO should we use request.album and request.year here?
			response = lyrics_from_url(
				Request.new( suggestion.artist, suggestion.title, request.album, request.year ),
				suggestion.url
			)
			return response, suggestions if response.lyrics
		end
	end

	log( "NO VALID MATCH FOUND" )

	return Response.new( request ), suggestions

end

#lyrics_from_url(request, url) ⇒ Object

Returns a Lyrics::Response object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/lyrics/lyrics.rb', line 344

def lyrics_from_url( request, url )

	response = Response.new( request )

	if ! known_url?( url )
		log( site_name().upcase() + "\nCan't handle received URL: " + url )
		return response
	end

	fetch_data = build_lyrics_fetch_data( request )
	fetch_data = FetchPageData.new( url, fetch_data.post_data, fetch_data.headers_data )

	log(
		site_name().upcase() + "\n" +
		"Retrieving LYRICS FROM URL...\n" +
		request.to_s() + "\n" +
		fetch_data.to_s()
	)

	page_body, url = fetch_lyrics_page( fetch_data )

	if page_body
		log( "Parsing lyrics... ", 0 )
		response.url = url
		parse_lyrics( response, page_body )
		log( response.lyrics ? "LYRICS FOUND" : "LYRICS NOT FOUND" )
		log( response.to_s() )
		log( " - parsed lyrics:\n[#{lyrics_data.lyrics}]" ) if verbose_log?
		response.lyrics = Strings.cleanup_lyrics( response.lyrics ) if response.lyrics && @cleanup_lyrics
	end

	return response

end

#lyrics_full_search(request) ⇒ Object

Returns a Lyrics::Response object



508
509
510
511
512
513
514
515
516
517
# File 'lib/lyrics/lyrics.rb', line 508

def lyrics_full_search( request )

	# LYRICS DIRECT SEARCH:
	response = lyrics_direct_search( request )
	return response if response.lyrics

	# NOT FOUND, SEARCH IN SUGGESTIONS:
	response, suggs = lyrics_from_suggestions( request, suggestions( request ) )
	return response
end

#lyrics_page_valid?(request, page_body, page_url) ⇒ Boolean

NOTE: override for example if your using google feeling lucky to verify that the resulting page is not just some random (trashy) result. Returns false is page_body does not correspond to the requested lyrics

Returns:

  • (Boolean)


300
301
302
# File 'lib/lyrics/lyrics.rb', line 300

def lyrics_page_valid?( request, page_body, page_url )
	return true
end

#lyrics_test_dataObject



555
556
557
# File 'lib/lyrics/lyrics.rb', line 555

def lyrics_test_data()
	return self.class.lyrics_test_data()
end

#notify(message) ⇒ Object



265
266
267
# File 'lib/lyrics/lyrics.rb', line 265

def notify( message )
	puts "#{site_name()}: #{message}"
end

#site_hostObject



241
242
243
# File 'lib/lyrics/lyrics.rb', line 241

def site_host()
	return self.class.site_host()
end

#site_nameObject



245
246
247
# File 'lib/lyrics/lyrics.rb', line 245

def site_name()
	return self.class.site_name()
end

#suggestions(request) ⇒ Object

Returns an array of maps { url, artist, title }



422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/lyrics/lyrics.rb', line 422

def suggestions( request )

	log( site_name().upcase() + "\nRetrieving SUGGESTIONS...\n" + request.to_s() )

	fetch_data = build_suggestions_fetch_data( request )
	suggestions = []

	suggestions_rec( request, fetch_data, suggestions, 0 )

	return suggestions

end

#suggestions_page_valid?(request, page_body, page_url) ⇒ Boolean

NOTE: override for example if your using google feeling lucky to verify that the resulting page is not just some random (trashy) result. Returns false is body does not correspond to the required suggestions page

Returns:

  • (Boolean)


411
412
413
# File 'lib/lyrics/lyrics.rb', line 411

def suggestions_page_valid?( request, page_body, page_url )
	return true
end

#suggestions_test_dataObject



563
564
565
# File 'lib/lyrics/lyrics.rb', line 563

def suggestions_test_data()
	return self.class.suggestions_test_data()
end

#verbose_log?Boolean

Returns:

  • (Boolean)


221
222
223
# File 'lib/lyrics/lyrics.rb', line 221

def verbose_log?()
	return log? && $VERBOSE_LOG
end