FSDirectory, FSItem, FileListController, ChooseServerToAddController, AppDelegate were changed to support new feature of downloading separate files when user wants to add torrent

This commit is contained in:
Alexey Chechetkin
2015-07-20 15:05:14 +03:00
parent e2ce29d745
commit 8a86597122
17 changed files with 269 additions and 61 deletions

View File

@@ -16,6 +16,7 @@
#import "InfoMessage.h"
#import "FSDirectory.h"
#import "Bencoding.h"
#import "TRFileInfo.h"
@interface AppDelegate() <RPCConnectorDelegate>
@@ -33,6 +34,8 @@
NSString *_magnetURLString;
NSArray *_unwantedFilesIdx;
// flag showing - that we use background fetching
BOOL _isBackgroundFetching;
@@ -87,6 +90,11 @@
// handle url - it is a .torrent file or magnet url
if( url )
{
// FIX: when user tryes to load file serveral times in a row
if( _chooseNav )
{
[_chooseNav dismissViewControllerAnimated:NO completion:nil];
}
//NSLog(@"URL Scheme: %@, desc:%@", url.scheme, url );
_torrentFileDataToAdd = nil;
@@ -107,6 +115,7 @@
if (trData)
{
fs = [FSDirectory directory];
// get name
trName = trData[@"info"][@"name"];
@@ -115,17 +124,28 @@
for( NSDictionary *fileDesc in trData[@"info"][@"files"] )
{
c += [fileDesc[@"length"] longLongValue];
long long fileLength = [fileDesc[@"length"] longLongValue];
c += fileLength;
NSMutableString *fileFullPath = [NSMutableString string];
for( NSString *path in fileDesc[@"path"] )
[fileFullPath appendString:path];
[fileFullPath appendFormat:@"/%@", path];
FSItem *item = [fs addFilePath:fileFullPath withIndex:idx];
TRFileInfo *info = [[TRFileInfo alloc] init];
info.length = fileLength;
info.lengthString = formatByteCount(fileLength);
info.wanted = YES;
info.downloadProgress = 0.1;
info.downloadProgressString = @"";
item.info = info;
[fs addFilePath:fileFullPath withIndex:idx];
idx++;
}
[fs sort];
trSize = formatByteCount(c);
}
}
@@ -140,6 +160,9 @@
// presenting view controller to choose from several remote servers
ChooseServerToAddTorrentController *chooseServerController = instantiateController( CONTROLLER_ID_CHOOSESERVER );
if( fs )
chooseServerController.files = fs;
chooseServerController.headerInfoMessage = _magnetURLString ?
[NSString stringWithFormat: NSLocalizedString(@"Add torrent with magnet link:\n%@", @""), _magnetURLString] :
[NSString stringWithFormat: NSLocalizedString(@"Add torrent with file size: %@", @""), trName, trSize ];
@@ -188,7 +211,12 @@
RPCConnector *connector = [[RPCConnector alloc] initWithConfig:config andDelegate:self];
if( _torrentFileDataToAdd )
[connector addTorrentWithData:_torrentFileDataToAdd priority:priority startImmidiately:startNow];
{
if( _unwantedFilesIdx )
[connector addTorrentWithData:_torrentFileDataToAdd priority:priority startImmidiately:startNow indexesUnwanted:_unwantedFilesIdx];
else
[connector addTorrentWithData:_torrentFileDataToAdd priority:priority startImmidiately:startNow];
}
else if( _magnetURLString )
[connector addTorrentWithMagnet:_magnetURLString priority:priority startImmidiately:startNow];
}
@@ -224,6 +252,12 @@
{
ChooseServerToAddTorrentController *csc = (ChooseServerToAddTorrentController*)_chooseNav.viewControllers[0];
if( csc.files )
{
NSArray *tmp = csc.files.rootItem.fileIndexesUnwanted;
_unwantedFilesIdx = ( tmp && tmp.count > 0 ) ? tmp : nil;
}
[self addTorrentToServerWithRPCConfig:csc.rpcConfig priority:csc.bandwidthPriority startNow:csc.startImmidiately];
[self dismissChooseServerController];
@@ -232,6 +266,7 @@
- (void)dismissChooseServerController
{
[_chooseNav dismissViewControllerAnimated:YES completion:nil];
_chooseNav = nil;
}
- (void)applicationWillResignActive:(UIApplication *)application

View File

@@ -9,15 +9,4 @@
#import "BandwidthPriorityCell.h"
@implementation BandwidthPriorityCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end

View File

@@ -877,6 +877,34 @@
<outlet property="swith" destination="8Xo-qK-Lg9" id="Obv-oB-AZH"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="filesToDownloadCell" id="rGb-hW-mc3" customClass="StartImmidiatelyCell">
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="rGb-hW-mc3" id="iJu-YW-dij">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="filesIcon" translatesAutoresizingMaskIntoConstraints="NO" id="hYt-OA-7yO">
<rect key="frame" x="8" y="4" width="36" height="36"/>
<constraints>
<constraint firstAttribute="width" constant="36" id="0B8-2J-VzR"/>
<constraint firstAttribute="height" constant="36" id="kEY-KD-Kyt"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Select files to download" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="F3g-l8-p6g">
<rect key="frame" x="52" y="13" width="507" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="centerY" secondItem="F3g-l8-p6g" secondAttribute="centerY" id="1tE-gL-LUT"/>
<constraint firstItem="F3g-l8-p6g" firstAttribute="leading" secondItem="hYt-OA-7yO" secondAttribute="trailing" constant="8" symbolic="YES" id="57N-eG-JU4"/>
<constraint firstAttribute="trailingMargin" secondItem="F3g-l8-p6g" secondAttribute="trailing" id="Hem-9z-Kd9"/>
<constraint firstItem="hYt-OA-7yO" firstAttribute="leading" secondItem="iJu-YW-dij" secondAttribute="leadingMargin" id="PMT-4z-RvR"/>
<constraint firstAttribute="centerY" secondItem="hYt-OA-7yO" secondAttribute="centerY" id="fcT-Kl-Ked"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="QX4-Ch-2jm" id="LbQ-Hb-M9x"/>
@@ -1156,8 +1184,8 @@
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="y5J-Q4-5sy" id="PM0-tm-1rl">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" text="Stop seeding if torrent idle more than(min)" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Aj1-0q-21X">
<rect key="frame" x="8" y="8" width="469" height="27"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalCompressionResistancePriority="1000" text="Stop seeding if torrent idle more than(min)" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.70000000000000018" translatesAutoresizingMaskIntoConstraints="NO" id="Aj1-0q-21X">
<rect key="frame" x="8" y="13" width="469" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
@@ -1178,13 +1206,12 @@
</switch>
</subviews>
<constraints>
<constraint firstItem="Aj1-0q-21X" firstAttribute="top" secondItem="PM0-tm-1rl" secondAttribute="topMargin" id="Hhg-Jb-W5U"/>
<constraint firstItem="UOG-Zv-kEX" firstAttribute="trailing" secondItem="PM0-tm-1rl" secondAttribute="trailingMargin" id="Sr5-yy-CWI"/>
<constraint firstItem="Jyj-0e-xdY" firstAttribute="leading" secondItem="Aj1-0q-21X" secondAttribute="trailing" constant="8" symbolic="YES" id="Ycl-cC-igY"/>
<constraint firstItem="UOG-Zv-kEX" firstAttribute="leading" secondItem="Jyj-0e-xdY" secondAttribute="trailing" constant="8" symbolic="YES" id="dcI-Xq-z2e"/>
<constraint firstAttribute="centerY" secondItem="Aj1-0q-21X" secondAttribute="centerY" id="llV-1Q-tID"/>
<constraint firstAttribute="centerY" secondItem="UOG-Zv-kEX" secondAttribute="centerY" id="mQ1-I9-YcE"/>
<constraint firstItem="Aj1-0q-21X" firstAttribute="leading" secondItem="PM0-tm-1rl" secondAttribute="leadingMargin" id="qlg-J6-oag"/>
<constraint firstAttribute="bottomMargin" secondItem="Aj1-0q-21X" secondAttribute="bottom" id="sZ4-F5-fjK"/>
<constraint firstAttribute="centerY" secondItem="Jyj-0e-xdY" secondAttribute="centerY" id="tcT-QJ-UNM"/>
</constraints>
</tableViewCellContentView>

View File

@@ -10,14 +10,5 @@
@implementation ChooseServerCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end

View File

@@ -9,8 +9,10 @@
#import <UIKit/UIKit.h>
#import "GlobalConsts.h"
#import "CommonTableController.h"
#import "FSDirectory.h"
#define CONTROLLER_ID_CHOOSESERVER @"chooseServerToAddController"
#define CELL_ID_FILESTODOWNLOAD @"filesToDownloadCell"
@class RPCServerConfig;
@@ -19,5 +21,6 @@
@property(nonatomic,readonly) RPCServerConfig *rpcConfig; // using only for returning config
@property(nonatomic) int bandwidthPriority;
@property(nonatomic) BOOL startImmidiately;
@property(nonatomic) FSDirectory *files;
@end

View File

@@ -11,6 +11,8 @@
#import "ChooseServerCell.h"
#import "BandwidthPriorityCell.h"
#import "StartImmidiatelyCell.h"
#import "FileListController.h"
#import "GlobalConsts.h"
@interface ChooseServerToAddTorrentController ()
@end
@@ -18,8 +20,9 @@
@implementation ChooseServerToAddTorrentController
{
NSArray *_sectionTitles;
int _selectedRow;
NSArray *_sectionTitles;
int _selectedRow;
FileListController *_fileList;
}
- (void)viewDidLoad
@@ -68,7 +71,7 @@
if( section == 0 )
return [RPCServerConfigDB sharedDB].db.count;
return 2;
return _files ? 3 : 2;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
@@ -79,6 +82,13 @@
_rpcConfig = [RPCServerConfigDB sharedDB].db[indexPath.row];
[self.tableView reloadData];
}
else if( indexPath.section == 1 && indexPath.row == 2 )
{
_fileList = instantiateController(CONTROLLER_ID_FILELIST);
_fileList.fsDir = _files;
_fileList.title = NSLocalizedString(@"Select files to download", @"");
[self.navigationController pushViewController:_fileList animated:YES];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
@@ -89,8 +99,10 @@
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// choose server to add torrent
if( indexPath.section == 0 )
{
ChooseServerCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID_CHOOSESERVER forIndexPath:indexPath];
@@ -108,6 +120,7 @@
return cell;
}
// additional paramters
if( indexPath.section == 1)
{
if( indexPath.row == 0)
@@ -117,13 +130,18 @@
[cell.segment addTarget:self action:@selector(priorityChanged:) forControlEvents:UIControlEventValueChanged];
return cell;
}
else
else if( indexPath.row == 1 )
{
StartImmidiatelyCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID_STARTIMMIDIATELY forIndexPath:indexPath];
cell.swith.on = _startImmidiately;
[cell.swith addTarget:self action:@selector(swithValueChanged:) forControlEvents:UIControlEventValueChanged];
return cell;
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID_FILESTODOWNLOAD forIndexPath:indexPath];
return cell;
}
}
return nil;

View File

@@ -40,12 +40,16 @@ typedef NS_ENUM(unichar, FSItemType)
@property(nonatomic,readonly) float folderDownloadProgress;
@property(nonatomic,readonly) NSString* folderDownloadProgressString;
@property(nonatomic,readonly) BOOL isAllFilesWanted;
@property(nonatomic) BOOL isAllFilesWanted;
@property(nonatomic,readonly) NSArray* fileIndexes;
@property(nonatomic,readonly) NSArray* fileIndexesWanted;
@property(nonatomic,readonly) NSArray* fileIndexesUnwanted;
+ (FSItem*)itemWithName:(NSString*)name andType:(FSItemType)itemType;
- (FSItem*)addItemWithName:(NSString*)name ofType:(FSItemType)itemType;
@end

View File

@@ -157,6 +157,78 @@
}
}
- (void)setIsAllFilesWanted:(BOOL)isAllFilesWanted
{
[self setNeedToRecalcStats];
[self traverse:self setWanted:isAllFilesWanted];
}
- (void)traverse:(FSItem*)item setWanted:(BOOL)wanted
{
if( item.items )
{
for( FSItem *i in item.items )
{
if( i.isFile )
{
if( i.info )
{
i.info.wanted = wanted;
}
}
else
{
[self traverse:i setWanted:wanted];
}
}
}
}
- (NSArray*)fileIndexesUnwanted
{
NSMutableArray *indexes = [NSMutableArray array];
if (_items)
{
for( FSItem *i in _items )
{
if( i.isFile && !i.info.wanted )
{
[indexes addObject:@(i.index)];
}
else
{
[indexes addObjectsFromArray:i.fileIndexesUnwanted];
}
}
}
return indexes;
}
- (NSArray*)fileIndexesWanted
{
NSMutableArray *indexes = [NSMutableArray array];
if (_items)
{
for( FSItem *i in _items )
{
if( i.isFile && i.info.wanted )
{
[indexes addObject:@(i.index)];
}
else
{
[indexes addObjectsFromArray:i.fileIndexesWanted];
}
}
}
return indexes;
}
- (NSArray *)fileIndexes
{
NSMutableArray *indexes = [NSMutableArray array];
@@ -195,6 +267,7 @@
return _allFilesWanted;
}
// add item to children, if it is already exists
// return existing item

View File

@@ -10,6 +10,8 @@
#define CONTROLLER_ID_FILELIST @"fileListController"
@class FSDirectory;
@protocol FileListControllerDelegate <NSObject>
@optional - (void)fileListControllerNeedUpdateFilesForTorrentWithId:(int)torrentId;
@@ -27,5 +29,6 @@
@property(nonatomic) int torrentId;
@property(nonatomic) BOOL torrentIsFinished;
@property(nonatomic) FSDirectory *fsDir;
@end

View File

@@ -27,7 +27,8 @@
UIImage *_iconImgFolderOpened;
UIImage *_iconImgFolderClosed;
FSDirectory *_fsDir;
//FSDirectory *_fsDir;
BOOL _isSelectOnly;
}
- (void)viewDidLoad
@@ -60,6 +61,14 @@
[_delegate fileListControllerNeedUpdateFilesForTorrentWithId:_torrentId];
}
- (void)setFsDir:(FSDirectory *)fsDir
{
_fsDir = fsDir;
_isSelectOnly = YES;
[self.tableView reloadData];
}
// update file infos
- (void)setFileInfos:(NSArray *)fileInfos
{
@@ -98,6 +107,13 @@
BOOL wanted = !item.isAllFilesWanted;
if( _isSelectOnly )
{
item.isAllFilesWanted = wanted;
[self.tableView reloadData];
return;
}
if( _delegate && wanted &&
[_delegate respondsToSelector:@selector(fileListControllerResumeDownloadingFilesWithIndexes:forTorrentWithId:)])
{
@@ -120,6 +136,13 @@
FSItem* item = sender.dataObject;
BOOL wanted = !item.info.wanted;
if( _isSelectOnly )
{
item.info.wanted = wanted;
[self.tableView reloadData];
return;
}
//sender.enabled = NO;
sender.view.userInteractionEnabled = NO;
@@ -216,19 +239,29 @@
if( item.isFile )
{
cell.detailLabel.text = [NSString stringWithFormat: NSLocalizedString(@"%@ of %@, %@ downloaded", @"FileList cell file info"),
item.info.bytesComplitedString,
item.info.lengthString,
item.info.downloadProgressString];
if (_isSelectOnly)
{
cell.detailLabel.text = item.info.lengthString;
}
else
{
cell.detailLabel.text = [NSString stringWithFormat: NSLocalizedString(@"%@ of %@, %@ downloaded", @"FileList cell file info"),
item.info.bytesComplitedString,
item.info.lengthString,
item.info.downloadProgressString];
}
if( item.info.downloadProgress < 1.0f )
{
if( !_isSelectOnly )
{
// configure priority segment control
[cell.prioritySegment addTarget:self action:@selector(prioritySegmentToggled:) forControlEvents:UIControlEventValueChanged];
cell.prioritySegment.dataObject = @(item.index);
cell.prioritySegment.selectedSegmentIndex = item.info.priority + 1;
cell.prioritySegment.enabled = YES;
cell.prioritySegment.hidden = NO;
}
// configure left checkBox control
cell.leftLabel.userInteractionEnabled = YES;
@@ -257,11 +290,19 @@
}
else // it is folder
{
cell.detailLabel.text = [NSString stringWithFormat: NSLocalizedString(@"%i files, %@ of %@, %@ downloaded", @"FileList cell folder info"),
item.filesCount,
item.folderDownloadedString,
item.folderSizeString,
item.folderDownloadProgressString];
if (_isSelectOnly)
{
cell.detailLabel.text = [NSString stringWithFormat:NSLocalizedString( @"%i files, %@", @"" ), item.filesCount, item.folderSizeString];
}
else
{
cell.detailLabel.text = [NSString stringWithFormat: NSLocalizedString(@"%i files, %@ of %@, %@ downloaded", @"FileList cell folder info"),
item.filesCount,
item.folderDownloadedString,
item.folderSizeString,
item.folderDownloadProgressString];
}
if( item.folderDownloadProgress < 1.0 )
{

View File

@@ -56,7 +56,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>288</string>
<string>317</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIBackgroundModes</key>

View File

@@ -54,6 +54,8 @@
- (void)deleteTorrentWithId:(int)torrentId deleteWithData:(BOOL)deleteWithData;
- (void)addTorrentWithData:(NSData*)data priority:(int)priority startImmidiately:(BOOL)startImmidiately;
- (void)addTorrentWithData:(NSData *)data priority:(int)priority startImmidiately:(BOOL)startImmidiately indexesUnwanted:(NSArray*)idxUnwanted;
- (void)addTorrentWithMagnet:(NSString*)magnetURLString priority:(int)priority startImmidiately:(BOOL)startImmidiately;
- (void)getAllPeersForTorrentWithId:(int)torrentId;

View File

@@ -289,6 +289,32 @@
}
- (void)addTorrentWithData:(NSData *)data
priority:(int)priority
startImmidiately:(BOOL)startImmidiately
indexesUnwanted:(NSArray*)idxUnwanted
{
NSString *base64content = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSDictionary *requestVals = @{
TR_METHOD : TR_METHODNAME_TORRENTADD,
TR_METHOD_ARGS : @{ TR_ARG_METAINFO : base64content,
TR_ARG_BANDWIDTHPRIORITY : @(priority),
TR_ARG_PAUSEONADD: startImmidiately ? @(NO):@(YES),
TR_ARG_FIELDS_FILES_UNWANTED : idxUnwanted
}
};
[self makeRequest:requestVals withName:TR_METHODNAME_TORRENTADD andHandler:^(NSDictionary *json)
{
if( _delegate && [_delegate respondsToSelector:@selector(gotTorrentAdded)])
dispatch_async(dispatch_get_main_queue(), ^{
[_delegate gotTorrentAdded];
});
}];
}
- (void)addTorrentWithMagnet:(NSString *)magnetURLString priority:(int)priority startImmidiately:(BOOL)startImmidiately
{
NSDictionary *requestVals = @{

View File

@@ -10,14 +10,4 @@
@implementation StartImmidiatelyCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end

View File

@@ -19,15 +19,21 @@
@property(nonatomic,readonly) NSString* name;
@property(nonatomic,readonly) NSString* fileName;
@property(nonatomic,readonly) long long bytesComplited;
@property(nonatomic,readonly) NSString* bytesComplitedString;
@property(nonatomic,readonly) long long length;
@property(nonatomic,readonly) NSString* lengthString;
@property(nonatomic,readonly) BOOL wanted;
@property(nonatomic) long long bytesComplited;
@property(nonatomic) NSString* bytesComplitedString;
@property(nonatomic) long long length;
@property(nonatomic) NSString* lengthString;
@property(nonatomic) BOOL wanted;
@property(nonatomic,readonly) int priority; /* TR_FILEINFO_PRIORITY */
@property(nonatomic,readonly) NSString* priorityString;
@property(nonatomic,readonly) float downloadProgress; /* 0 .. 1 */
@property(nonatomic,readonly) NSString* downloadProgressString;
@property(nonatomic) float downloadProgress; /* 0 .. 1 */
@property(nonatomic) NSString* downloadProgressString;
@property(nonatomic,readonly) int folderLevel;
@property(nonatomic,readonly) NSString* parentFolderName;