VLCNetworkServerBrowserFTP.m 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*****************************************************************************
  2. * VLCNetworkServerBrowserFTP.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Tobias Conradi <videolan # tobias-conradi.de>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCNetworkServerBrowserFTP.h"
  13. #import "WhiteRaccoon.h"
  14. @interface VLCNetworkServerBrowserFTP () <WRRequestDelegate>
  15. @property (nonatomic) NSURL *url;
  16. @property (nonatomic) WRRequestListDirectory *FTPListDirRequest;
  17. @end
  18. @implementation VLCNetworkServerBrowserFTP
  19. @synthesize delegate = _delegate, items = _items;
  20. #pragma mark - Protocol conformance
  21. - (NSString *)title {
  22. if ([_url.path isEqualToString:@"/"])
  23. return _url.host;
  24. else
  25. return [_url.path lastPathComponent];
  26. }
  27. - (void)update {
  28. if (_FTPListDirRequest)
  29. return;
  30. _FTPListDirRequest = [[WRRequestListDirectory alloc] init];
  31. _FTPListDirRequest.delegate = self;
  32. _FTPListDirRequest.hostname = _url.host;
  33. _FTPListDirRequest.username = _url.user;
  34. _FTPListDirRequest.password = _url.password;
  35. _FTPListDirRequest.path = _url.path;
  36. _FTPListDirRequest.passive = YES;
  37. [_FTPListDirRequest start];
  38. }
  39. #pragma mark -
  40. - (instancetype)initWithLogin:(VLCNetworkServerLoginInformation *)login
  41. {
  42. return [self initWithFTPServer:login.address
  43. userName:login.username
  44. andPassword:login.password
  45. atPath:@"/"];
  46. }
  47. - (instancetype)initWithFTPServer:(NSString *)serverAddress userName:(NSString *)username andPassword:(NSString *)password atPath:(NSString *)path
  48. {
  49. NSURLComponents *components = [[NSURLComponents alloc] init];
  50. components.scheme = @"ftp";
  51. components.host = serverAddress;
  52. components.user = username.length ? username : @"anonymous";
  53. components.password = password.length ? password : nil;
  54. components.path = path;
  55. return [self initWithURL:components.URL];
  56. }
  57. - (instancetype)initWithURL:(NSURL *)url
  58. {
  59. self = [super init];
  60. if (self) {
  61. _url = url;
  62. }
  63. return self;
  64. }
  65. - (VLCMediaList *)mediaList
  66. {
  67. VLCMediaList *mediaList = [[VLCMediaList alloc] init];
  68. @synchronized(_items) {
  69. NSUInteger count = _items.count;
  70. for (NSInteger i = count - 1; i >= 0; i--) {
  71. VLCMedia *media = [_items[i] media];
  72. if (media)
  73. [mediaList addMedia:media];
  74. }
  75. }
  76. return mediaList;
  77. }
  78. #pragma mark - white raccoon delegation
  79. - (void)requestCompleted:(WRRequest *)request
  80. {
  81. if (request == _FTPListDirRequest) {
  82. NSMutableArray *filteredList = [[NSMutableArray alloc] init];
  83. NSArray *rawList = [(WRRequestListDirectory*)request filesInfo];
  84. NSUInteger count = rawList.count;
  85. for (NSUInteger x = 0; x < count; x++) {
  86. NSDictionary *dict = rawList[x];
  87. if (![[dict objectForKey:(id)kCFFTPResourceName] hasPrefix:@"."])
  88. [filteredList addObject:[[VLCNetworkServerBrowserItemFTP alloc] initWithDictionary:dict baseURL:self.url]];
  89. }
  90. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  91. @synchronized(_items) {
  92. _items = [NSArray arrayWithArray:filteredList];
  93. }
  94. [self.delegate networkServerBrowserDidUpdate:self];
  95. }];
  96. } else
  97. APLog(@"unknown request %@ completed", request);
  98. }
  99. - (void)requestFailed:(WRRequest *)request
  100. {
  101. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  102. NSDictionary *userInfo = nil;
  103. if (request.error.message) {
  104. userInfo = @{ NSLocalizedDescriptionKey : request.error.message };
  105. }
  106. NSError *error = [NSError errorWithDomain:@"org.videolan.whiteracoon" code:request.error.errorCode userInfo:userInfo];
  107. [self.delegate networkServerBrowser:self requestDidFailWithError:error];
  108. APLog(@"request %@ failed with error %i", request, request.error.errorCode);
  109. }];
  110. }
  111. @end
  112. @implementation VLCNetworkServerBrowserItemFTP
  113. @synthesize name = _name, container = _container, fileSizeBytes = _fileSizeBytes, URL = _URL;
  114. - (instancetype)initWithDictionary:(NSDictionary *)dict baseURL:(NSURL *)baseURL
  115. {
  116. self = [super init];
  117. if (self) {
  118. NSString *rawFileName = [dict objectForKey:(id)kCFFTPResourceName];
  119. NSData *flippedData = [rawFileName dataUsingEncoding:[[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingFTPTextEncoding] intValue] allowLossyConversion:YES];
  120. if (flippedData != nil) {
  121. _name = [[NSString alloc] initWithData:flippedData encoding:NSUTF8StringEncoding];
  122. if (_name == nil) {
  123. /* this can happen if our string conversation failed */
  124. _name = rawFileName;
  125. }
  126. _container = [dict[(id)kCFFTPResourceType] intValue] == 4;
  127. _fileSizeBytes = dict[(id)kCFFTPResourceSize];
  128. _URL = [baseURL URLByAppendingPathComponent:_name];
  129. }
  130. }
  131. return self;
  132. }
  133. - (id<VLCNetworkServerBrowser>)containerBrowser {
  134. return [[VLCNetworkServerBrowserFTP alloc] initWithURL:self.URL];
  135. }
  136. - (VLCMedia *)media
  137. {
  138. if (_URL)
  139. return [VLCMedia mediaWithURL:_URL];
  140. return nil;
  141. }
  142. @end