/// <summary> /// Loads a collection from the isolated storage folder /// </summary> /// <param name="collectionIdentifier"></param> /// <returns>The collection or null, if the collection isn't found</returns> public static async Task <IonCollection> loadCollectionFromIsolatedStorageAsync(IonConfig config) { try { // Generate filePath for collection string filePath = FilePaths.getCollectionFolderPath(config) + config.collectionIdentifier + IonConstants.JsonFileExtension; IonCollection collection = null; using (await fileLocks.ObtainLock(filePath).LockAsync().ConfigureAwait(false)) { // Open file StorageFile file = await _localFolder.GetFileAsync(filePath); // Extract content string content = await FileIO.ReadTextAsync(file); // Deserialize collection collection = JsonConvert.DeserializeObject <IonCollection>(content); } fileLocks.ReleaseLock(filePath); return(collection); } catch (Exception e) { IonLogging.log("Error loading collection " + config.collectionIdentifier + " from isolated storeage. Message: " + e.Message, IonLogMessageTypes.ERROR); return(null); } }
/// <summary> /// Gets a collection from the cache /// </summary> /// <param name="collectionIdentifier"></param> /// <returns></returns> private async Task <IonCollection> getCollectionFromCacheAsync(CollectionCacheIndex cacheIndex, bool serverCallAsBackup) { string collectionURL = PagesURLs.getCollectionURL(_config); // retrieve from memory cache IonCollection collection = _memoryCache.collection; if (collection != null) { return(collection); } // try to load collection from isolated storage try { collection = await StorageUtils.loadCollectionFromIsolatedStorageAsync(_config).ConfigureAwait(false); // Add collection to memory cache if (collection != null) { _memoryCache.collection = collection; } } catch (Exception e) { IonLogging.log("Error getting collection from isolated storage. Message: " + e.Message, IonLogMessageTypes.ERROR); } return(collection); }
/// <summary> /// Used to get a list of pagePreviews that match the given filter /// </summary> /// <param name="filter"></param> /// <returns>List of pagePreviews</returns> public async Task <List <IonPagePreview> > getPagePreviewsAsync(Predicate <IonPagePreview> filter) { // Filter all pagePreviews in collection with the given filter IonCollection collection = await getCollectionAsync().ConfigureAwait(false); List <IonPagePreview> filteredPagePreviews = collection.pages.FindAll(filter); return(filteredPagePreviews); }
public void collectionEqualsCheck() { string collectionStringOriginal = "{\"collection\":[{\"identifier\":\"lookbook\",\"default_locale\":\"de_DE\",\"last_changed\":\"2016-04-18T16:56:52Z\",\"fts_db\":\"https://lookbook-dev.anfema.com/protected_media/fts/lookbook.sqlite3\",\"archive\":\"https://lookbook-dev.anfema.com/client/v1/de_DE/lookbook.tar?variation=default\",\"pages\":[{\"identifier\":\"barkers-department-store\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-18T12:02:19Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"commercial\",\"meta\":{\"materials\":\"//lookbook/material-thermatex-dummy\",\"description\":\"<p>BarkersDepartmentStore,<br>England,<br>THERMATEX®Alpha</p>\"}},{\"identifier\":\"harley-davidson-zentrale\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-18T11:52:15Z\",\"position\":1,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"commercial\",\"meta\":{\"description\":\"<p>HarleyDavidsonZentrale,<br>Neu-Isenburg,Deutschland,<br>HERADESIGN®xy</p>\"}},{\"identifier\":\"baudoin-wash-systems-bv\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-18T11:52:24Z\",\"position\":2,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"commercial\",\"meta\":{\"description\":\"<p>BaudoinWashSystemsB.V.,<br>Niederlande,<br>THERMATEX®Alpha</p>\"}},{\"identifier\":\"konsum-leipzig\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-30T14:37:04Z\",\"position\":3,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"commercial\",\"meta\":{\"description\":\"KonsumLeipzig,\\nLeipzig,Deutschland,\\nTHERMATEX®Alphacreme\"}},{\"identifier\":\"erika-cavallini\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T12:35:45Z\",\"position\":4,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"commercial\",\"meta\":{\"description\":\"<p>ErikaCavalliniMailand,<br>Italien,<br>HERADESIGN®xy</p>\"}},{\"identifier\":\"essa-primary-school\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-18T16:51:37Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>EssaPrimarySchool,<br>England,<br>THERMATEX®AntarisHERADESIGN®fine</p>\"}},{\"identifier\":\"grundschule-am-arnulfpark\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-18T16:56:52Z\",\"position\":1,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>GrundschuleamArnulfpark,<br>Mu¨nchen,Deutschland,<br>HERADESIGN®superfine</p>\"}},{\"identifier\":\"schule-fischerhude\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:23:40Z\",\"position\":2,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>SchuleFischerhude,<br>Deutschland,<br>THERMATEX®Baffel</p>\"}},{\"identifier\":\"kita-doberlug\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:24:18Z\",\"position\":3,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>KitaDoberlug,<br>Deutschland,<br>THERMATEX®VariolineMotiv</p>\"}},{\"identifier\":\"novopecherskaya-schule\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:25:34Z\",\"position\":4,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>NovopecherskayaSchule,<br>Kiew,Ukraine,<br>THERMATEX®Antaris<br>THERMATEX®Sonicelement<br>HERADESIGN®fineHERADESIGN®fine</p>\"}},{\"identifier\":\"universitat-leiden\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:26:29Z\",\"position\":5,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"education\",\"meta\":{\"description\":\"<p>Universita¨tLeiden,<br>Niederlande,<br>HERADESIGN®fine</p>\"}},{\"identifier\":\"incor-hospital\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:35:01Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"infrastructure\",\"meta\":{\"description\":\"<p>IncorHospital,<br>Sa~oPaulo,Brazil,<br>THERMATEX®Thermofon</p>\"}},{\"identifier\":\"multiplex-atmosphera-cinema\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:30:04Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"lifestyle\",\"meta\":{\"description\":\"<p>MULTIPLEX-AtmospheraCinema,<br>Kiew,Ukraine,<br>HERADESIGN®fine,<br>THERMATEX®Alpha,THERMATEX®AlphaBlack</p>\"}},{\"identifier\":\"bowling-bahn\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:31:31Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"sports-leisure\",\"meta\":{\"description\":\"<p>BowlingBahn,<br>Ukraine,<br>HERADESIGN®superfine<br>HERADESIGN®Deckensegel<br>THERMATEX®Alpha</p>\"}},{\"identifier\":\"mediacom-gmbh\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-31T09:32:59Z\",\"position\":0,\"layout\":\"project\",\"locale\":\"de_DE\",\"parent\":\"office\",\"meta\":{\"description\":\"<p>MediacomGmbH,<br>Brilon,Deutschland,<br>THERMATEX®Sonicelement,<br>THERMATEX®LineWandabsorbermitMotiv</p>\"}},{\"identifier\":\"material-thermatex-dummy\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-14T06:11:13Z\",\"position\":0,\"layout\":\"material\",\"locale\":\"de_DE\",\"parent\":\"settings\",\"meta\":{\"title\":\"Title\",\"subtitle\":\"Subtitle\"}},{\"identifier\":\"dummy-material-2\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-14T15:44:00Z\",\"position\":1,\"layout\":\"material\",\"locale\":\"de_DE\",\"parent\":\"settings\",\"meta\":{\"title\":\"Title\",\"subtitle\":\"Subtitle\"}},{\"identifier\":\"commercial\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-14T08:49:26Z\",\"position\":0,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Commercial\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/58009e0c-953c-401a-825f-7594e9bfa2a4/01_commercial.png\"}},{\"identifier\":\"education\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-24T14:30:38Z\",\"position\":1,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Education\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/b5452444-7122-4a1d-b7a9-24889869939b/01_commercial.png\"}},{\"identifier\":\"infrastructure\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-24T14:30:58Z\",\"position\":2,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Infrastructure\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/fe5efb73-4ef4-4a0c-bbaa-f804ab91b024/01_commercial.png\"}},{\"identifier\":\"lifestyle\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-24T14:31:16Z\",\"position\":3,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Lifestyle\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/8d4ca813-211c-44d7-acf2-feb465b1e952/01_commercial.png\"}},{\"identifier\":\"sports-leisure\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-24T14:31:35Z\",\"position\":4,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Sports&Leisure\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/3f5e9f98-c050-4963-9556-79d7222d4270/01_commercial.png\"}},{\"identifier\":\"office\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-03-24T14:31:53Z\",\"position\":5,\"layout\":\"category\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Office\",\"menu-mask\":\"https://lookbook-dev.anfema.com/protected_media/images/3d0a8578-b9ad-4d3c-86bc-7ca746170de8/01_commercial.png\"}},{\"identifier\":\"about\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-14T16:32:43Z\",\"position\":6,\"layout\":\"about\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{\"title\":\"Legal\"}},{\"identifier\":\"settings\",\"collection_identifier\":\"lookbook\",\"version_number\":1,\"last_changed\":\"2016-04-11T14:55:35Z\",\"position\":7,\"layout\":\"settings\",\"locale\":\"de_DE\",\"parent\":null,\"meta\":{}}]}]}"; IonCollection collection = DataParser.parseCollection(collectionStringOriginal); string collectionStringResult = JsonConvert.SerializeObject(collection); IonCollection collection2 = JsonConvert.DeserializeObject <IonCollection>(collectionStringResult); Assert.AreEqual(collection, collection2); }
public async Task <String> DownloadSearchDatabaseAsync() { String dbTargetFile = FilePaths.GetFtsDbFilePath(_config.collectionIdentifier); IonCollection ampCollection = await _ampPages.getCollectionAsync().ConfigureAwait(false); // Load fts db from server and save data to file using (MemoryStream responseStream = await _dataClient.performRequestAsync(ampCollection.fts_db).ConfigureAwait(false)) { await FileUtils.WriteToFile(responseStream, dbTargetFile).ConfigureAwait(false); } return(dbTargetFile); }
/// <summary> /// Used to get a page with a desired identifier /// </summary> /// <param name="pageIdentifier"></param> /// <returns>Already parsed IonPage</returns> public async Task <IonPage> getPageAsync(string pageIdentifier) { string pageURL = PagesURLs.getPageURL(_config, pageIdentifier); PageCacheIndex pageCacheIndex = await PageCacheIndex.retrieve(pageURL, _config).ConfigureAwait(false); bool isNetworkConnected = NetworkUtils.isOnline(); if (pageCacheIndex == null) { if (isNetworkConnected) { IonLogging.log("Loading page \"" + pageIdentifier + "\" from server.", IonLogMessageTypes.SUCCESS); return(await getPageFromServerAsync(pageIdentifier).ConfigureAwait(false)); } else { IonLogging.log("Error getting page \"" + pageIdentifier + "\" from server or cache.", IonLogMessageTypes.ERROR); throw new PageNotAvailableException(); } } // Get collection IonCollection collection = await getCollectionAsync().ConfigureAwait(false); // Get last changed of the page from collection DateTime pageLastChanged = collection.getPageLastChanged(pageIdentifier); // Estimate, if the page is outdated or not bool isOutdated = pageCacheIndex.isOutdated(pageLastChanged); if (!isOutdated) { IonLogging.log("Loading page \"" + pageIdentifier + "\" from cache.", IonLogMessageTypes.SUCCESS); return(await getPageFromCacheAsync(pageIdentifier).ConfigureAwait(false)); } else { if (isNetworkConnected) { // Download page from server IonLogging.log("Loading newer version of page \"" + pageIdentifier + "\" from server.", IonLogMessageTypes.SUCCESS); return(await getPageFromServerAsync(pageIdentifier).ConfigureAwait(false)); } else { // get old version from cache IonLogging.log("Loading potentially old version of page \"" + pageIdentifier + "\" from cache.", IonLogMessageTypes.WARNING); return(await getPageFromCacheAsync(pageIdentifier).ConfigureAwait(false)); } } }
/// <summary> /// Saves a collection to the isolated storage /// </summary> /// <param name="collection"></param> /// <returns></returns> public static async Task saveCollectionToIsolatedStorageAsync(IonCollection collection, IonConfig config) { // Generate filePath for collection file string filePath = FilePaths.getCollectionFolderPath(config) + collection.identifier + IonConstants.JsonFileExtension; using (await fileLocks.ObtainLock(filePath).LockAsync().ConfigureAwait(false)) { // Create file or use existing file StorageFile file = await _localFolder.CreateFileAsync(filePath, CreationCollisionOption.ReplaceExisting); // Serialize collection string collectionSerialized = JsonConvert.SerializeObject(collection); // Write serialzed collection to file await FileIO.WriteTextAsync(file, collectionSerialized); } fileLocks.ReleaseLock(filePath); }
/// <summary> /// Gets a collection from the server /// </summary> /// <param name="collectionIdentifier"></param> /// <returns></returns> private async Task <IonCollection> getCollectionFromServerAsync(CollectionCacheIndex cacheIndex, bool cacheAsBackup) { //DateTime lastModified = cacheIndex != null ? cacheIndex.lastModified : DateTime.MinValue; try { // Retrive collecion from server and parse it HttpResponseMessage response = await _dataClient.getCollectionAsync(_config.collectionIdentifier, cacheIndex != null?cacheIndex.lastModified : DateTime.MinValue).ConfigureAwait(false); // Only parse the answer if it is not newer than the cached version if (!(response.StatusCode == System.Net.HttpStatusCode.NotModified)) { // Parse collection IonCollection collection = await DataParser.parseCollectionAsync(response).ConfigureAwait(false); // Add collection to memory cache _memoryCache.collection = collection; // Save collection to isolated storage await StorageUtils.saveCollectionToIsolatedStorageAsync(collection, _config).ConfigureAwait(false); // save cacheIndex await saveCollectionCacheIndexAsync(collection.last_changed).ConfigureAwait(false); return(collection); } else { // Collection in the server is the same as stored already in isolated storage cache if (_memoryCache.collection == null) { // Only load collection from isolated storage cache, if the memory cache has no collection cached try { // Get collection from isolated storage IonCollection collection = await StorageUtils.loadCollectionFromIsolatedStorageAsync(_config).ConfigureAwait(false); // Add collection to memory cache if (collection != null) { _memoryCache.collection = collection; } // change the last-mofied date in the cacheIndex to now await saveCollectionCacheIndexAsync(collection.last_changed).ConfigureAwait(false); return(collection); } catch (Exception e) { IonLogging.log("Error getting collection from isolated storage. Message: " + e.Message, IonLogMessageTypes.ERROR); return(null); } } else { // change the last-mofied date in the cacheIndex to now await saveCollectionCacheIndexAsync(_memoryCache.collection.last_changed).ConfigureAwait(false); return(_memoryCache.collection); } } } catch (Exception e) { IonLogging.log("Error retreiving collection data: " + e.Message, IonLogMessageTypes.ERROR); return(null); } }
/// <summary> /// Inits the memory cache with a given size /// </summary> /// <param name="pageMemoryCacheSize"></param> public MemoryCache(long pageMemoryCacheSize) { _pageMemoryCacheSize = pageMemoryCacheSize; collection = null; _pageMemoryCache = new LRUCache <string, IonPage>(pageMemoryCacheSize); }