public override Task OnSuspendingAsync(object s, SuspendingEventArgs e, bool prelaunchActivated) { // Log suspension. LifecycleLog.AppSuspending(); return(base.OnSuspendingAsync(s, e, prelaunchActivated)); }
public App() { InitializeComponent(); SplashFactory = (e) => new Views.Splash(e); #if DEBUG DebugSettings.EnableFrameRateCounter = true; #endif #region App Settings // some settings must be set in app.constructor var settings = SettingsService.Instance; RequestedTheme = settings.AppTheme; CacheMaxDuration = settings.CacheMaxDuration; ShowShellBackButton = settings.UseShellBackButton; #endregion // Initialize logger. informationListener = new StorageFileEventListener("info"); verboseListener = new StorageFileEventListener("verbose"); // Enable events for loggers. informationListener.EnableEvents(EventLog.Log, EventLevel.Informational); verboseListener.EnableEvents(EventLog.Log, EventLevel.LogAlways); // Clear FutureAccessList as it has a max limit of 1000. ClearFutureAccessList(); // Log startup. LifecycleLog.AppStarting(); }
public static async Task UpdateMediaMetaDataAsync(this MediaMetaDatabaseContext context, MediaMetadata metaToSave) { try { // Time and log updating and saving. using (new DisposableLogger(DatabaseLog.UpdateSingleBegin, DatabaseLog.UpdateSingleEnd)) { // Find MediaMetaJson in database list. var metaJson = context.MediaMetaJsons.Include(m => m.Labels).SingleOrDefault(mj => mj.Labels.ListEquals(metaToSave.Labels)); if (metaJson != null) { var newMetaJson = new MediaMetaJson(metaToSave); metaJson.Json = newMetaJson.Json; await context.SaveChangesAsync(); } } } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } }
public override Task OnPrelaunchAsync(IActivatedEventArgs args, out bool runOnStartAsync) { // Log prelaunch. LifecycleLog.AppPrelaunch(); runOnStartAsync = true; return(Task.CompletedTask); }
private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args) { await NavigationService.Dispatcher.DispatchAsync(() => { // Log reason. LifecycleLog.ExtensionRevoked(args.Reason); ClearExtendedExecution(); }, 0, CoreDispatcherPriority.Normal); }
/// <summary> /// This is the go-to method to handle the authorization and sign-in OAuth flow. /// It tries to fetch the google auth token from cache, and if it can't it will try to /// fetch it using a refresh token, if that's not possible it will prompt the user to /// authorize the application resulting in a google auth token. /// It will then use this google auth token to try to sign into firebase, and if that /// doesn't work the first time it will retry a second time after having the using re-authorize /// the application. (It does this since the refresh token could have been revoked.) /// </summary> /// <returns><c>true</c> if sign in was successful, <c>false</c> otherwise.</returns> public async Task <bool> SignInPromptUserIfNecessary() { try { string googleToken; using (new DisposableLogger(() => AuthLog.GetAccessTokenBegin("Google"), (sw) => AuthLog.GetAccessTokenEnd(sw, "Google", !string.IsNullOrEmpty(GoogleClient.accessToken)))) { // Try to fetch google token without prompting the user (authorizing). if (await GoogleClient.Client.GetAccessTokenWithoutAuthentication()) { googleToken = GoogleClient.accessToken; } else // Prompt the user to authorize the application. { googleToken = await AuthModal.AuthorizeAndGetGoogleAccessTokenAsync(); } } var firebaseSignInSuccess = false; using (new DisposableLogger(() => AuthLog.GetAccessTokenBegin("Firebase"), (sw) => AuthLog.GetAccessTokenEnd(sw, "Firebase", firebaseSignInSuccess))) { // Try to sign into firebase with the googleToken. firebaseSignInSuccess = await SignInWithFirebaseAsync(googleToken); } if (!firebaseSignInSuccess) { // Could not log into firebase. Could be caused by a refresh token revocation, try re-authenticating with Google. googleToken = await AuthModal.AuthorizeAndGetGoogleAccessTokenAsync(); using (new DisposableLogger(() => AuthLog.GetAccessTokenBegin("Firebase"), (sw) => AuthLog.GetAccessTokenEnd(sw, "Firebase", firebaseSignInSuccess))) { // Retry firebase login. firebaseSignInSuccess = await SignInWithFirebaseAsync(googleToken); // Return result. return(firebaseSignInSuccess); } } return(firebaseSignInSuccess); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); return(false); } }
public static async Task SaveAllMetadatasAsync(this MediaMetaDatabaseContext context, ICollection <MediaMetadata> metas) { // Time and log serialization. using (new DisposableLogger(DatabaseLog.SerializationBegin, (sw) => DatabaseLog.SerializationEnd(sw, metas.Count))) { var fullList = await context.MediaMetaJsons.Include(m => m.Labels).ToListAsync(); foreach (var meta in metas) { // If any MediaMetaJson has a set of labels that are equal to the ones of meta, then update it. var toUpdate = fullList.FirstOrDefault(mmj => { return(mmj.Labels.ListEquals(meta.Labels)); }); // If there is an existing item to update. if (toUpdate != null) { var metaJson = await MediaMetaJson.FromMediaMetaAsync(meta); toUpdate.Json = metaJson.Json; } else // If a new item needs to be added. { meta.DateAdded = DateTime.Now; var metaJson = await MediaMetaJson.FromMediaMetaAsync(meta); context.MediaMetaJsons.Add(metaJson); } } } try { // Time and log saving of MediaMetaJsons. using (new DisposableLogger(DatabaseLog.SaveBegin, (sw) => DatabaseLog.SaveEnd(sw, metas.Count))) { await context.SaveChangesAsync(); } } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } }
private static async Task <string> ParseInternetShortcut(StorageFile file) { try { using (var stream = await file.OpenStreamForReadAsync()) { var lines = ReadLines(stream, Encoding.UTF8); string line = lines.Skip(1).Take(1).First(); string url = line.Replace("URL=", ""); url = url.Replace("\"", ""); url = url.Replace("BASE", ""); return(url); } } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); return(string.Empty); } }
public async Task <bool> SignInWithFirebaseAsync(string googleAccessToken) { try { var authProvider = new FirebaseAuthProvider(new FirebaseConfig(ApiKey)); FirebaseAuthLink = await authProvider.SignInWithOAuthAsync(FirebaseAuthType.Google, googleAccessToken); accessToken = FirebaseAuthLink.FirebaseToken; FirebaseAuthLink.FirebaseAuthRefreshed += FirebaseAuthLink_FirebaseAuthRefreshed; return(true); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); return(false); } }
protected override INavigationService CreateNavigationService(Frame frame) { var navService = base.CreateNavigationService(frame); navService.Frame.ContentTransitions?.Clear(); navService.Frame.ContentTransitions?.Add(new NavigationThemeTransition { DefaultNavigationTransitionInfo = new ContinuumNavigationTransitionInfo() }); frame.NavigationFailed += (obj, e) => { // Log NavigationException. LifecycleLog.NavigationException(e); // Set handled to true so the application doesn't crash. e.Handled = true; }; navService.FrameFacade.BackRequested += async(sender, backArgs) => { // Handle event so this is the only place handling it. backArgs.Handled = true; // Perform navigation on main thread. await navService.Dispatcher.DispatchAsync(() => { try { // Go back when on main thread. navService.FrameFacade.GoBack(); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } }, 0, CoreDispatcherPriority.Normal); }; return(navService); }
public async Task EvaluateImagesOnline(IProgress <int> progress, CancellationToken cancellationToken) { // Sign into firebase. if (await FirebaseClient.Client.SignInPromptUserIfNecessary()) { // Find all media datas without annotation data. var mediaDatasWithoutAnnotationData = MediaDatas.Where(data => data.Meta.AnnotationData == null); var evaluated = 0; using (new DisposableLogger(GalleryLog.EvaluateOnlineBegin, (sw) => GalleryLog.EvaluateOnlineEnd(sw, evaluated))) { IsEvaluating = true; await mediaDatasWithoutAnnotationData.ForEachAsyncConcurrent(async media => { try { // Evaluate media thumbnail online. await media.EvaluateOnlineAsync(FirebaseClient.accessToken); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } finally { // Update and then report progress. evaluated++; progress.Report(evaluated); } }, cancellationToken, 5); IsEvaluating = false; } // Save online results to database. await DatabaseUtils.SaveAllMetadatasAsync(MediaDatas); } }
public static async Task SaveAllMetadatasAsync(ICollection <MediaData> mediaDatas) { using (var context = new MediaMetaDatabaseContext()) { var metaDatas = new List <MediaMetadata>(); foreach (var data in mediaDatas) { metaDatas.Add(data.Meta); } try { await context.SaveAllMetadatasAsync(metaDatas); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } // Update static list. App.MediaDatas = new List <MediaData>(mediaDatas); } }
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args) { // Log OnStart. LifecycleLog.AppOnStart(startKind, args); // CoreApplication.EnablePrelaunch was introduced in Windows 10 version 1607 var canEnablePrelaunch = Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch"); if (startKind == StartKind.Activate) { if (args.Kind == ActivationKind.Protocol) { // Opens the URI for "navigation" (handling) on the GalleryPage. TODO: Open Auth completed page here. await NavigationService.NavigateAsync(typeof(Views.GalleryPage), SettingsService.Instance.FolderPath); Window.Current.Activate(); } } if (startKind == StartKind.Launch) { // Enable prelaunch. if (canEnablePrelaunch) { TryEnablePrelaunch(); } // End the Extended Execution Session. ClearExtendedExecution(); using (session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.Unspecified, Description = "Loading Memes from database" }) { // Register Revoked listener. session.Revoked += SessionRevoked; var accessStatus = BackgroundExecutionManager.GetAccessStatus(); if (accessStatus != BackgroundAccessStatus.AlwaysAllowed) { // Request background access. var accessGranted = await BackgroundExecutionManager.RequestAccessKindAsync(BackgroundAccessRequestKind.AlwaysAllowed, "To allow faster launch performance"); } // Request extension. This is done so that if the application can finish loading data // from database when prelaunched or minimized (suspended prematurely). var result = await session.RequestExtensionAsync(); LifecycleLog.ExtensionRequestResult(result); if (result == ExtendedExecutionResult.Denied) { session.Dispose(); // TODO: Notify user of extension result denied. } // Set up database. using (new DisposableLogger(DatabaseLog.LoadBegin, DatabaseLog.LoadEnd)) { if (!(args.PreviousExecutionState == ApplicationExecutionState.Suspended && MediaDatas.Count > 0)) { await SetUpAndLoadFromDatabase(); } } // If MediaDatas have been loaded from database then open GalleryPage using those. if (MediaDatas.Count > 0) { await NavigationService.NavigateAsync(typeof(Views.GalleryPage), nameof(MediaDatas)); return; } // If no folder path has been set, have the user select one. if (string.IsNullOrEmpty(SettingsService.Instance.FolderPath)) { await NavigationService.NavigateAsync(typeof(Views.FolderSelectPage)); } else { await NavigationService.NavigateAsync(typeof(Views.GalleryPage)); } } } }
public async void SearchForHigherResolutionOnlineAsync() { // Don't scan for videos. if (MediaData is VideoData) { return; } var onlineMedias = new Dictionary <Uri, (Size, long)>(); // Get file size and dimensions of every fully matched image. foreach (var webImage in FullyMatchedImages) { // Parse URL. if (Uri.TryCreate(webImage.Url, UriKind.Absolute, out var uri)) { // Check to make sure this URL points to a file and not a webpage. if (Path.HasExtension(uri.AbsoluteUri)) { // Get MIME type of online file. var mimeType = MimeTypeMap.GetMimeType(Path.GetExtension(uri.AbsoluteUri)); // Check if MIME type of online file is supported. if (FileTypes.IsSupportedMIME(mimeType)) { try { // Get dimensions of online image. var dimensions = await ImageUtilities.GetWebDimensionsAsync(uri); // If dimensions is empty, continue. if (dimensions.IsEmpty) { continue; } // Get file size of online image. var contentLength = await OnlineUtil.GetContentSizeAsync(uri); // Add to dictionary. onlineMedias.Add(uri, (dimensions, contentLength)); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } } } } } // If these are null then no comparisons can be made. if (MediaData?.Meta == null) { return; } if (MediaData?.BasicProperties == null) { return; } // Check if any of the fully matched images are higher resolution or larger than local file. var largerMedia = new KeyValuePair <Uri, (Size, long)>(); foreach (var urlAndData in onlineMedias) { var url = urlAndData.Key; var(dimensions, contentLength) = urlAndData.Value; // If online media is larger in file size than local media. if (contentLength > (long)MediaData.BasicProperties.Size) { // If size of this online media is larger than the currently largest media. if (Math.Max(largerMedia.Value.Item2, contentLength) == contentLength) { largerMedia = urlAndData; // Update largerMedia. } } else if (dimensions.Height > MediaData.Meta.Height && // If online media is larger in both width and height dimensions.Width > MediaData.Meta.Width) // than the local media. { // If dimensions of this online media is larger than the currently largest media. if (Math.Max(largerMedia.Value.Item1.Height, dimensions.Height) == dimensions.Height && Math.Max(largerMedia.Value.Item1.Width, dimensions.Width) == dimensions.Width) { largerMedia = urlAndData; // Update largerMedia. } } } // If no larger media has been found, return. if (largerMedia.Key == null) { return; } // Set property. LargerMedia = largerMedia.Key; }
private void App_UnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e) { e.Handled = true; LifecycleLog.Exception(e.Exception); }
private async Task ProcessFileChange(StorageLibraryChange change) { // Temp variable used for instantiating StorageFiles for sorting if needed later //StorageFile newFile = null; var extension = Path.GetExtension(change.Path); switch (change.ChangeType) { // New File in the Library case StorageLibraryChangeType.Created: case StorageLibraryChangeType.MovedIntoLibrary: if (FileTypes.Extensions.Contains(extension, StringComparer.InvariantCultureIgnoreCase)) { try { // Don't add file to gallery if it already exists. if (MediaDatas.Any(data => data.MediaFile.Path == change.Path)) { return; } var mediaFile = (StorageFile)(await change.GetStorageItemAsync()); if (mediaFile == null) { return; } await AddFileAsync(ImageSize, mediaFile); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } } break; // Renamed file case StorageLibraryChangeType.MovedOrRenamed: if (FileTypes.Extensions.Contains(extension, StringComparer.InvariantCultureIgnoreCase)) { try { var mediaData = GetMediaDataFromPath(change.PreviousPath, MediaDatas); var newName = Path.GetFileName(change.Path); // If no MediaData could be found in Gallery for this renamed item AND there is an entry for it in App.MediaDatas (lostMediaData) // that probably means it has been renamed while the application was off, so update its path and add it to the gallery. var lostMediaFile = GetMediaFileFromPath(change.Path, _lostMediaFiles); if (mediaData == null && lostMediaFile != null) { var lostMetaData = GetMediaMetaDataFromPath(change.PreviousPath, App.DatabaseMetaDatas); // Update path on metadata. lostMetaData.MediaFilePath = change.Path; // Get current MediaData associated with metadata. var lostMediaData = await MediaData.CreateFromMediaMetadataAsync(lostMetaData); // If file can still not be found then return. if (lostMediaData == null) { return; } // Add file to gallery, including the lost media data. await AddFileAsync(ImageSize, lostMediaFile, false, lostMediaData); } else if (mediaData == null) { return; } // Don't rename file in gallery if it is already renamed if (MediaDatas.Any(data => data.Title == newName)) { return; } var mediaFile = (StorageFile)(await change.GetStorageItemAsync()); // Run on UI thread. await App.Current.NavigationService.Frame.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // Update MediaFile of mediaData. mediaData.MediaFile = mediaFile; }); await mediaData.UpdateFileNameValuesAsync(newName); } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } } break; // File Removed From Library case StorageLibraryChangeType.Deleted: case StorageLibraryChangeType.MovedOutOfLibrary: if (FileTypes.Extensions.Contains(extension, StringComparer.InvariantCultureIgnoreCase)) { try { // Only remove file from gallery if it exists in gallery. if (MediaDatas.Any(data => data.MediaFile.Path == change.Path)) { RemoveFile(change.Path); } } catch (Exception e) { // Log Exception. LifecycleLog.Exception(e); } } break; // Modified Contents case StorageLibraryChangeType.ContentsChanged: if (FileTypes.Extensions.Contains(extension, StringComparer.InvariantCultureIgnoreCase)) { /*newFile = (StorageFile)(await change.GetStorageItemAsync()); * var imageProps = await newFile.Properties.GetImagePropertiesAsync(); * var dateTaken = imageProps.DateTaken; * var dateModified = newFile.DateCreated; * if (DateTimeOffset.Compare(dateTaken.AddSeconds(70), dateModified) > 0) * { * // File was modified by the user * }*/ } break; // Ignored Cases case StorageLibraryChangeType.EncryptionChanged: case StorageLibraryChangeType.ContentsReplaced: case StorageLibraryChangeType.IndexingStatusChanged: default: // These are safe to ignore in this application break; } }