Archived
1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ilyrics/iLyrics/Songtexte.m
Kim Wittenburg 41b1ef775c -Added Songtexte.com Lyrics Hoster
-Repositioned the load more results button into the outline view
-Improved the replacing of html escape characters
-Lyrics Hosters can now be dragged into a preferred order in the preference window
-Changed results outline's column ordering method
-Some code changes
-Replaced the Buttons in the lyrics pane with an action button
-Preferred order of lyrics hosters will now be saved
-Translation Improvements
2012-06-24 14:22:37 +02:00

154 lines
6.9 KiB
Objective-C

//
// 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