Ejemplo n.º 1
0
 public override void Load()
 {
     if (SettingsHolder.Content.SkinsCacheNames)
     {
         InitializeLocationsOnce();
         if (!_fullDetailsRequired)
         {
             var name = CacheStorage.Get <string>(_nameCacheKey);
             if (name != null)
             {
                 ClearErrors();
                 ClearData();
                 Loaded  = false;
                 Name    = name;
                 Changed = false;
                 Loaded  = true;
                 return;
             }
         }
         base.Load();
         CacheStorage.Set(_nameCacheKey, Name);
     }
     else
     {
         base.Load();
     }
 }
Ejemplo n.º 2
0
 private void SaveListToCache(IList <TItem> list)
 {
     if (_cacheKey == null)
     {
         return;
     }
     CacheStorage.Set(_cacheKey, list.Select(x => x.Serialize()));
 }
Ejemplo n.º 3
0
 public static void Set <T>(string key, T value)
 {
     CacheStorage.Set(key + Postfix, DateTime.Now);
     if (SimpleSerialization.IsSupported <T>())
     {
         CacheStorage.Set(key, value);
     }
     else
     {
         CacheStorage.Storage.SetObject(key, value);
     }
 }
Ejemplo n.º 4
0
        public static void SetShared(string filename, string url)
        {
            var name = Path.GetFileName(filename)?.ApartFromLast(ReplayObject.ReplayExtension, StringComparison.OrdinalIgnoreCase);
            var info = new FileInfo(filename);

            if (name == null || !info.Exists)
            {
            }
            else
            {
                CacheStorage.Set($@"sharedReplay:{name.ToLowerInvariant()}:{info.Length}", url);
            }
        }
Ejemplo n.º 5
0
        public static async Task <string> PostOnlineDataAsync(ServerInformationExtra data, CancellationToken cancellation = default(CancellationToken))
        {
            try {
                var json     = JsonConvert.SerializeObject(data);
                var key      = ".PostedOnlineData:" + json.GetChecksum();
                var uploaded = CacheStorage.Get <string>(key);
                if (uploaded != null)
                {
                    return(uploaded);
                }

                var id = await InternalUtils.PostOnlineDataAsync(json, UserAgent, cancellation);

                if (id != null)
                {
                    CacheStorage.Set(key, id);
                    LazierCached.Set(@".OnlineData:" + id, data);
                }

                return(id);
            } catch (Exception e) when(e.IsCancelled())
            {
            } catch (WebException e) when(e.Response is HttpWebResponse h)
            {
                try {
                    var s = h.GetResponseStream()?.ReadAsStringAndDispose();
                    if (s != null)
                    {
                        var o = JObject.Parse(s);
                        if (o["error"] != null)
                        {
                            NonfatalError.NotifyBackground($"Can’t share online data: {o["error"].ToString().ToSentenceMember()}",
                                                           o["details"]?.ToString().ToSentence());
                            return(null);
                        }
                    }
                    NonfatalError.NotifyBackground($"Can’t share online data: {h.StatusDescription.ToLower()}", e);
                } catch (Exception ex) {
                    Logging.Warning(ex);
                    NonfatalError.NotifyBackground("Can’t share online data", e);
                }
            } catch (Exception e) {
                NonfatalError.NotifyBackground("Can’t share online data", e);
            }
            return(null);
        }
Ejemplo n.º 6
0
        public override Task SaveAsync()
        {
            FullDetailsRequired();

            var json = new JObject();

            SaveData(json);
            CacheStorage.Set(_nameCacheKey, Name);

            Changed = false;
            using (CarsManager.Instance.IgnoreChanges()) {
                File.WriteAllText(JsonFilename, JsonConvert.SerializeObject(json, Formatting.Indented, new JsonSerializerSettings {
                    Formatting           = Formatting.Indented,
                    NullValueHandling    = NullValueHandling.Include,
                    DefaultValueHandling = DefaultValueHandling.Include,
                    Culture = CultureInfo.InvariantCulture
                }));
            }

            return(Task.Delay(0));
        }
Ejemplo n.º 7
0
        private async Task <string> TryToFindAppIconAsync()
        {
            const string iconMissing = "_";

            var iconKey = $".AppIcon:{Id}";
            var result  = CacheStorage.Get <string>(iconKey);

            if (result != null)
            {
                return(result == iconMissing ? null : result);
            }

            var windows = await Windows.GetValueAsync();

            var icon = windows?.FirstOrDefault(x => string.Equals(x.DisplayName, Name, StringComparison.Ordinal))
                       ?? windows?.FirstOrDefault(x => string.Equals(x.DisplayName, Id, StringComparison.Ordinal))
                       ?? windows?.OrderBy(x => x.DisplayName.Length).FirstOrDefault();

            CacheStorage.Set(iconKey, icon?.IconOff ?? iconMissing);
            return(icon?.IconOff);
        }
Ejemplo n.º 8
0
        public static async Task <TimeZoneInfo> TryToDetermineAsync(GeoTagsEntry geoTags)
        {
            var key = Key + geoTags;

            if (CacheStorage.Contains(key))
            {
                return(CacheStorage.Get <string>(key).As <TimeZoneInfo>());
            }

            try {
                var result = await GoogleApiProvider.DetermineTimeZoneAsync(geoTags);

                CacheStorage.Set(key, result);
                return(result);
            } catch (WebException e) {
                Logging.Warning(e.Message);
                return(null);
            } catch (Exception e) {
                Logging.Warning(e);
                CacheStorage.Set(key, "");
                return(null);
            }
        }
Ejemplo n.º 9
0
        public static async Task <GeoTagsEntry> TryToLocateAsync([CanBeNull] string address)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                return(null);
            }

            var key = Key + address;

            if (CacheStorage.Contains(key))
            {
                var cache = CacheStorage.Get <string>(key).As <Point?>();
                return(cache.HasValue ? new GeoTagsEntry(cache.Value.X, cache.Value.Y) : null);
            }

            try {
                var result = await YahooApiProvider.LocateAsync(address);

                if (result.LatitudeValue.HasValue && result.LongitudeValue.HasValue)
                {
                    Logging.Write($"“{address}”, geo tags: ({result})");
                    CacheStorage.Set(key, new Point(result.LatitudeValue.Value, result.LongitudeValue.Value).As <string>());
                    return(result);
                }

                CacheStorage.Set(key, "");
                return(null);
            } catch (WebException e) {
                Logging.Warning("TryToLocateAsync(): " + e.Message);
                return(null);
            } catch (Exception e) {
                Logging.Warning("TryToLocateAsync(): " + e);
                CacheStorage.Set(key, "");
                return(null);
            }
        }
Ejemplo n.º 10
0
            // RaceU API, v1
            // ReSharper disable InconsistentNaming

            public void _setLinks(string encodedData)
            {
                CacheStorage.Set(".raceULinks", encodedData);
                ActionExtension.InvokeInMainThread(() => SetRaceULinks(encodedData));
            }
Ejemplo n.º 11
0
        private async Task <string> DownloadResumeSupportAsync([NotNull] CookieAwareWebClient client,
                                                               [NotNull] FlexibleLoaderGetPreferredDestinationCallback getPreferredDestination,
                                                               [CanBeNull] FlexibleLoaderReportDestinationCallback reportDestination, [CanBeNull] Func <bool> checkIfPaused,
                                                               IProgress <long> progress, CancellationToken cancellation)
        {
            // Common variables
            string filename = null, selectedDestination = null, actualFootprint = null;
            Stream remoteData = null;

            var resumeSupported = ResumeSupported;

            try {
                // Read resume-related data and remove it to avoid conflicts
                var resumeDestination             = CacheStorage.Get <string>(_keyDestination);
                var resumePartiallyLoadedFilename = CacheStorage.Get <string>(_keyPartiallyLoadedFilename);
                var resumeLastWriteDate           = CacheStorage.Get <DateTime?>(_keyLastWriteDate);
                var resumePreviousFootprint       = CacheStorage.Get <string>(_keyFootprint);
                ClearResumeData();

                // Collect known information for destination callback
                var information = FlexibleLoaderMetaInformation.FromLoader(this);

                // Opening stream to read…
                var headRequest = HeadRequestSupported && resumeDestination != null;
                using (headRequest ? client.SetMethod("HEAD") : null) {
                    Logging.Warning($"Initial request: {(headRequest ? "HEAD" : "GET")}");
                    remoteData = await client.OpenReadTaskAsync(Url);
                }

                cancellation.ThrowIfCancellationRequested();

                // Maybe we’ll be lucky enough to load the most accurate data
                if (client.ResponseHeaders != null)
                {
                    if (long.TryParse(client.ResponseHeaders[HttpResponseHeader.ContentLength] ?? "",
                                      NumberStyles.Any, CultureInfo.InvariantCulture, out var length))
                    {
                        TotalSize = information.TotalSize = length;
                    }

                    if (TryGetFileName(client.ResponseHeaders, out var fileName))
                    {
                        FileName = information.FileName = fileName;
                    }

                    // For example, Google Drive responds with “none” and yet allows to download file partially,
                    // so this header will only be checked if value is not defined.
                    if (resumeSupported == null)
                    {
                        var accept = client.ResponseHeaders[HttpResponseHeader.AcceptRanges] ?? "";
                        if (accept.Contains("bytes"))
                        {
                            resumeSupported = true;
                        }
                        else if (accept.Contains("none"))
                        {
                            resumeSupported = false;
                        }
                    }

                    client.LogResponseHeaders();
                }

                // Was the file partially loaded before?
                var partiallyLoaded = ResumeSupported != false && resumePartiallyLoadedFilename != null
                        ? new FileInfo(FileUtils.EnsureFilenameIsValid(resumePartiallyLoadedFilename)) : null;
                if (partiallyLoaded != null)
                {
                    Logging.Warning("Not finished: " + partiallyLoaded);
                }

                // Does it still exist
                if (partiallyLoaded?.Exists != true)
                {
                    Logging.Warning($"Partially downloaded file “{partiallyLoaded?.FullName}” does not exist");
                    partiallyLoaded = null;
                }

                // If so, wasn’t it changed since the last time?
                if (partiallyLoaded?.LastWriteTime > resumeLastWriteDate + TimeSpan.FromMinutes(5))
                {
                    Logging.Warning($"Partially downloaded file is newer that it should be: {partiallyLoaded.LastWriteTime}, expected: {resumeLastWriteDate}");
                    partiallyLoaded = null;
                }

                // Looks like file is partially downloaded, but let’s ensure link still leads to the same content
                actualFootprint = GetFootprint(information, client.ResponseHeaders);
                if (partiallyLoaded != null && resumePreviousFootprint != actualFootprint)
                {
                    Logging.Warning($"Footprints don’t match: {resumePreviousFootprint}≠{actualFootprint}");
                    partiallyLoaded = null;
                }

                // Let’s check where to load data, which is potentially the most actual data at this point
                var destination = getPreferredDestination(Url, information);
                selectedDestination = destination.Filename;
                if (partiallyLoaded != null && (!destination.CanResumeDownload || !FileUtils.ArePathsEqual(selectedDestination, resumeDestination)))
                {
                    Logging.Warning($"Different destination chosen: {selectedDestination} (before: {resumeDestination})");
                    partiallyLoaded = null;
                }

                // TODO: Check that header?

                // Where to write?
                // ReSharper disable once MergeConditionalExpression
                filename = partiallyLoaded != null ? partiallyLoaded.FullName : FileUtils.EnsureUnique(true, destination.Filename);
                reportDestination?.Invoke(filename);

                // Set cancellation token
                cancellation.Register(o => client.CancelAsync(), null);

                // Open write stream
                if (partiallyLoaded != null)
                {
                    var rangeFrom = partiallyLoaded.Length;
                    using (client.SetRange(new Tuple <long, long>(rangeFrom, -1))) {
                        Logging.Warning($"Trying to resume download from {rangeFrom} bytes…");

                        remoteData.Dispose();
                        remoteData = await client.OpenReadTaskAsync(Url);

                        cancellation.ThrowIfCancellationRequested();
                        client.LogResponseHeaders();

                        // It’s unknown if resume is supported or not at this point
                        if (resumeSupported == null)
                        {
                            var bytes      = new byte[16];
                            var firstBytes = await remoteData.ReadAsync(bytes, 0, bytes.Length);

                            cancellation.ThrowIfCancellationRequested();

                            if (CouldBeBeginningOfAFile(bytes))
                            {
                                using (var file = File.Create(filename)) {
                                    Logging.Warning("File beginning found, restart download");
                                    file.Write(bytes, 0, firstBytes);
                                    await CopyToAsync(remoteData, file, checkIfPaused, progress, cancellation);

                                    cancellation.ThrowIfCancellationRequested();
                                }

                                Logging.Write("Download finished");
                                return(filename);
                            }

                            rangeFrom += firstBytes;
                        }

                        using (var file = new FileStream(filename, FileMode.Append, FileAccess.Write)) {
                            await CopyToAsync(remoteData, file, checkIfPaused, new Progress <long>(v => {
                                progress?.Report(v + rangeFrom);
                            }), cancellation);

                            cancellation.ThrowIfCancellationRequested();
                        }
                    }
                }
                else
                {
                    if (headRequest)
                    {
                        Logging.Warning("Re-open request to be GET");
                        remoteData.Dispose();
                        remoteData = await client.OpenReadTaskAsync(Url);
                    }

                    using (var file = File.Create(filename)) {
                        Logging.Debug("Downloading the whole file…");
                        await CopyToAsync(remoteData, file, checkIfPaused, progress, cancellation);

                        cancellation.ThrowIfCancellationRequested();
                    }
                }

                Logging.Write("Download finished");
                return(filename);
            } catch (Exception e) when(e is WebException || e.IsCancelled())
            {
                Logging.Write("Download is interrupted! Saving details to resume later…");
                var download = filename == null ? null : new FileInfo(filename);

                if (download?.Exists == true && filename.Length > 0)
                {
                    CacheStorage.Set(_keyDestination, selectedDestination);
                    CacheStorage.Set(_keyPartiallyLoadedFilename, filename);
                    CacheStorage.Set(_keyFootprint, actualFootprint);
                    CacheStorage.Set(_keyLastWriteDate, download.LastWriteTime);
                }
                else
                {
                    ClearResumeData();
                }

                throw;
            } finally {
                remoteData?.Dispose();
            }
        }