VLCLocalServerFolderListViewController.m 10.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//
//  VLCLocalServerFolderListViewController.m
//  VLC for iOS
//
//  Created by Felix Paul Kühne on 10.08.13.
//  Copyright (c) 2013 VideoLAN. All rights reserved.
//
//  Refer to the COPYING file of the official project for license.
//

#import "VLCLocalServerFolderListViewController.h"
#import "MediaServerBasicObjectParser.h"
#import "MediaServer1ItemObject.h"
#import "MediaServer1ContainerObject.h"
#import "MediaServer1Device.h"
#import "VLCLocalNetworkListCell.h"
17 18 19
#import "VLCAppDelegate.h"
#import "VLCPlaylistViewController.h"
#import "UINavigationController+Theme.h"
20
#import "WhiteRaccoon.h"
21

22 23 24
#define kVLCUPNPFileServer 0
#define kVLCFTPServer 1

25
@interface VLCLocalServerFolderListViewController () <UITableViewDataSource, UITableViewDelegate, WRRequestDelegate>
26
{
27
    /* UI */
28 29
    UIBarButtonItem *_backButton;

30
    /* generic data storage */
31
    NSString *_listTitle;
32
    NSMutableArray *_objectList;
33 34
    NSUInteger _serverType;

35
    /* UPNP specifics */
36 37
    MediaServer1Device *_UPNPdevice;
    NSString *_UPNProotID;
38 39 40 41 42 43 44

    /* FTP specifics */
    NSString *_ftpServerAddress;
    NSString *_ftpServerUserName;
    NSString *_ftpServerPassword;
    NSString *_ftpServerPath;
    WRRequestListDirectory *_listDirRequest;
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
}

@end

@implementation VLCLocalServerFolderListViewController

- (void)loadView
{
    _tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
    _tableView.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    self.view = _tableView;
}

60
- (id)initWithUPNPDevice:(MediaServer1Device*)device header:(NSString*)header andRootID:(NSString*)rootID
61 62 63 64
{
    self = [super init];

    if (self) {
65 66 67 68
        _UPNPdevice = device;
        _listTitle = header;
        _UPNProotID = rootID;
        _serverType = kVLCUPNPFileServer;
69 70 71 72 73 74 75 76
    }

    return self;
}

- (id)initWithFTPServer:(NSString *)serverAddress userName:(NSString *)username andPassword:(NSString *)password atPath:(NSString *)path
{
    self = [super init];
77

78 79 80 81 82 83
    if (self) {
        _ftpServerAddress = serverAddress;
        _ftpServerUserName = username;
        _ftpServerPassword = password;
        _ftpServerPath = path;
        _serverType = kVLCFTPServer;
84 85 86 87 88 89 90 91 92
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

93 94
    _objectList = [[NSMutableArray alloc] init];

95 96 97 98 99
    if (_serverType == kVLCUPNPFileServer) {
        NSMutableString *outResult = [[NSMutableString alloc] init];
        NSMutableString *outNumberReturned = [[NSMutableString alloc] init];
        NSMutableString *outTotalMatches = [[NSMutableString alloc] init];
        NSMutableString *outUpdateID = [[NSMutableString alloc] init];
100

101
        [[_UPNPdevice contentDirectory] BrowseWithObjectID:_UPNProotID BrowseFlag:@"BrowseDirectChildren" Filter:@"*" StartingIndex:@"0" RequestedCount:@"0" SortCriteria:@"+dc:title" OutResult:outResult OutNumberReturned:outNumberReturned OutTotalMatches:outTotalMatches OutUpdateID:outUpdateID];
102

103 104 105
        NSData *didl = [outResult dataUsingEncoding:NSUTF8StringEncoding];
        MediaServerBasicObjectParser *parser = [[MediaServerBasicObjectParser alloc] initWithMediaObjectArray:_objectList itemsOnly:NO];
        [parser parseFromData:didl];
106 107 108 109 110 111
    } else if (_serverType == kVLCFTPServer) {
        if ([_ftpServerPath isEqualToString:@"/"])
            _listTitle = _ftpServerAddress;
        else
            _listTitle = [_ftpServerPath lastPathComponent];
        [self _listFTPDirectory];
112
    }
113 114 115 116

    self.tableView.separatorColor = [UIColor colorWithWhite:.122 alpha:1.];
    self.view.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];

117
    self.title = _listTitle;
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
        return NO;
    return YES;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _objectList.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"LocalNetworkCellDetail";

    VLCLocalNetworkListCell *cell = (VLCLocalNetworkListCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
        cell = [VLCLocalNetworkListCell cellWithReuseIdentifier:CellIdentifier];

147 148 149 150 151 152 153 154 155 156 157 158
    if (_serverType == kVLCUPNPFileServer) {
        MediaServer1BasicObject *item = _objectList[indexPath.row];
        if (![item isContainer]) {
            MediaServer1ItemObject *mediaItem = _objectList[indexPath.row];
            [cell setSubtitle: [NSString stringWithFormat:@"%0.2f MB", (float)([mediaItem.size intValue] / 1e6)]];
            [cell setIsDirectory:NO];
            [cell setIcon:[UIImage imageNamed:@"blank"]];
        } else {
            [cell setIsDirectory:YES];
            [cell setIcon:[UIImage imageNamed:@"folder"]];
        }
        [cell setTitle:[item title]];
159 160 161 162 163 164 165 166 167 168
    } else if (_serverType == kVLCFTPServer) {
        cell.title = [_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceName];
        if ([[_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceType] intValue] == 4) {
            cell.isDirectory = YES;
            cell.icon = [UIImage imageNamed:@"folder"];
        } else {
            cell.isDirectory = NO;
            cell.icon = [UIImage imageNamed:@"blank"];
            cell.subtitle = [NSString stringWithFormat:@"%0.2f MB", [[_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceType] intValue], (float)([[_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceSize] intValue] / 1e6)];
        }
169
    }
170 171 172 173 174 175

    return cell;
}

#pragma mark - Table view delegate

176 177 178 179 180
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor colorWithWhite:.122 alpha:1.];
}

181 182
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
    if (_serverType == kVLCUPNPFileServer) {
        MediaServer1BasicObject *item = _objectList[indexPath.row];
        if ([item isContainer]) {
            MediaServer1ContainerObject *container = _objectList[indexPath.row];
            VLCLocalServerFolderListViewController *targetViewController = [[VLCLocalServerFolderListViewController alloc] initWithUPNPDevice:_UPNPdevice header:[container title] andRootID:[container objectID]];
            [[self navigationController] pushViewController:targetViewController animated:YES];
        } else {
            MediaServer1ItemObject *item = _objectList[indexPath.row];

            MediaServer1ItemRes *resource = nil;
            NSEnumerator *e = [[item resources] objectEnumerator];
            NSURL *itemURL;
            while((resource = (MediaServer1ItemRes*)[e nextObject])){
                APLog(@"%@ - %d, %@, %d, %d, %d, %@ (%@)", [item title], [resource bitrate], [resource duration], [resource nrAudioChannels], [resource size],  [resource durationInSeconds],  [resource protocolInfo], [item uri]);
                itemURL = [NSURL URLWithString:[item uri]];
            }

            if (itemURL && ([itemURL.scheme isEqualToString:@"http"] || [itemURL.scheme isEqualToString:@"rtsp"] || [itemURL.scheme isEqualToString:@"rtp"] || [itemURL.scheme isEqualToString:@"mms"] || [itemURL.scheme isEqualToString:@"mmsh"])) {
                VLCAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;

                UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:appDelegate.playlistViewController];
                [navController loadTheme];

                appDelegate.revealController.contentViewController = navController;
                [appDelegate.revealController toggleSidebar:NO duration:kGHRevealSidebarDefaultAnimationDuration];

                [appDelegate.playlistViewController performSelector:@selector(openMovieFromURL:) withObject:itemURL afterDelay:kGHRevealSidebarDefaultAnimationDuration];
            }
211
        }
212 213 214 215 216 217 218 219 220 221 222 223 224
    } else if (_serverType == kVLCFTPServer) {
        if ([[_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceType] intValue] == 4) {
            NSString *newPath;
            if ([_ftpServerPath hasSuffix:@"/"])
                newPath = [NSString stringWithFormat:@"%@%@", _ftpServerPath, [_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceName]];
            else
                newPath = [NSString stringWithFormat:@"%@/%@", _ftpServerPath, [_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceName]];

            VLCLocalServerFolderListViewController *targetViewController = [[VLCLocalServerFolderListViewController alloc] initWithFTPServer:_ftpServerAddress userName:_ftpServerUserName andPassword:_ftpServerPassword atPath:newPath];
            [self.navigationController pushViewController:targetViewController animated:YES];
        } else {
            NSLog(@"user would like to fetch %@", [_objectList[indexPath.row] objectForKey:(id)kCFFTPResourceName]);
        }
225 226 227
    }
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
#pragma mark - FTP specifics
- (void)_listFTPDirectory
{
    if (_listDirRequest)
        return;

    _listDirRequest = [[WRRequestListDirectory alloc] init];
    _listDirRequest.delegate = self;
    _listDirRequest.hostname = _ftpServerAddress;
    _listDirRequest.username = _ftpServerUserName;
    _listDirRequest.password = _ftpServerPassword;
    _listDirRequest.path = _ftpServerPath;

    [_listDirRequest start];
}

- (void)requestCompleted:(WRRequest *)request
{
    if (request == _listDirRequest) {
        NSMutableArray *filteredList = [[NSMutableArray alloc] init];
        NSArray *rawList = [(WRRequestListDirectory*)request filesInfo];
        NSUInteger count = rawList.count;

        for (NSUInteger x = 0; x < count; x++) {
            if (![[rawList[x] objectForKey:(id)kCFFTPResourceName] hasPrefix:@"."])
                [filteredList addObject:rawList[x]];
        }

        _objectList = [NSArray arrayWithArray:filteredList];
        [self.tableView reloadData];
    }
}

- (void)requestFailed:(WRRequest *)request
{
    APLog(@"request %@ failed with error %i message '%@'", request, request.error.errorCode, request.error.message);
}

266
@end