mirror of
https://github.com/transmission/transmission
synced 2025-03-20 10:45:43 +00:00
refactor: use tr_torrent_metainfo in mac client (#2343)
This commit is contained in:
parent
68582d2ca6
commit
3f8cf63e59
5 changed files with 93 additions and 113 deletions
|
@ -53,6 +53,7 @@
|
|||
#include "session.h"
|
||||
#include "subprocess.h"
|
||||
#include "torrent-magnet.h"
|
||||
#include "torrent-metainfo.h"
|
||||
#include "torrent.h"
|
||||
#include "tr-assert.h"
|
||||
#include "trevent.h" /* tr_runInEventThread() */
|
||||
|
@ -103,6 +104,16 @@ tr_torrent* tr_torrentFindFromHash(tr_session* session, tr_sha1_digest_t const*
|
|||
return hash == nullptr ? nullptr : session->getTorrent(*hash);
|
||||
}
|
||||
|
||||
tr_torrent* tr_torrentFindFromMetainfo(tr_session* session, tr_torrent_metainfo const* metainfo)
|
||||
{
|
||||
if (session == nullptr || metainfo == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tr_torrentFindFromHash(session, &metainfo->infoHash());
|
||||
}
|
||||
|
||||
tr_torrent* tr_torrentFindFromMagnetLink(tr_session* session, char const* magnet_link)
|
||||
{
|
||||
auto mm = tr_magnet_metainfo{};
|
||||
|
|
|
@ -52,6 +52,7 @@ struct tr_file;
|
|||
struct tr_info;
|
||||
struct tr_session;
|
||||
struct tr_torrent;
|
||||
struct tr_torrent_metainfo;
|
||||
struct tr_variant;
|
||||
|
||||
using tr_priority_t = int8_t;
|
||||
|
@ -1068,6 +1069,8 @@ int tr_torrentId(tr_torrent const* torrent);
|
|||
|
||||
tr_torrent* tr_torrentFindFromId(tr_session* session, int id);
|
||||
|
||||
tr_torrent* tr_torrentFindFromMetainfo(tr_session*, tr_torrent_metainfo const*);
|
||||
|
||||
tr_torrent* tr_torrentFindFromHash(tr_session* session, tr_sha1_digest_t const* hash);
|
||||
|
||||
/** @brief Convenience function similar to tr_torrentFindFromHash() */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <atomic> /* atomic, atomic_fetch_add_explicit, memory_order_relaxed */
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/torrent-metainfo.h>
|
||||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/variant.h>
|
||||
|
||||
|
@ -1063,31 +1064,19 @@ static void removeKeRangerRansomware()
|
|||
|
||||
for (NSString* torrentPath in filenames)
|
||||
{
|
||||
//ensure torrent doesn't already exist
|
||||
tr_ctor* ctor = tr_ctorNew(fLib);
|
||||
tr_ctorSetMetainfoFromFile(ctor, torrentPath.UTF8String);
|
||||
|
||||
tr_info info;
|
||||
tr_parse_result const result = tr_torrentParse(ctor, &info);
|
||||
tr_ctorFree(ctor);
|
||||
|
||||
if (result != TR_PARSE_OK)
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (!metainfo.parseTorrentFile(torrentPath.UTF8String)) // invalid torrent
|
||||
{
|
||||
if (result == TR_PARSE_DUPLICATE)
|
||||
if (type != ADD_AUTO)
|
||||
{
|
||||
[self duplicateOpenAlert:@(info.name)];
|
||||
[self invalidOpenAlert:torrentPath.lastPathComponent];
|
||||
}
|
||||
else if (result == TR_PARSE_ERR)
|
||||
{
|
||||
if (type != ADD_AUTO)
|
||||
{
|
||||
[self invalidOpenAlert:torrentPath.lastPathComponent];
|
||||
}
|
||||
}
|
||||
else
|
||||
NSAssert2(NO, @"Unknown error code (%d) when attempting to open \"%@\"", result, torrentPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
tr_metainfoFree(&info);
|
||||
if (tr_torrentFindFromMetainfo(fLib, &metainfo) != nullptr) // dupe torrent
|
||||
{
|
||||
[self duplicateOpenAlert:@(metainfo.name().c_str())];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1113,10 +1102,10 @@ static void removeKeRangerRansomware()
|
|||
}
|
||||
|
||||
//determine to show the options window
|
||||
auto const is_multifile = std::size(metainfo.files()) > 1;
|
||||
BOOL const showWindow = type == ADD_SHOW_OPTIONS ||
|
||||
([fDefaults boolForKey:@"DownloadAsk"] && (info.isFolder || ![fDefaults boolForKey:@"DownloadAskMulti"]) &&
|
||||
([fDefaults boolForKey:@"DownloadAsk"] && (is_multifile || ![fDefaults boolForKey:@"DownloadAskMulti"]) &&
|
||||
(type != ADD_AUTO || ![fDefaults boolForKey:@"DownloadAskManual"]));
|
||||
tr_metainfoFree(&info);
|
||||
|
||||
Torrent* torrent;
|
||||
if (!(torrent = [[Torrent alloc] initWithPath:torrentPath location:location
|
||||
|
@ -3329,34 +3318,21 @@ static void removeKeRangerRansomware()
|
|||
continue;
|
||||
}
|
||||
|
||||
tr_ctor* ctor = tr_ctorNew(fLib);
|
||||
tr_ctorSetMetainfoFromFile(ctor, fullFile.UTF8String);
|
||||
|
||||
switch (tr_torrentParse(ctor, NULL))
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (!metainfo.parseTorrentFile(fullFile.UTF8String))
|
||||
{
|
||||
case TR_PARSE_OK:
|
||||
{
|
||||
[self openFiles:@[ fullFile ] addType:ADD_AUTO forcePath:nil];
|
||||
|
||||
NSString* notificationTitle = NSLocalizedString(@"Torrent File Auto Added", "notification title");
|
||||
NSUserNotification* notification = [[NSUserNotification alloc] init];
|
||||
notification.title = notificationTitle;
|
||||
notification.informativeText = file;
|
||||
|
||||
notification.hasActionButton = NO;
|
||||
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
break;
|
||||
}
|
||||
case TR_PARSE_ERR:
|
||||
[fAutoImportedNames removeObject:file];
|
||||
break;
|
||||
|
||||
case TR_PARSE_DUPLICATE: //let's ignore this (but silence a warning)
|
||||
break;
|
||||
}
|
||||
|
||||
tr_ctorFree(ctor);
|
||||
[self openFiles:@[ fullFile ] addType:ADD_AUTO forcePath:nil];
|
||||
|
||||
NSString* notificationTitle = NSLocalizedString(@"Torrent File Auto Added", "notification title");
|
||||
NSUserNotification* notification = [[NSUserNotification alloc] init];
|
||||
notification.title = notificationTitle;
|
||||
notification.informativeText = file;
|
||||
notification.hasActionButton = NO;
|
||||
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3650,9 +3626,8 @@ static void removeKeRangerRansomware()
|
|||
[file.pathExtension caseInsensitiveCompare:@"torrent"] == NSOrderedSame)
|
||||
{
|
||||
torrent = YES;
|
||||
tr_ctor* ctor = tr_ctorNew(fLib);
|
||||
tr_ctorSetMetainfoFromFile(ctor, file.UTF8String);
|
||||
if (tr_torrentParse(ctor, NULL) == TR_PARSE_OK)
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (metainfo.parseTorrentFile(file.UTF8String))
|
||||
{
|
||||
if (!fOverlayWindow)
|
||||
{
|
||||
|
@ -3662,7 +3637,6 @@ static void removeKeRangerRansomware()
|
|||
|
||||
return NSDragOperationCopy;
|
||||
}
|
||||
tr_ctorFree(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3721,13 +3695,11 @@ static void removeKeRangerRansomware()
|
|||
[file.pathExtension caseInsensitiveCompare:@"torrent"] == NSOrderedSame)
|
||||
{
|
||||
torrent = YES;
|
||||
tr_ctor* ctor = tr_ctorNew(fLib);
|
||||
tr_ctorSetMetainfoFromFile(ctor, file.UTF8String);
|
||||
if (tr_torrentParse(ctor, NULL) == TR_PARSE_OK)
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (metainfo.parseTorrentFile(file.UTF8String))
|
||||
{
|
||||
[filesToOpen addObject:file];
|
||||
}
|
||||
tr_ctorFree(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#import "DragOverlayView.h"
|
||||
#import "NSStringAdditions.h"
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/torrent-metainfo.h>
|
||||
|
||||
@interface DragOverlayWindow (Private)
|
||||
|
||||
- (void)resizeWindow;
|
||||
|
@ -83,7 +86,6 @@
|
|||
NSInteger count = 0;
|
||||
|
||||
NSString* name;
|
||||
BOOL folder;
|
||||
NSInteger fileCount = 0;
|
||||
|
||||
for (NSString* file in files)
|
||||
|
@ -91,24 +93,20 @@
|
|||
if ([[NSWorkspace.sharedWorkspace typeOfFile:file error:NULL] isEqualToString:@"org.bittorrent.torrent"] ||
|
||||
[file.pathExtension caseInsensitiveCompare:@"torrent"] == NSOrderedSame)
|
||||
{
|
||||
tr_ctor* ctor = tr_ctorNew(fLib);
|
||||
tr_ctorSetMetainfoFromFile(ctor, file.UTF8String);
|
||||
tr_info info;
|
||||
if (tr_torrentParse(ctor, &info) == TR_PARSE_OK)
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (metainfo.parseTorrentFile(file.UTF8String))
|
||||
{
|
||||
count++;
|
||||
size += info.totalSize;
|
||||
fileCount += info.fileCount;
|
||||
++count;
|
||||
|
||||
//only useful when one torrent
|
||||
if (count == 1)
|
||||
size += metainfo.totalSize();
|
||||
|
||||
auto const n_files = std::size(metainfo.files());
|
||||
fileCount += n_files;
|
||||
if (n_files == 1)
|
||||
{
|
||||
name = @(info.name);
|
||||
folder = info.isFolder;
|
||||
name = @(metainfo.name().c_str());
|
||||
}
|
||||
}
|
||||
tr_metainfoFree(&info);
|
||||
tr_ctorFree(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@
|
|||
|
||||
//set strings and icon
|
||||
NSString* secondString = [NSString stringForFileSize:size];
|
||||
if (count > 1 || folder)
|
||||
if (count > 1)
|
||||
{
|
||||
NSString* fileString;
|
||||
if (fileCount == 1)
|
||||
|
@ -137,7 +135,7 @@
|
|||
NSImage* icon;
|
||||
if (count == 1)
|
||||
{
|
||||
icon = [NSWorkspace.sharedWorkspace iconForFileType:folder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : name.pathExtension];
|
||||
icon = [NSWorkspace.sharedWorkspace iconForFileType:name ? name.pathExtension : NSFileTypeForHFSTypeCode(kGenericFolderIcon)];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#import <QuickLook/QuickLook.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
#include <libtransmission/torrent-metainfo.h>
|
||||
|
||||
#import "NSStringAdditions.h"
|
||||
|
||||
OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
|
||||
|
@ -47,12 +51,8 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
[NSApplication sharedApplication];
|
||||
|
||||
//try to parse the torrent file
|
||||
tr_info inf;
|
||||
tr_ctor* ctor = tr_ctorNew(NULL);
|
||||
tr_ctorSetMetainfoFromFile(ctor, [[(__bridge NSURL*)url path] UTF8String]);
|
||||
int const err = tr_torrentParse(ctor, &inf);
|
||||
tr_ctorFree(ctor);
|
||||
if (err)
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
if (!metainfo.parseTorrentFile([[(__bridge NSURL*)url path] UTF8String]))
|
||||
{
|
||||
return noErr;
|
||||
}
|
||||
|
@ -67,8 +67,11 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
|
||||
NSMutableDictionary* allImgProps = [NSMutableDictionary dictionary];
|
||||
|
||||
NSString* name = [NSString stringWithUTF8String:inf.name];
|
||||
NSString* fileTypeString = inf.isFolder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension];
|
||||
NSString* name = [NSString stringWithUTF8String:metainfo.name().c_str()];
|
||||
|
||||
auto const n_files = std::size(metainfo.files());
|
||||
auto const is_multifile = n_files > 1;
|
||||
NSString* fileTypeString = is_multifile ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension];
|
||||
|
||||
NSUInteger const width = 32;
|
||||
[htmlString appendFormat:@"<h2><img class=\"icon\" src=\"%@\" width=\"%ld\" height=\"%ld\" />%@</h2>",
|
||||
|
@ -77,28 +80,22 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
width,
|
||||
name];
|
||||
|
||||
NSString* fileSizeString = [NSString stringForFileSize:inf.totalSize];
|
||||
if (inf.isFolder)
|
||||
NSString* fileSizeString = [NSString stringForFileSize:metainfo.totalSize()];
|
||||
if (is_multifile)
|
||||
{
|
||||
NSString* fileCountString;
|
||||
if (inf.fileCount == 1)
|
||||
{
|
||||
fileCountString = NSLocalizedStringFromTableInBundle(@"1 file", nil, bundle, "quicklook file count");
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCountString = [NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ files", nil, bundle, "quicklook file count"),
|
||||
[NSString formattedUInteger:inf.fileCount]];
|
||||
}
|
||||
NSString* fileCountString = [NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ files", nil, bundle, "quicklook file count"),
|
||||
[NSString formattedUInteger:n_files]];
|
||||
fileSizeString = [NSString stringWithFormat:@"%@, %@", fileCountString, fileSizeString];
|
||||
}
|
||||
[htmlString appendFormat:@"<p>%@</p>", fileSizeString];
|
||||
|
||||
NSString* dateCreatedString = inf.dateCreated > 0 ?
|
||||
[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:inf.dateCreated] dateStyle:NSDateFormatterLongStyle
|
||||
auto const date_created = metainfo.dateCreated();
|
||||
NSString* dateCreatedString = date_created > 0 ?
|
||||
[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:date_created] dateStyle:NSDateFormatterLongStyle
|
||||
timeStyle:NSDateFormatterShortStyle] :
|
||||
nil;
|
||||
NSString* creatorString = inf.creator ? [NSString stringWithUTF8String:inf.creator] : nil;
|
||||
auto const& creator = metainfo.creator();
|
||||
NSString* creatorString = !std::empty(creator) ? [NSString stringWithUTF8String:creator.c_str()] : nil;
|
||||
if ([creatorString isEqualToString:@""])
|
||||
{
|
||||
creatorString = nil;
|
||||
|
@ -126,29 +123,31 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
[htmlString appendFormat:@"<p>%@</p>", creationString];
|
||||
}
|
||||
|
||||
if (inf.comment)
|
||||
auto const& commentStr = metainfo.comment();
|
||||
if (!std::empty(commentStr))
|
||||
{
|
||||
NSString* comment = [NSString stringWithUTF8String:inf.comment];
|
||||
NSString* comment = [NSString stringWithUTF8String:commentStr.c_str()];
|
||||
if (![comment isEqualToString:@""])
|
||||
[htmlString appendFormat:@"<p>%@</p>", comment];
|
||||
}
|
||||
|
||||
NSMutableArray* lists = [NSMutableArray array];
|
||||
|
||||
if (inf.webseedCount > 0)
|
||||
auto const n_webseeds = std::size(metainfo.webseeds());
|
||||
if (n_webseeds > 0)
|
||||
{
|
||||
NSMutableString* listSection = [NSMutableString string];
|
||||
[listSection appendString:@"<table>"];
|
||||
|
||||
NSString* headerTitleString = inf.webseedCount == 1 ?
|
||||
NSString* headerTitleString = n_webseeds == 1 ?
|
||||
NSLocalizedStringFromTableInBundle(@"1 Web Seed", nil, bundle, "quicklook web seed header") :
|
||||
[NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ Web Seeds", nil, bundle, "quicklook web seed header"),
|
||||
[NSString formattedUInteger:inf.webseedCount]];
|
||||
[NSString formattedUInteger:n_webseeds]];
|
||||
[listSection appendFormat:@"<tr><th>%@</th></tr>", headerTitleString];
|
||||
|
||||
for (int i = 0; i < inf.webseedCount; ++i)
|
||||
for (auto const& url : metainfo.webseeds())
|
||||
{
|
||||
[listSection appendFormat:@"<tr><td>%s<td></tr>", inf.webseeds[i]];
|
||||
[listSection appendFormat:@"<tr><td>%s<td></tr>", url.c_str()];
|
||||
}
|
||||
|
||||
[listSection appendString:@"</table>"];
|
||||
|
@ -156,12 +155,13 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
[lists addObject:listSection];
|
||||
}
|
||||
|
||||
if (!std::empty(*inf.announce_list))
|
||||
auto const& announce_list = metainfo.announceList();
|
||||
if (!std::empty(announce_list))
|
||||
{
|
||||
NSMutableString* listSection = [NSMutableString string];
|
||||
[listSection appendString:@"<table>"];
|
||||
|
||||
auto const n = std::size(*inf.announce_list);
|
||||
auto const n = std::size(announce_list);
|
||||
NSString* headerTitleString = n == 1 ?
|
||||
NSLocalizedStringFromTableInBundle(@"1 Tracker", nil, bundle, "quicklook tracker header") :
|
||||
[NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ Trackers", nil, bundle, "quicklook tracker header"),
|
||||
|
@ -169,7 +169,7 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
[listSection appendFormat:@"<tr><th>%@</th></tr>", headerTitleString];
|
||||
|
||||
#warning handle tiers?
|
||||
for (auto const tracker : *inf.announce_list)
|
||||
for (auto const& tracker : announce_list)
|
||||
{
|
||||
[listSection appendFormat:@"<tr><td>%s<td></tr>", tracker.announce_str.c_str()];
|
||||
}
|
||||
|
@ -179,22 +179,20 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
[lists addObject:listSection];
|
||||
}
|
||||
|
||||
if (inf.isFolder)
|
||||
if (is_multifile)
|
||||
{
|
||||
NSMutableString* listSection = [NSMutableString string];
|
||||
[listSection appendString:@"<table>"];
|
||||
|
||||
NSString* fileTitleString = inf.fileCount == 1 ?
|
||||
NSLocalizedStringFromTableInBundle(@"1 File", nil, bundle, "quicklook file header") :
|
||||
[NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ Files", nil, bundle, "quicklook file header"),
|
||||
[NSString formattedUInteger:inf.fileCount]];
|
||||
NSString* fileTitleString = [NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"%@ Files", nil, bundle, "quicklook file header"),
|
||||
[NSString formattedUInteger:n_files]];
|
||||
[listSection appendFormat:@"<tr><th>%@</th></tr>", fileTitleString];
|
||||
|
||||
#warning display size?
|
||||
#warning display folders?
|
||||
for (int i = 0; i < inf.fileCount; ++i)
|
||||
for (auto const& file : metainfo.files())
|
||||
{
|
||||
NSString* fullFilePath = [NSString stringWithUTF8String:inf.files[i].name];
|
||||
NSString* fullFilePath = [NSString stringWithUTF8String:file.path().c_str()];
|
||||
NSCAssert([fullFilePath hasPrefix:[name stringByAppendingString:@"/"]], @"Expected file path %@ to begin with %@/", fullFilePath, name);
|
||||
|
||||
NSString* shortenedFilePath = [fullFilePath substringFromIndex:[name length] + 1];
|
||||
|
@ -219,8 +217,6 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
|
||||
[htmlString appendString:@"</body></html>"];
|
||||
|
||||
tr_metainfoFree(&inf);
|
||||
|
||||
NSDictionary* props = @{
|
||||
(NSString*)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8",
|
||||
(NSString*)kQLPreviewPropertyMIMETypeKey : @"text/html",
|
||||
|
|
Loading…
Add table
Reference in a new issue