//
// Songtexte.m
// iLyrics
//
// Created by Kim Wittenburg on 22.06.12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
// TODO: Implement parsing of multi-page results
#import "Songtexte.h"
#import "SearchResult.h"
@implementation Songtexte {
NSString *resultsPage;
BOOL hasMoreResults;
BOOL hadMoreResults;
}
@synthesize enabled;
-(NSString *) name {
return @"Songtexte.com";
}
-(NSDate *)hosterVersion {
return [NSDate dateWithString:@"2012-06-22 15:00:00 +0100"];
}
-(void) startNewSearchForQuery: (NSString *)query {
NSString *searchPath = [NSString stringWithFormat:@"http://www.songtexte.com/search?c=songs&q=%@", [query stringByFormattingForURL]];
NSURL *searchURL = [NSURL URLWithString:searchPath];
NSError *error;
NSString *page = [NSString stringWithContentsOfURL:searchURL encoding:NSUTF8StringEncoding error:&error];
if (error || page == nil) {
//Network or other error
resultsPage = nil;
hasMoreResults = hadMoreResults = NO;
}
resultsPage = page;
if ([resultsPage rangeOfString:@"\n\n"].location == NSNotFound) {
//No Results
hasMoreResults = hadMoreResults = NO;
} else {
hasMoreResults = hadMoreResults = YES;
}
}
-(BOOL)hasMoreResults {
return hasMoreResults;
}
-(NSArray *)nextResults {
if (resultsPage == nil) {
//Network or other error
return nil;
}
NSRange tableStartRange = [resultsPage rangeOfString:@"\n\n"];
if (tableStartRange.location == NSNotFound) {
//No Results
return [[NSArray alloc] init];
}
NSRange tableRange = [self restRangeFromString:resultsPage subtractingRange:tableStartRange];
int resultsTableStart = NSMaxRange([resultsPage rangeOfString:@"
" options:NSCaseInsensitiveSearch range:tableRange]);
NSRange resultsTableEndRange = [resultsPage rangeOfString:@"- " options:NSCaseInsensitiveSearch range:tableRange];
}
int resultsTableEnd = resultsTableEndRange.location;
hasMoreResults = NO;
return [self resultsFromTable:[resultsPage substringWithRange:NSMakeRange(resultsTableStart, resultsTableEnd-resultsTableStart)]];
}
-(NSArray *)resultsFromTable:(NSString *)table {
NSRange restRange = NSMakeRange(0, [table length]);
NSMutableArray *tags = [[NSMutableArray alloc] init];
NSUInteger currentIndex = [table rangeOfString:@"
- "].location;
while (currentIndex != NSNotFound) {
int startIndex = currentIndex + [@"
- " length];
int endIndex = [table rangeOfString:@"
" options:NSCaseInsensitiveSearch range:restRange].location;
NSRange tagRange = NSMakeRange(startIndex, endIndex-startIndex);
SearchResult *result = [self searchResultFromTag:[table substringWithRange:tagRange]];
if (result) {
[tags addObject:result];
}
restRange = [self restRangeFromString:table subtractingRange:tagRange];
restRange.length -= [@"" length];
restRange.location += [@"" length];
currentIndex = [table rangeOfString:@"- " options:NSCaseInsensitiveSearch range:restRange].location;
}
return tags;
}
-(SearchResult *) searchResultFromTag: (NSString *)tag {
NSRange artistStartRange = [tag rangeOfString:@"Songtexte, Übersetzungen, Lyrics\">"];
NSRange artistEndRange = [tag rangeOfString:@"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:artistStartRange]];
int artistStart = NSMaxRange(artistStartRange);
NSString *artist = [[tag substringWithRange:NSMakeRange(artistStart, artistEndRange.location-artistStart)] stringByRemovingHTMLTags];
NSRange songLinkStartRange = [tag rangeOfString:@"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:hrefEndRange]];
NSRange nameEndRange = [tag rangeOfString:@"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:nameStartRange]];
int nameStart = NSMaxRange(nameStartRange);
NSString *name = [[tag substringWithRange:NSMakeRange(nameStart, nameEndRange.location-nameStart)] stringByRemovingHTMLTags];
return [[SearchResult alloc] initWithName:name fromArtist:artist preview:nil link:[self urlFromHref:linkHref] loadedByHoster:self];
}
-(NSURL*) urlFromHref: (NSString *) link {
if (![link hasPrefix:@"http://www.songtexte.com"]) {
return [NSURL URLWithString:[NSString stringWithFormat:@"http://www.songtexte.com/%@", link]];
} else {
return [NSURL URLWithString:link];
}
}
-(NSRange) restRangeFromString: (NSString *) page subtractingRange: (NSRange) aRange {
int loc = NSMaxRange(aRange);
return NSMakeRange(loc, [page length]-loc);
}
-(void)resetLoadedResults {
hasMoreResults = hadMoreResults;
}
-(Lyrics *)lyricsBySearchResult:(id)result {
NSError *error;
NSString *page = [NSString stringWithContentsOfURL:[result link] encoding:NSUTF8StringEncoding error:&error];
if (error || page == nil) {
return nil;
}
NSRange lyricsStartRange = [page rangeOfString:@"
"];
NSRange lyricsEndRange = [page rangeOfString:@"
" options:NSCaseInsensitiveSearch range:[self restRangeFromString:page subtractingRange:lyricsStartRange]];
int lyricsStart = NSMaxRange(lyricsStartRange);
NSString *lyrics = [[page substringWithRange:NSMakeRange(lyricsStart, lyricsEndRange.location-lyricsStart)] stringByRemovingHTMLTags];
return [[Lyrics alloc] initWithName:[result name] byArtist:[result artist] withLyrics:lyrics];
}
-(BOOL)canShowInBrowser:(id)result {
return YES;
}
-(void)showInBrowser:(id)result {
[[NSWorkspace sharedWorkspace] openURL:[result link]];
}
@end