VLCOneDriveObject.m 9.24 KB
Newer Older
1 2 3 4
/*****************************************************************************
 * VLCOneDriveObject.h
 * VLC for iOS
 *****************************************************************************
5
 * Copyright (c) 2015-2018 VideoLAN. All rights reserved.
6 7 8
 * $Id$
 *
 * Authors: Felix Paul Kühne <fkuehne # videolan.org>
9
 *          Pierre Sagaspe <pierre.sagaspe # me.com>
10 11 12 13 14
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/

#import "VLCOneDriveObject.h"
15
#import "VLCHTTPFileDownloader.h"
16
#import "NSString+SupportedMedia.h"
17
#import "UIDevice+VLC.h"
18

19
#if TARGET_OS_IOS
20 21 22 23 24 25
@interface VLCOneDriveObject () <VLCHTTPFileDownloader>
{
    VLCHTTPFileDownloader *_fileDownloader;
}

@end
26 27 28 29 30
#else
@interface VLCOneDriveObject ()

@end
#endif
31 32 33 34 35 36 37 38 39 40

@implementation VLCOneDriveObject

#pragma mark properties

- (BOOL)isFolder
{
    return [self.type isEqual:@"folder"] || [self.type isEqual:@"album"];
}

41 42 43 44 45 46 47 48 49 50
- (BOOL)isVideo
{
    return [self.type isEqual:@"video"];
}

- (BOOL)isAudio
{
    return [self.type isEqual:@"audio"];
}

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
- (NSString *)filesPath
{
    return [self.objectId stringByAppendingString:@"/files"];
}

- (BOOL)hasFullFolderTree
{
    BOOL hasFullTree = YES;

    if (self.folders != nil) {
        NSUInteger count = self.folders.count;

        for (NSUInteger x = 0; x < count; x++) {
            VLCOneDriveObject *folder = self.folders[x];
            if (!folder.hasFullFolderTree) {
                hasFullTree = NO;
                break;
            }
        }
    } else
        hasFullTree = NO;

    return hasFullTree;
}

#pragma mark - actions

- (void)loadFolderContent
{
    if (!self.isFolder) {
        APLog(@"%@ is no folder, can't load content", self.objectId);
        return;
    }

    if (self.folders == nil) {
        [self.liveClient getWithPath:self.filesPath
                            delegate:self
                           userState:@"load-folder-content"];
    } else {
        NSUInteger count = self.folders.count;

        for (NSUInteger x = 0; x < count; x++) {
            VLCOneDriveObject *folder = self.folders[x];
            if (!folder.hasFullFolderTree) {
95
                folder.delegate = self.delegate;
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
                [folder loadFolderContent];
                return;
            }
        }

        [self.delegate fullFolderTreeLoaded:self];
    }
}

#pragma mark - live operations

- (void)liveOperationSucceeded:(LiveDownloadOperation *)operation
{
    NSString *userState = operation.userState;

111
    if ([userState isEqualToString:@"load-folder-content"]) {
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
        NSMutableArray *subFolders = [[NSMutableArray alloc] init];
        NSMutableArray *folderFiles = [[NSMutableArray alloc] init];
        NSMutableArray *items = [[NSMutableArray alloc] init];
        NSArray *rawFolderObjects = operation.result[@"data"];
        BOOL hasSubFolders = NO;
        NSUInteger count = rawFolderObjects.count;

        for (NSUInteger x = 0; x < count; x++) {
            NSDictionary *rawObject = rawFolderObjects[x];
            VLCOneDriveObject *oneDriveObject = [[VLCOneDriveObject alloc] init];

            oneDriveObject.parent = self;
            oneDriveObject.objectId = rawObject[@"id"];
            oneDriveObject.name = rawObject[@"name"];
            oneDriveObject.type = rawObject[@"type"];

            oneDriveObject.liveClient = self.liveClient;

            if (oneDriveObject.isFolder) {
                hasSubFolders = YES;
                [subFolders addObject:oneDriveObject];
            } else {
                oneDriveObject.size = rawObject[@"size"];
                oneDriveObject.thumbnailURL = rawObject[@"picture"];
136
                oneDriveObject.downloadPath = rawObject[@"source"];
137 138 139 140

                if (oneDriveObject.isVideo)
                    oneDriveObject.subtitleURL = [self configureSubtitle:oneDriveObject.name folderItems:rawFolderObjects];

141
                oneDriveObject.duration = rawObject[@"duration"];
142 143
                [folderFiles addObject:oneDriveObject];
            }
144 145 146 147 148

            //Display only folders and supported files.
            if (oneDriveObject.isFolder || [oneDriveObject.name isSupportedFormat])
                [items addObject:oneDriveObject];

149 150 151 152 153 154 155 156 157 158 159 160 161
        }

        self.folders = subFolders;
        self.files = folderFiles;
        self.items = items;
        [self.delegate folderContentLoaded:self];
    }
}

- (void)liveOperationFailed:(NSError *)error operation:(LiveDownloadOperation *)operation
{
    NSString *userState = operation.userState;

162
    APLog(@"liveOperationFailed %@ (%@)", userState, error);
163 164 165 166 167

    if ([userState isEqualToString:@"load-folder-content"])
        [self.delegate folderContentLoadingFailed:error sender:self];
}

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 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 211 212 213 214 215 216 217 218
#pragma - subtitle

- (NSString *)configureSubtitle:(NSString *)fileName folderItems:(NSArray *)folderItems
{
    NSString *subtitleURL = nil;
    NSString *subtitlePath = [self _searchSubtitle:fileName folderItems:folderItems];

    if (subtitlePath)
        subtitleURL = [self _getFileSubtitleFromServer:[NSURL URLWithString:subtitlePath]];

    return subtitleURL;
}

- (NSString *)_searchSubtitle:(NSString *)fileName folderItems:(NSArray *)folderItems
{
    NSString *urlTemp = [[fileName lastPathComponent] stringByDeletingPathExtension];
    NSString *itemPath = nil;

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", urlTemp];
    NSArray *results = [folderItems filteredArrayUsingPredicate:predicate];

    for (int cnt = 0; cnt < results.count; cnt++) {
        NSDictionary *dictObject = results[cnt];
        NSString *itemName = dictObject[@"name"];
        if ([itemName isSupportedSubtitleFormat])
            itemPath = dictObject[@"source"];
    }
    return itemPath;
}

- (NSString *)_getFileSubtitleFromServer:(NSURL *)subtitleURL
{
    NSString *FileSubtitlePath = nil;
    NSData *receivedSub = [NSData dataWithContentsOfURL:subtitleURL]; // TODO: fix synchronous load

    if (receivedSub.length < [[UIDevice currentDevice] VLCFreeDiskSpace].longLongValue) {
        NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *directoryPath = searchPaths[0];
        FileSubtitlePath = [directoryPath stringByAppendingPathComponent:[subtitleURL lastPathComponent]];

        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:FileSubtitlePath]) {
            //create local subtitle file
            [fileManager createFileAtPath:FileSubtitlePath contents:nil attributes:nil];
            if (![fileManager fileExistsAtPath:FileSubtitlePath]) {
                APLog(@"file creation failed, no data was saved");
                return nil;
            }
        }
        [receivedSub writeToFile:FileSubtitlePath atomically:YES];
    } else {
219 220 221 222 223 224 225 226 227 228
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"DISK_FULL", nil)
                                                                                 message:[NSString stringWithFormat:NSLocalizedString(@"DISK_FULL_FORMAT", nil), [subtitleURL lastPathComponent], [[UIDevice currentDevice] model]]
                                                                          preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_OK", nil)
                                                           style:UIAlertActionStyleCancel
                                                         handler:nil];

        [alertController addAction:okAction];
        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
229 230 231 232 233
    }

    return FileSubtitlePath;
}

234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
#pragma mark - delegation

- (void)folderContentLoaded:(VLCOneDriveObject *)sender
{
}

- (void)folderContentLoadingFailed:(NSError *)error sender:(VLCOneDriveObject *)sender
{
    if (self.delegate)
        [self.delegate folderContentLoadingFailed:error sender:self];
}

- (void)fullFolderTreeLoaded:(VLCOneDriveObject *)sender
{
    [self loadFolderContent];
}

251 252 253 254
#pragma mark - file downloading

- (void)saveObjectToDocuments
{
255
#if TARGET_OS_IOS
256 257
    _fileDownloader = [[VLCHTTPFileDownloader alloc] init];
    _fileDownloader.delegate = self;
258
    [_fileDownloader downloadFileFromURL:[NSURL URLWithString:self.downloadPath] withFileName:self.name];
259
#endif
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
}

- (void)downloadStarted
{
    if ([self.downloadDelegate respondsToSelector:@selector(downloadStarted:)])
        [self.downloadDelegate downloadStarted:self];
}

- (void)downloadEnded
{
    if ([self.downloadDelegate respondsToSelector:@selector(downloadEnded:)])
        [self.downloadDelegate downloadEnded:self];
}

- (void)downloadFailedWithErrorDescription:(NSString *)description
275
{
276
    APLog(@"download failed (%@)", description);
277 278
}

279
- (void)progressUpdatedTo:(CGFloat)percentage receivedDataSize:(CGFloat)receivedDataSize expectedDownloadSize:(CGFloat)expectedDownloadSize
280
{
281 282 283 284
    if ([self.downloadDelegate respondsToSelector:@selector(progressUpdated:)])
        [self.downloadDelegate progressUpdated:percentage];
    if ([self.downloadDelegate respondsToSelector:@selector(calculateRemainingTime:expectedDownloadSize:)])
        [self.downloadDelegate calculateRemainingTime:receivedDataSize expectedDownloadSize:expectedDownloadSize];
285 286 287
}

@end