154 lines
6.9 KiB
Objective-C
Executable File
154 lines
6.9 KiB
Objective-C
Executable File
//
|
|
// 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:@"</label>\n</div>\n</div>"].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:@"</label>\n</div>\n</div>"];
|
|
if (tableStartRange.location == NSNotFound) {
|
|
//No Results
|
|
return [[NSArray alloc] init];
|
|
}
|
|
NSRange tableRange = [self restRangeFromString:resultsPage subtractingRange:tableStartRange];
|
|
int resultsTableStart = NSMaxRange([resultsPage rangeOfString:@"<ul>" options:NSCaseInsensitiveSearch range:tableRange]);
|
|
NSRange resultsTableEndRange = [resultsPage rangeOfString:@"<li id=\"" options:NSCaseInsensitiveSearch range:tableRange];
|
|
if (resultsTableEndRange.location == NSNotFound) {
|
|
resultsTableEndRange = [resultsPage rangeOfString:@"</ul>" 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:@"<li>"].location;
|
|
while (currentIndex != NSNotFound) {
|
|
int startIndex = currentIndex + [@"<li>" length];
|
|
int endIndex = [table rangeOfString:@"</li>" 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 -= [@"</li>" length];
|
|
restRange.location += [@"</li>" length];
|
|
currentIndex = [table rangeOfString:@"<li>" options:NSCaseInsensitiveSearch range:restRange].location;
|
|
}
|
|
return tags;
|
|
}
|
|
|
|
-(SearchResult *) searchResultFromTag: (NSString *)tag {
|
|
NSRange artistStartRange = [tag rangeOfString:@"Songtexte, Übersetzungen, Lyrics\"><span>"];
|
|
NSRange artistEndRange = [tag rangeOfString:@"</span>" 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:@"<a" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:artistEndRange]];
|
|
/*if ([tag rangeOfString:@"title=\"zum Song (noch kein Songtext vorhanden)\"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:songLinkStartRange]].location != NSNotFound) {
|
|
return nil;
|
|
}*/
|
|
//This would remove entries which does not exist anymore.
|
|
//The Problem: hasMoreResults woult also return YES if there is only one result (no matter if existing or not).
|
|
NSRange hrefStartRange = [tag rangeOfString:@"href=\"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:songLinkStartRange]];
|
|
NSRange hrefEndRange = [tag rangeOfString:@"\"" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:hrefStartRange]];
|
|
int hrefStart = NSMaxRange(hrefStartRange);
|
|
NSString *linkHref = [tag substringWithRange:NSMakeRange(hrefStart, hrefEndRange.location-hrefStart)];
|
|
NSRange nameStartRange = [tag rangeOfString:@"<span>" options:NSCaseInsensitiveSearch range:[self restRangeFromString:tag subtractingRange:hrefEndRange]];
|
|
NSRange nameEndRange = [tag rangeOfString:@"</span>" 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:@"<div id=\"lyrics\">"];
|
|
NSRange lyricsEndRange = [page rangeOfString:@"</div>" 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
|