Browse Source

update library

marinofaggiana 4 years ago
parent
commit
35bc301751

+ 5 - 11
File Provider Extension/FileProviderExtension.swift

@@ -187,8 +187,6 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         
         let pathComponents = url.pathComponents
         let identifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
-        var downloadRequest: DownloadRequest?
-        var task: URLSessionTask?
         
         if let _ = outstandingSessionTasks[url] {
             completionHandler(nil)
@@ -214,17 +212,13 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, update: true)
         
         NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath,  requestHandler: { (request) in
+                        
+        }, taskHandler: { (task) in
             
-            downloadRequest = request
-            
-        }, progressHandler: { (progress) in
+            self.outstandingSessionTasks[url] = task
+            fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(identifier.rawValue)) { (error) in }
             
-            if task == nil && downloadRequest?.task != nil {
-                task = downloadRequest?.task
-                self.outstandingSessionTasks[url] = task
-                
-                fileProviderData.shared.fileProviderManager.register(task!, forItemWithIdentifier: NSFileProviderItemIdentifier(identifier.rawValue)) { (error) in }
-            }
+        }, progressHandler: { (_) in
             
         }) { (account, etag, date, length, allHeaderFields, error, errorCode, errorDescription) in
             

+ 6 - 1
Share/ShareViewController.m

@@ -272,9 +272,14 @@
         NSString *fileNameForUpload = [[NCUtility shared] createFileName:fileName serverUrl:self.serverUrl account:self.account];
         NSString *fileNameServer = [NSString stringWithFormat:@"%@/%@", self.serverUrl, fileNameForUpload];
         
-        [[NCCommunication shared] uploadWithServerUrlFileName:fileNameServer fileNameLocalPath:fileNameLocal dateCreationFile:nil dateModificationFile:nil customUserAgent:nil addCustomHeaders:nil progressHandler:^(NSProgress * progress) {
+        [[NCCommunication shared] uploadWithServerUrlFileName:fileNameServer fileNameLocalPath:fileNameLocal dateCreationFile:nil dateModificationFile:nil customUserAgent:nil addCustomHeaders:nil taskHandler:^(NSURLSessionTask *task) {
+                        
+        } progressHandler:^(NSProgress *progress) {
+            
             [self.hud progress:progress.fractionCompleted];
+            
         } completionHandler:^(NSString *account, NSString *ocId, NSString *etag, NSDate *date, int64_t size, NSDictionary *allHeaderFields, NSInteger errorCode, NSString *errorDescription) {
+            
             [self.hud hideHud];
             [self.filesName removeObject:fileName];
            

+ 2 - 0
iOSClient/Activity/NCActivity.swift

@@ -382,6 +382,8 @@ extension activityTableViewCell: UICollectionViewDelegate {
             
             NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
                 
+            }, taskHandler: { (_) in
+                
             }, progressHandler: { (_) in
                 
             }) { (account, etag, date, lenght, allHeaderFields, error, errorCode, errorDescription) in

+ 1 - 12
iOSClient/AppDelegate.m

@@ -28,8 +28,6 @@
 #import "NCPushNotificationEncryption.h"
 #import <QuartzCore/QuartzCore.h>
 
-@import Sentry;
-
 @class NCViewerRichdocument;
 
 @interface AppDelegate() <TOPasscodeViewControllerDelegate>
@@ -50,16 +48,7 @@
         NCBrandOptions.sharedInstance.disable_crash_service = false;
     }
     if (![CCUtility getDisableCrashservice] && NCBrandOptions.sharedInstance.disable_crash_service == false) {
-        [SentrySDK startWithOptions: @{
-            @"dsn": @"https://42eaf570ec2646b1a564a4c4bfc8c279@o394108.ingest.sentry.io/5243836",
-            @"debug": @(YES),
-            @"enableAutoSessionTracking": @(YES)
-            /* PRIVACY : https://github.com/getsentry/sentry-cocoa
-             By default, we don’t apply the user identification provided to the SDK via the API. Instead, we use
-             the installation ID generated with the first use of the application. The ID doesn’t contain any
-             private or public data of your users or any public or shared data of their device.
-             */
-        }];
+        
     }
     
     [CCUtility createDirectoryStandard];

+ 1 - 1
iOSClient/CCGlobal.h

@@ -78,7 +78,7 @@
 
 // Database Realm
 #define k_databaseDefault                               @"nextcloud.realm"
-#define k_databaseSchemaVersion                         145
+#define k_databaseSchemaVersion                         149
 
 // Database JSON
 #define k_databaseDefaultJSON                           @"nextcloud.json"

+ 13 - 0
iOSClient/Data/NCDatabase.swift

@@ -283,6 +283,7 @@ class tableLocalFile: Object {
     @objc dynamic var exifDate: NSDate? = nil
     @objc dynamic var exifLatitude = ""
     @objc dynamic var exifLongitude = ""
+    @objc dynamic var exifLensModel: String? = nil
     @objc dynamic var favorite: Bool = false
     @objc dynamic var fileName = ""
     @objc dynamic var ocId = ""
@@ -433,3 +434,15 @@ class tableTrash: Object {
         return "fileId"
     }
 }
+
+class tableVideo: Object {
+    
+    @objc dynamic var account = ""
+    @objc dynamic var ocId = ""
+    @objc dynamic var time: Int64 = 0
+    
+    override static func primaryKey() -> String {
+        return "ocId"
+    }
+}
+

+ 0 - 1
iOSClient/Data/NCElementsJSON.swift

@@ -50,7 +50,6 @@ import Foundation
 
     @objc public let capabilitiesRichdocumentsMimetypes:        Array = ["ocs","data","capabilities","richdocuments","mimetypes"]
 
-    
     @objc public let capabilitiesActivity:                      Array = ["ocs","data","capabilities","activity","apiv2"]
     
     @objc public let capabilitiesNotification:                  Array = ["ocs","data","capabilities","notifications","ocs-endpoints"]

+ 57 - 1
iOSClient/Data/NCManageDatabase.swift

@@ -213,7 +213,8 @@ class NCManageDatabase: NSObject {
         self.clearTable(tableShare.self, account: account)
         self.clearTable(tableTag.self, account: account)
         self.clearTable(tableTrash.self, account: account)
-        
+        self.clearTable(tableVideo.self, account: account)
+
         if removeAccount {
             self.clearTable(tableAccount.self, account: account)
         }
@@ -1536,6 +1537,26 @@ class NCManageDatabase: NSObject {
         }
     }
     
+    @objc func setLocalFile(ocId: String, exifDate: NSDate?, exifLatitude: String, exifLongitude: String, exifLensModel: String?) {
+        
+        let realm = try! Realm()
+
+        do {
+            try realm.safeWrite {
+                if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first {
+                    result.exifDate = exifDate
+                    result.exifLatitude = exifLatitude
+                    result.exifLongitude = exifLongitude
+                    if exifLensModel?.count ?? 0 > 0 {
+                        result.exifLensModel = exifLensModel
+                    }
+                }
+            }
+        } catch let error {
+            NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
+        }
+    }
+    
     @objc func getTableLocalFile(predicate: NSPredicate) -> tableLocalFile? {
         
         let realm = try! Realm()
@@ -2666,6 +2687,41 @@ class NCManageDatabase: NSObject {
         return tableTrash.init(value: result)
     }
     
+    //MARK: -
+    //MARK: Table Video
+    
+    func addVideoTime(account: String, ocId: String, time: CMTime?) {
+        
+        guard let time = time else { return }
+        let realm = try! Realm()
+        
+        do {
+            try realm.safeWrite {
+                let addObject = tableVideo()
+               
+                addObject.account = account
+                addObject.ocId = ocId
+                addObject.time = Int64(CMTimeGetSeconds(time) * 1000)
+              
+                realm.add(addObject, update: .all)
+            }
+        } catch let error {
+            NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
+        }
+    }
+    
+    func getVideoTime(account: String, ocId: String) -> CMTime? {
+        
+        let realm = try! Realm()
+        
+        guard let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", account, ocId).first else {
+            return nil
+        }
+        
+        let time = CMTimeMake(value: result.time, timescale: 1000)
+        return time
+    }
+    
     //MARK: -
 }
 

+ 2 - 0
iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift

@@ -503,6 +503,8 @@ import NCCommunication
 
         NCCommunication.shared.download(serverUrlFileName: preview, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
             
+        }, taskHandler: { (task) in
+            
         }, progressHandler: { (_) in
             
         }) { (account, etag, date, lenght, allHeaderFields, error, errorCode, errorDescription) in

+ 5 - 1
iOSClient/Main/NCDetailViewController.swift

@@ -647,7 +647,9 @@ extension NCDetailViewController: NCViewerImageViewControllerDelegate, NCViewerI
             let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)!
                         
             NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
-                                
+                
+            }, taskHandler: { (task) in
+                
             },  progressHandler: { (progress) in
                                 
                 self.progress(Float(progress.fractionCompleted))
@@ -766,6 +768,8 @@ extension NCDetailViewController: NCViewerImageViewControllerDelegate, NCViewerI
                                 
                 NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
                     
+                }, taskHandler: { (task) in
+                    
                 }, progressHandler: { (progress) in
                                     
                     self.progress(Float(progress.fractionCompleted))

+ 13 - 11
iOSClient/Networking/NCNetworking.swift

@@ -255,6 +255,8 @@ import Queuer
             NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, status: Int(k_metadataStatusDownloading))
             NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadStartFile, userInfo: ["metadata":metadata])
             
+        }, taskHandler: { (_) in
+            
         }, progressHandler: { (progress) in
             
             NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, object: nil, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: k_metadataStatusInDownload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
@@ -375,30 +377,30 @@ import Queuer
         
         let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
         let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
-        var task: URLSessionTask?
+        var uploadTask: URLSessionTask?
         let description = metadata.ocId
         
         NCCommunication.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: metadata.creationDate as Date, dateModificationFile: metadata.date as Date, customUserAgent: nil, addCustomHeaders: nil, requestHandler: { (request) in
             
             self.uploadRequest[fileNameLocalPath] = request
+        
+        }, taskHandler: { (task) in
             
-        }, progressHandler: { (progress) in
+            uploadTask = task
+            NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task.taskIdentifier, status: Int(k_metadataStatusUploading))
+            #if !EXTENSION
+            CCGraphics.createNewImage(from: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, typeFile: metadata.typeFile)
+            #endif
+            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["metadata":metadata])
             
-            if task == nil && self.uploadRequest[fileNameLocalPath]?.task != nil {
-                task = self.uploadRequest[fileNameLocalPath]?.task
-                NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task!.taskIdentifier, status: Int(k_metadataStatusUploading))
-                #if !EXTENSION
-                CCGraphics.createNewImage(from: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, typeFile: metadata.typeFile)
-                #endif
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["metadata":metadata])
-            }
+        }, progressHandler: { (progress) in
             
             NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
             
         }) { (account, ocId, etag, date, size, allHeaderFields, error, errorCode, errorDescription) in
          
             self.uploadRequest[fileNameLocalPath] = nil
-            self.uploadComplete(fileName: metadata.fileName, serverUrl: metadata.serverUrl, ocId: ocId, etag: etag, date: date, size: size, description: description, task: task!, errorCode: errorCode, errorDescription: errorDescription)
+            self.uploadComplete(fileName: metadata.fileName, serverUrl: metadata.serverUrl, ocId: ocId, etag: etag, date: date, size: size, description: description, task: uploadTask!, errorCode: errorCode, errorDescription: errorDescription)
             
             completion(errorCode, errorDescription)
         }

+ 2 - 0
iOSClient/Networking/NCNetworkingE2EE.swift

@@ -271,6 +271,8 @@ import Alamofire
                     
                     NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["metadata":metadata])
                     
+                }, taskHandler: { (_) in
+                    
                 }, progressHandler: { (progress) in
                     
                     NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])

+ 0 - 38
iOSClient/Utility/CCExifGeo.h

@@ -1,38 +0,0 @@
-//
-//  CCExifGeo.h
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 03/02/16.
-//  Copyright (c) 2016 Marino Faggiana. All rights reserved.
-//
-//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-#import <Foundation/Foundation.h>
-#import <CoreLocation/CoreLocation.h>
-#import <ImageIO/ImageIO.h>
-#import <UIKit/UIKit.h>
-
-@class tableMetadata;
-
-@interface CCExifGeo : NSObject
-
-+ (CCExifGeo *)sharedInstance;
-
-- (void)setExifLocalTableEtag:(tableMetadata *)metadata;
-- (void)setGeocoderEtag:(NSString *)ocId exifDate:(NSDate *)exifDate latitude:(NSString*)latitude longitude:(NSString*)longitude;
-
-@end

+ 0 - 171
iOSClient/Utility/CCExifGeo.m

@@ -1,171 +0,0 @@
-//
-//  CCExifGeo.m
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 03/02/16.
-//  Copyright (c) 2016 Marino Faggiana. All rights reserved.
-//
-//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-#import "CCExifGeo.h"
-#import "CCUtility.h"
-#import "NCBridgeSwift.h"
-
-@implementation CCExifGeo
-
-+ (CCExifGeo *)sharedInstance {
-    
-    static CCExifGeo *sharedInstance;
-    
-    @synchronized(self)
-    {
-        if (!sharedInstance) {
-            
-            sharedInstance = [CCExifGeo new];
-        }
-        return sharedInstance;
-    }
-}
-
-- (void)setExifLocalTableEtag:(tableMetadata *)metadata
-{
-    NSString *dateTime;
-    NSString *latitudeRef;
-    NSString *longitudeRef;
-    NSString *stringLatitude = @"0";
-    NSString *stringLongitude = @"0";
-    
-    double latitude = 0;
-    double longitude = 0;
-    
-    NSDate *date = [NSDate new];
-    
-    if (![CCUtility fileProviderStorageExists:metadata.ocId fileNameView:metadata.fileNameView])
-        return;
-
-    NSURL *url = [NSURL fileURLWithPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView]];
-
-    CGImageSourceRef originalSource =  CGImageSourceCreateWithURL((CFURLRef) url, NULL);
-    if (!originalSource)
-        return;
-    
-    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(originalSource, 0, NULL);
-    if (!imageProperties)
-        return;
-    
-    CFDictionaryRef tiff = CFDictionaryGetValue(imageProperties, kCGImagePropertyTIFFDictionary);
-    CFDictionaryRef gps = CFDictionaryGetValue(imageProperties, kCGImagePropertyGPSDictionary);
-
-    if (tiff) {
-        
-        dateTime = (NSString *)CFDictionaryGetValue(tiff, kCGImagePropertyTIFFDateTime);
-        
-        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
-        [dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"];
-    
-        date = [dateFormatter dateFromString:dateTime];
-        if (!date) date = metadata.date;
-    }
-    
-    if (gps) {
-        
-        latitude = [(NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitude) doubleValue];
-        longitude = [(NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitude) doubleValue];
-        
-        latitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitudeRef);
-        longitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitudeRef);
-        
-        // conversion 4 decimal +N -S
-        // The latitude in degrees. Positive values indicate latitudes north of the equator. Negative values indicate latitudes south of the equator.
-        if ([latitudeRef isEqualToString:@"N"])
-            stringLatitude = [NSString stringWithFormat:@"+%.4f", latitude];
-        else
-            stringLatitude = [NSString stringWithFormat:@"-%.4f", latitude];
-        
-        // conversion 4 decimal +E -W
-        // The longitude in degrees. Measurements are relative to the zero meridian, with positive values extending east of the meridian
-        // and negative values extending west of the meridian.
-        if ([longitudeRef isEqualToString:@"E"])
-            stringLongitude = [NSString stringWithFormat:@"+%.4f", longitude];
-        else
-            stringLongitude = [NSString stringWithFormat:@"-%.4f", longitude];
-        
-        if (latitude == 0 || longitude == 0){
-            
-            stringLatitude = @"0";
-            stringLongitude = @"0";
-        }
-    }
-
-    // Wite data EXIF in TableLocalFile
-    /*
-    if (tiff || gps)
-        [[NCManageDatabase sharedInstance] setLocalFileWithOcId:metadata.ocId date:nil exifDate:date exifLatitude:stringLatitude exifLongitude:stringLongitude fileName:nil etag:nil];
-    */
-    CFRelease(originalSource);
-    CFRelease(imageProperties);
-}
-
-- (void)setGeocoderEtag:(NSString *)ocId exifDate:(NSDate *)exifDate latitude:(NSString*)latitude longitude:(NSString*)longitude
-{
-    // If exists already geocoder data in TableGPS exit
-    if ([[NCManageDatabase sharedInstance] getLocationFromGeoLatitude:latitude longitude:longitude])
-        return;
-    
-    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
-    CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]];
-    
-    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
-        
-        //DDLogInfo(@"[LOG] Found placemarks: %@, error: %@", placemarks, error);
-        
-        if (error == nil && [placemarks count] > 0) {
-            
-            CLPlacemark *placemark = [placemarks lastObject];
-            
-            NSString *thoroughfare = @"";
-            NSString *postalCode = @"";
-            NSString *locality = @"";
-            NSString *administrativeArea = @"";
-            NSString *country = @"";
-            
-            if (placemark.thoroughfare) thoroughfare = placemark.thoroughfare;
-            if (placemark.postalCode) postalCode = placemark.postalCode;
-            if (placemark.locality) locality = placemark.locality;
-            if (placemark.administrativeArea) administrativeArea = placemark.administrativeArea;
-            if (placemark.country) country = placemark.country;
-            
-            NSString *location = [NSString stringWithFormat:@"%@ %@ %@ %@ %@", thoroughfare, postalCode, locality, administrativeArea, country];
-            location = [location stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
-            
-            // GPS
-            if ([location length] > 0) {
-                
-                [[NCManageDatabase sharedInstance] addGeocoderLocation:location placemarkAdministrativeArea:placemark.administrativeArea placemarkCountry:placemark.country placemarkLocality:placemark.locality placemarkPostalCode:placemark.postalCode placemarkThoroughfare:placemark.thoroughfare latitude:latitude longitude:longitude];
-                
-                NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:exifDate, ocId, nil];
-                
-                // Notify for CCDetail
-                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"insertGeocoderLocation" object:nil userInfo:dictionary];
-            }
-        } else {
-            //NSLog(@"[LOG] setGeocoderocId : %@", error.debugDescription);
-        }
-    }];
-}
-
-@end

+ 10 - 0
iOSClient/Utility/CCUtility.h

@@ -173,6 +173,12 @@
 + (NSInteger)getLogLevel;
 + (void)setLogLevel:(NSInteger)value;
 
++ (BOOL)getAudioMute;
++ (void)setAudioMute:(BOOL)set;
+
++ (BOOL)getAutomaticDownloadImage;
++ (void)setAutomaticDownloadImage:(BOOL)set;
+
 // ===== Varius =====
 
 + (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL;
@@ -259,6 +265,10 @@
 + (BOOL)isPermissionToRead:(NSInteger) permissionValue;
 + (BOOL)isPermissionToReadCreateUpdate:(NSInteger) permissionValue;
 
+// ===== EXIF =====
+
++ (void)setExif:(tableMetadata *)metadata withCompletionHandler:(void(^)(double latitude, double longitude, NSString *location, NSDate *date, NSString *lensModel))completition;
+
 // ===== Third parts =====
 
 + (NSString *)stringValueForKey:(id)key conDictionary:(NSDictionary *)dictionary;

+ 185 - 0
iOSClient/Utility/CCUtility.m

@@ -25,6 +25,7 @@
 #import "CCGraphics.h"
 #import "NCBridgeSwift.h"
 #import <OpenSSL/OpenSSL.h>
+#import <CoreLocation/CoreLocation.h>
 
 #define INTRO_MessageType       @"MessageType_"
 
@@ -707,6 +708,29 @@
     [UICKeyChainStore setString:valueString forKey:@"logLevel" service:k_serviceShareKeyChain];
 }
 
++ (BOOL)getAudioMute
+{
+    return [[UICKeyChainStore stringForKey:@"audioMute" service:k_serviceShareKeyChain] boolValue];
+}
+
++ (void)setAudioMute:(BOOL)set
+{
+    NSString *sSet = (set) ? @"true" : @"false";
+    [UICKeyChainStore setString:sSet forKey:@"audioMute" service:k_serviceShareKeyChain];
+}
+
++ (BOOL)getAutomaticDownloadImage
+{
+    return [[UICKeyChainStore stringForKey:@"automaticDownloadImage" service:k_serviceShareKeyChain] boolValue];
+}
+
++ (void)setAutomaticDownloadImage:(BOOL)set
+{
+    NSString *sSet = (set) ? @"true" : @"false";
+    [UICKeyChainStore setString:sSet forKey:@"automaticDownloadImage" service:k_serviceShareKeyChain];
+}
+
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Various =====
 #pragma --------------------------------------------------------------------------------------------
@@ -1656,6 +1680,167 @@
     
 }
 
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== EXIF =====
+#pragma --------------------------------------------------------------------------------------------
+
++ (void)setExif:(tableMetadata *)metadata withCompletionHandler:(void(^)(double latitude, double longitude, NSString *location, NSDate *date, NSString *lensModel))completition
+{
+    NSString *dateTime;
+    NSString *latitudeRef;
+    NSString *longitudeRef;
+    NSString *stringLatitude = @"0";
+    NSString *stringLongitude = @"0";
+    __block NSString *location = @"";
+    
+    double latitude = 0;
+    double longitude = 0;
+    
+    NSDate *date = [NSDate new];
+    long fileSize = 0;
+    int pixelY = 0;
+    int pixelX = 0;
+    NSString *lensModel;
+
+    if (![metadata.typeFile isEqualToString:k_metadataTypeFile_image] || ![CCUtility fileProviderStorageExists:metadata.ocId fileNameView:metadata.fileNameView]) {
+        completition(latitude, longitude, location, date, lensModel);
+        return;
+    }
+    
+    NSURL *url = [NSURL fileURLWithPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView]];
+    CGImageSourceRef originalSource =  CGImageSourceCreateWithURL((CFURLRef) url, NULL);
+    if (!originalSource) {
+        completition(latitude, longitude, location, date, lensModel);
+        return;
+    }
+    
+    CFDictionaryRef fileProperties = CGImageSourceCopyProperties(originalSource, nil);
+    if (!fileProperties) {
+        completition(latitude, longitude, location,date, lensModel);
+        return;
+    }
+    
+    // FILES PROPERTIES
+    NSNumber *fileSizeNumber = CFDictionaryGetValue(fileProperties, kCGImagePropertyFileSize);
+    fileSize = [fileSizeNumber longValue];
+    
+    
+    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(originalSource, 0, NULL);
+    if (!imageProperties) {
+        completition(latitude, longitude, location,date, lensModel);
+        return;
+    }
+
+    CFDictionaryRef tiff = CFDictionaryGetValue(imageProperties, kCGImagePropertyTIFFDictionary);
+    CFDictionaryRef gps = CFDictionaryGetValue(imageProperties, kCGImagePropertyGPSDictionary);
+    CFDictionaryRef exif = CFDictionaryGetValue(imageProperties, kCGImagePropertyExifDictionary);
+    
+    if (exif) {
+        
+        NSString *sPixelX = (NSString *)CFDictionaryGetValue(exif, kCGImagePropertyExifPixelXDimension);
+        pixelX = [sPixelX intValue];
+        NSString *sPixelY = (NSString *)CFDictionaryGetValue(exif, kCGImagePropertyExifPixelYDimension);
+        pixelY = [sPixelY intValue];
+        lensModel = (NSString *)CFDictionaryGetValue(exif, kCGImagePropertyExifLensModel);
+    }
+ 
+    if (tiff) {
+        
+        dateTime = (NSString *)CFDictionaryGetValue(tiff, kCGImagePropertyTIFFDateTime);
+        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+        [dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"];
+        date = [dateFormatter dateFromString:dateTime];
+        if (!date) date = metadata.date;
+    }
+    
+    if (gps) {
+        
+        latitude = [(NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitude) doubleValue];
+        longitude = [(NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitude) doubleValue];
+        
+        latitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitudeRef);
+        longitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitudeRef);
+        
+        // conversion 4 decimal +N -S
+        // The latitude in degrees. Positive values indicate latitudes north of the equator. Negative values indicate latitudes south of the equator.
+        if ([latitudeRef isEqualToString:@"N"]) {
+            stringLatitude = [NSString stringWithFormat:@"+%.4f", latitude];
+        } else {
+            stringLatitude = [NSString stringWithFormat:@"-%.4f", latitude];
+        }
+        
+        // conversion 4 decimal +E -W
+        // The longitude in degrees. Measurements are relative to the zero meridian, with positive values extending east of the meridian
+        // and negative values extending west of the meridian.
+        if ([longitudeRef isEqualToString:@"E"]) {
+            stringLongitude = [NSString stringWithFormat:@"+%.4f", longitude];
+        } else {
+            stringLongitude = [NSString stringWithFormat:@"-%.4f", longitude];
+        }
+        
+        if (latitude == 0 || longitude == 0) {
+            
+            stringLatitude = @"0";
+            stringLongitude = @"0";
+        }
+    }
+
+    // Wite data EXIF in DB
+    if (tiff || gps) {
+        [[NCManageDatabase sharedInstance] setLocalFileWithOcId:metadata.ocId exifDate:date exifLatitude:stringLatitude exifLongitude:stringLongitude exifLensModel:lensModel];
+        if ([stringLatitude doubleValue] != 0 || [stringLongitude doubleValue] != 0) {
+            
+            // If exists already geocoder data in TableGPS exit
+            location = [[NCManageDatabase sharedInstance] getLocationFromGeoLatitude:stringLatitude longitude:stringLongitude];
+            if (location != nil) {
+                completition(latitude, longitude, location, date, lensModel);
+                return;
+            }
+            
+            CLGeocoder *geocoder = [[CLGeocoder alloc] init];
+            CLLocation *llocation = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
+            
+            [geocoder reverseGeocodeLocation:llocation completionHandler:^(NSArray *placemarks, NSError *error) {
+                        
+                if (error == nil && [placemarks count] > 0) {
+                    
+                    CLPlacemark *placemark = [placemarks lastObject];
+                    
+                    NSString *thoroughfare = @"";
+                    NSString *postalCode = @"";
+                    NSString *locality = @"";
+                    NSString *administrativeArea = @"";
+                    NSString *country = @"";
+                    
+                    if (placemark.thoroughfare) thoroughfare = placemark.thoroughfare;
+                    if (placemark.postalCode) postalCode = placemark.postalCode;
+                    if (placemark.locality) locality = placemark.locality;
+                    if (placemark.administrativeArea) administrativeArea = placemark.administrativeArea;
+                    if (placemark.country) country = placemark.country;
+                    
+                    location = [NSString stringWithFormat:@"%@ %@ %@ %@ %@", thoroughfare, postalCode, locality, administrativeArea, country];
+                    location = [location stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+                    
+                    // GPS
+                    if ([location length] > 0) {
+                        
+                        [[NCManageDatabase sharedInstance] addGeocoderLocation:location placemarkAdministrativeArea:placemark.administrativeArea placemarkCountry:placemark.country placemarkLocality:placemark.locality placemarkPostalCode:placemark.postalCode placemarkThoroughfare:placemark.thoroughfare latitude:stringLatitude longitude:stringLongitude];
+                    }
+                    
+                    completition(latitude, longitude, location, date, lensModel);
+                }
+            }];
+        } else {
+            completition(latitude, longitude, location, date, lensModel);
+        }
+    } else {
+        completition(latitude, longitude, location, date, lensModel);
+    }
+       
+    CFRelease(originalSource);
+    CFRelease(imageProperties);
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Third parts =====
 #pragma --------------------------------------------------------------------------------------------

+ 1 - 1
iOSClient/Utility/NCUtility.swift

@@ -308,7 +308,7 @@ class NCUtility: NSObject {
     
         guard let view = view else { return }
         
-        activityIndicator.color = NCBrandColor.sharedInstance.brandElement
+        activityIndicator.color = .gray
         activityIndicator.hidesWhenStopped = true
             
         view.addSubview(activityIndicator)

+ 122 - 0
iOSClient/Utility/UIImage+Extensions.swift

@@ -0,0 +1,122 @@
+//
+//  UIColor+fixedOrientation.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 27/11/2019.
+//  Copyright © 2019 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+import Accelerate
+
+extension UIImage {
+    
+    func resizeImageUsingVImage(size:CGSize) -> UIImage? {
+        
+        let cgImage = self.cgImage!
+        var format = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: nil, bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue), version: 0, decode: nil, renderingIntent: CGColorRenderingIntent.defaultIntent)
+        var sourceBuffer = vImage_Buffer()
+        defer {
+            free(sourceBuffer.data)
+        }
+        var error = vImageBuffer_InitWithCGImage(&sourceBuffer, &format, nil, cgImage, numericCast(kvImageNoFlags))
+        guard error == kvImageNoError else { return nil }
+        // create a destination buffer
+        let destWidth = Int(size.width)
+        let destHeight = Int(size.height)
+        let bytesPerPixel = self.cgImage!.bitsPerPixel/8
+        let destBytesPerRow = destWidth * bytesPerPixel
+        let destData = UnsafeMutablePointer<UInt8>.allocate(capacity: destHeight * destBytesPerRow)
+        defer {
+            destData.deallocate()
+        }
+        var destBuffer = vImage_Buffer(data: destData, height: vImagePixelCount(destHeight), width: vImagePixelCount(destWidth), rowBytes: destBytesPerRow)
+        // scale the image
+        error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, nil, numericCast(kvImageHighQualityResampling))
+        guard error == kvImageNoError else { return nil }
+        // create a CGImage from vImage_Buffer
+        var destCGImage = vImageCreateCGImageFromBuffer(&destBuffer, &format, nil, nil, numericCast(kvImageNoFlags), &error)?.takeRetainedValue()
+        guard error == kvImageNoError else { return nil }
+        // create a UIImage
+        let resizedImage = destCGImage.flatMap { UIImage(cgImage: $0, scale: 0.0, orientation: self.imageOrientation) }
+        destCGImage = nil
+        return resizedImage
+    }
+    
+    func fixedOrientation() -> UIImage? {
+        
+        guard imageOrientation != UIImage.Orientation.up else {
+            // This is default orientation, don't need to do anything
+            return self.copy() as? UIImage
+        }
+        
+        guard let cgImage = self.cgImage else {
+            // CGImage is not available
+            return nil
+        }
+        
+        guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
+            return nil // Not able to create CGContext
+        }
+        
+        var transform: CGAffineTransform = CGAffineTransform.identity
+        
+        switch imageOrientation {
+        case .down, .downMirrored:
+            transform = transform.translatedBy(x: size.width, y: size.height)
+            transform = transform.rotated(by: CGFloat.pi)
+        case .left, .leftMirrored:
+            transform = transform.translatedBy(x: size.width, y: 0)
+            transform = transform.rotated(by: CGFloat.pi / 2.0)
+        case .right, .rightMirrored:
+            transform = transform.translatedBy(x: 0, y: size.height)
+            transform = transform.rotated(by: CGFloat.pi / -2.0)
+        case .up, .upMirrored:
+            break
+        @unknown default:
+            break
+        }
+        
+        // Flip image one more time if needed to, this is to prevent flipped image
+        switch imageOrientation {
+        case .upMirrored, .downMirrored:
+            transform = transform.translatedBy(x: size.width, y: 0)
+            transform = transform.scaledBy(x: -1, y: 1)
+        case .leftMirrored, .rightMirrored:
+            transform = transform.translatedBy(x: size.height, y: 0)
+            transform = transform.scaledBy(x: -1, y: 1)
+        case .up, .down, .left, .right:
+            break
+        @unknown default:
+            break
+        }
+        
+        ctx.concatenate(transform)
+        
+        switch imageOrientation {
+        case .left, .leftMirrored, .right, .rightMirrored:
+            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
+        default:
+            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
+            break
+        }
+        
+        guard let newCGImage = ctx.makeImage() else { return nil }
+        return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
+    }
+}

+ 2 - 0
iOSClient/Viewer/NCViewerRichdocument.swift

@@ -134,6 +134,8 @@ class NCViewerRichdocument: WKWebView, WKNavigationDelegate, WKScriptMessageHand
                         
                         NCCommunication.shared.download(serverUrlFileName: url, fileNameLocalPath: fileNameLocalPath, requestHandler: { (_) in
                             
+                        }, taskHandler: { (task) in
+                            
                         }, progressHandler: { (_) in
                             
                         }, completionHandler: { (account, etag, date, lenght, allHeaderFields, error, errorCode, errorDescription) in