/// <summary> /// Loads a page from the isolated storage of the device /// </summary> /// <param name="collectionIdentifier"></param> /// <param name="locale"></param> /// <param name="pageIdentifier"></param> /// <returns>The desired page or null, if the page wasn't found in the isolated folder</returns> public static async Task <IonPage> loadPageFromIsolatedStorageAsync(IonConfig config, string pageIdentifier) { try { // Generate filePath for page string filePath = FilePaths.getPagesFolderPath(config) + pageIdentifier + IonConstants.JsonFileExtension; IonPage page = null; using (await fileLocks.ObtainLock(filePath).LockAsync().ConfigureAwait(false)) { // Get file from file Path StorageFile file = await _localFolder.GetFileAsync(filePath); // Read content string string content = await FileIO.ReadTextAsync(file); // Deserialize page page = JsonConvert.DeserializeObject <IonPage>(content); } fileLocks.ReleaseLock(filePath); return(page); } catch (Exception e) { IonLogging.log("Error loading page " + pageIdentifier + " of collection " + config.collectionIdentifier + " from isolated storeage. Message: " + e.Message, IonLogMessageTypes.ERROR); return(null); } }
private async Task showData(string pageName) { try { IonPage page = await Ion.getInstance(AppController.instance.ampConfig).getPageAsync(pageName); _allContent = DataConverters.convertContent(page.getContents()); // Load files for page content await Ion.getInstance(AppController.instance.ampConfig).loadContentFilesAsync(_allContent); //await Ion.getInstance( AppController.instance.ampConfig ).DownloadSearchDatabase(); //List<SearchResult> results = await Ion.getInstance( AppController.instance.ampConfig ).FullTextSearch("test", "de_DE"); // Set the data context of the lists imageContentList.DataContext = _allContent.imageContent; textContentList.DataContext = _allContent.textContent; colorContentList.DataContext = _allContent.colorContent; flagContentList.DataContext = _allContent.flagContent; fileContentList.DataContext = _allContent.fileContent; mediaContentList.DataContext = _allContent.mediaContent; dateTimeContentList.DataContext = _allContent.dateTimeContent; optionContentList.DataContext = _allContent.optionContent; } catch (Exception exception) { // Error handling, if no data could be loaded Debug.WriteLine("Error loading page: " + exception.Message); } setDataLoaded(); initPage(); }
/// <summary> /// Saves a page to the isolated storage folder /// </summary> /// <param name="page"></param> /// <returns></returns> public static async Task savePageToIsolatedStorageAsync(IonPage page, IonConfig config) { try { // Generate filePath for page string filePath = FilePaths.getPagesFolderPath(config) + page.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 pageSerialized = JsonConvert.SerializeObject(page); // Write serialzed collection to file await FileIO.WriteTextAsync(file, pageSerialized); } fileLocks.ReleaseLock(filePath); } catch (Exception e) { IonLogging.log("Error saving page to isolated storage: " + e.Message, IonLogMessageTypes.ERROR); } }
public void pageEqualsCheck() { string pageStringOriginal = "{\"page\":[{\"parent\":\"education\",\"identifier\":\"grundschule-am-arnulfpark\",\"collection\":\"lookbook\",\"last_changed\":\"2016-04-28T06:48:03Z\",\"archive\":\"https://lookbook-dev.anfema.com/client/v1/de_DE/lookbook/grundschule-am-arnulfpark.tar\",\"contents\":[{\"outlet\":\"project\",\"type\":\"containercontent\",\"children\":[{\"type\":\"filecontent\",\"is_searchable\":false,\"outlet\":\"project-pdf\",\"is_available\":false,\"variation\":\"default\"},{\"type\":\"connectioncontent\",\"is_searchable\":false,\"outlet\":\"materials\",\"is_available\":false,\"variation\":\"default\"},{\"type\":\"textcontent\",\"mime_type\":\"text/html\",\"is_multiline\":true,\"is_searchable\":false,\"outlet\":\"description\",\"text\":\"<p>PrimarySchoolArnulfpark,<br>Munich,Germany,<br>HERADESIGN®<i>superfine</i></p>\",\"variation\":\"default\"},{\"width\":2048,\"scale\":0,\"is_searchable\":false,\"height\":1536,\"type\":\"imagecontent\",\"mime_type\":\"image/jpeg\",\"checksum\":\"sha256:02f207f9a133241fd651a001ce79f780a63741873aed5615e0d88d14f05f71ae\",\"original_file_size\":243439,\"original_checksum\":\"sha256:02f207f9a133241fd651a001ce79f780a63741873aed5615e0d88d14f05f71ae\",\"file_size\":243439,\"original_image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-1_TPOMWZN.jpg\",\"outlet\":\"images\",\"original_width\":2048,\"position\":0,\"variation\":\"default\",\"translation_y\":0,\"image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-1_TPOMWZN.jpg\",\"original_height\":1536,\"translation_x\":0,\"original_mime_type\":\"image/jpeg\"},{\"width\":2048,\"scale\":0,\"is_searchable\":false,\"height\":1536,\"type\":\"imagecontent\",\"mime_type\":\"image/jpeg\",\"checksum\":\"sha256:f0b73615e96fadccca4fda81e8103b6d02b64894ef2f7356d4e9840d57cf60aa\",\"original_file_size\":466526,\"original_checksum\":\"sha256:f0b73615e96fadccca4fda81e8103b6d02b64894ef2f7356d4e9840d57cf60aa\",\"file_size\":466526,\"original_image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-2_Y0LpxdS.jpg\",\"outlet\":\"images\",\"original_width\":2048,\"position\":1,\"variation\":\"default\",\"translation_y\":0,\"image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-2_Y0LpxdS.jpg\",\"original_height\":1536,\"translation_x\":0,\"original_mime_type\":\"image/jpeg\"},{\"width\":2048,\"scale\":0,\"is_searchable\":false,\"height\":1536,\"type\":\"imagecontent\",\"mime_type\":\"image/jpeg\",\"checksum\":\"sha256:21c9d0da97ec753620d6bfbe61afd6d8a7ee27515b48b79ba1d3ed7da0ca9438\",\"original_file_size\":359975,\"original_checksum\":\"sha256:21c9d0da97ec753620d6bfbe61afd6d8a7ee27515b48b79ba1d3ed7da0ca9438\",\"file_size\":359975,\"original_image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-3_GnnXUmT.jpg\",\"outlet\":\"images\",\"original_width\":2048,\"position\":2,\"variation\":\"default\",\"translation_y\":0,\"image\":\"https://lookbook-dev.anfema.com/protected_media/images/e9fb32e5-2fa2-4628-b778-4dfbe7b682aa/02-02-3_GnnXUmT.jpg\",\"original_height\":1536,\"translation_x\":0,\"original_mime_type\":\"image/jpeg\"}],\"variation\":\"default\"}],\"children\":[],\"locale\":\"de_DE\",\"layout\":\"project\",\"position\":1}]}"; IonPage page = DataParser.parsePage(pageStringOriginal); string pageStringResult = JsonConvert.SerializeObject(page); IonPage page2 = JsonConvert.DeserializeObject <IonPage>(pageStringResult); Assert.AreEqual(page, page2); }
/// <summary> /// Used to save a page to the memory and isolated storage cache /// </summary> /// <param name="page"></param> /// <param name="config"></param> /// <returns></returns> public async Task savePageToCachesAsync(IonPage page, IonConfig config) { // Memory cache _memoryCache.savePage(page, _config); // Local storage cache await StorageUtils.savePageToIsolatedStorageAsync(page, config).ConfigureAwait(false); // Save page cache index await PageCacheIndex.save(page, _config).ConfigureAwait(false); }
/// <summary> /// Returns a whole IonPage with the desired name and calls the given callback method after retrieving the page /// </summary> /// <param name="name"></param> /// <param name="callback"></param> /// <returns>IonPage with the desired name</returns> public async Task <IonPage> getPageAsync(string name, Action callback = null) { IonPage page = await _ionPages.getPageAsync(name).ConfigureAwait(false); if (callback != null) { callback(); } return(page); }
/// <summary> /// Get a desired page from the cache /// </summary> /// <param name="pageIdentifier"></param> /// <returns></returns> private async Task <IonPage> getPageFromCacheAsync(string pageIdentifier) { // Try to get page from memory cache IonPage page = _memoryCache.getPage(pageIdentifier, _config); if (page != null) { // Page in memory cache return(page); } // Try to load page from local storage page = await StorageUtils.loadPageFromIsolatedStorageAsync(_config, pageIdentifier).ConfigureAwait(false); // Add page to memory cache if (page != null) { _memoryCache.savePage(page, _config); } return(page); }
/// <summary> /// Gets a page directly from the server /// </summary> /// <param name="pageIdentifier"></param> /// <returns></returns> private async Task <IonPage> getPageFromServerAsync(string pageIdentifier) { try { // Retrieve the page from the server HttpResponseMessage response = await _dataClient.getPageAsync(pageIdentifier).ConfigureAwait(false); IonPage page = await DataParser.parsePageAsync(response).ConfigureAwait(false); // Add page to cache, if it is not null if (page != null) { await savePageToCachesAsync(page, _config); } return(page); } catch (Exception e) { IonLogging.log("Error getting page " + pageIdentifier + " from server! " + e.Message, IonLogMessageTypes.ERROR); return(null); } }
/// <summary> /// Parses a given pageString to a IonPage /// </summary> /// <param name="pageString"></param> /// <returns>Parsed IonPage</returns> public static IonPage parsePage(string pageString) { // Parse the page to a raw page container IonPage pageParsed = new IonPage(); try { // Deserialize page IonPageRoot pageParsedNew = JsonConvert.DeserializeObject <IonPageRoot>(pageString); // Set the first element of the root to be the page pageParsed = pageParsedNew.page[0]; // Sort out empty content pageParsed.sortOutEmptyContent(); } catch (Exception e) { IonLogging.log("Error deserializing page json: " + e.Message, IonLogMessageTypes.ERROR); } return(pageParsed); }
/// <summary> /// 设置属性 /// </summary> protected override void SetAttributes() { IonPage control = this.ControlHost.Content as IonPage; base.SetAttributes(); }
/// <summary> /// Used to load and extract an archive to the caches /// </summary> /// <param name="ionFiles"></param> /// <param name="ionPages"></param> /// <param name="url"></param> /// <param name="callback"></param> /// <returns></returns> public async Task loadArchiveAsync(IIonFiles ionFiles, IIonPages ionPages, string url, Action callback = null) { // Temporary used elements in the isolated storage StorageFile archiveFile = null; StorageFolder tempFolder = null; // Get temp-folder path string tempFolderPath = FilePaths.getTempFolderPath(_config); // Lock all used elements using (await _fileLocks.ObtainLock(url).LockAsync().ConfigureAwait(false)) using (await _fileLocks.ObtainLock(tempFolderPath).LockAsync().ConfigureAwait(false)) { try { // Request archive file archiveFile = await ionFiles.requestArchiveFileAsync(url); // Get tempFolder for extraction tempFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(tempFolderPath, CreationCollisionOption.ReplaceExisting); // Generate fileStream from archiveFile using (Stream stream = (Stream)await archiveFile.OpenStreamForReadAsync()) { // Extract file to tempFolder await TarUtils.ExtractTarArchiveAsync(stream, tempFolder).ConfigureAwait(false); } // Get all elements listed in the index file string indexFileString = await FileIO.ReadTextAsync(await tempFolder.GetFileAsync("index.json")); List <ArchiveElement> elementsList = JsonConvert.DeserializeObject <List <ArchiveElement> >(indexFileString); // Handle each element of the index.json for (int i = 0; i < elementsList.Count; i++) { IonRequestInfo requestInfo = PagesURLs.analyze(elementsList[i].url, _config); // Treat every element regarding its type switch (requestInfo.requestType) { case IonRequestType.MEDIA: { // Get all the needed folder- and file names StorageFolder mediaFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(FilePaths.getMediaFolderPath(_config, false), CreationCollisionOption.OpenIfExists); string sourcePath = tempFolder.Path + IonConstants.BackSlash + elementsList[i].name.Replace('/', (char)IonConstants.BackSlash[0]); string destinationPath = mediaFolder.Path + IonConstants.BackSlash + FilePaths.getFileName(elementsList[i].url); // Delete a possible existing file if (File.Exists(destinationPath)) { File.Delete(destinationPath); } // Move the file from the temp to the media folder File.Move(sourcePath, destinationPath); // Create index for file FileCacheIndex index = new FileCacheIndex(elementsList[i].url, elementsList[i].checksum, DateTimeUtils.now()); // Save file index await CacheIndexStore.save(elementsList[i].url, index, _config).ConfigureAwait(false); break; } case IonRequestType.PAGE: { // Extract the page json from the file string pageString = await FileIO.ReadTextAsync(await tempFolder.GetFileAsync(elementsList[i].name.Replace('/', (char)IonConstants.BackSlash[0]))); // Parse the new page IonPage page = DataParser.parsePage(pageString); // Save the page to the caches await ionPages.savePageToCachesAsync(page, _config).ConfigureAwait(false); break; } default: { IonLogging.log("Object " + elementsList[i].url + " could not be parsed from archive.", IonLogMessageTypes.ERROR); break; } } } } catch (Exception e) { IonLogging.log("Error at the archive download: " + e.Message, IonLogMessageTypes.ERROR); } finally { // Clean up all temperary used elements if (archiveFile != null) { // Delete index file string indexFilePath = FilePaths.getCacheIndicesFolderPath(_config) + IonConstants.BackSlash + archiveFile.Name + IonConstants.JsonFileExtension; if (File.Exists(indexFilePath)) { File.Delete(indexFilePath); } // Delete archive file await archiveFile.DeleteAsync(); } if (tempFolder != null) { await tempFolder.DeleteAsync(); } // Call the callback action if set before if (callback != null) { callback(); } } } // Release the file locks _fileLocks.ReleaseLock(url); _fileLocks.ReleaseLock(tempFolderPath); }
/// <summary> /// Saves a pageCacheIndex to cache /// </summary> /// <param name="page"></param> /// <param name="config"></param> public static async Task save(IonPage page, IonConfig config) { string url = PagesURLs.getPageURL(config, page.identifier); PageCacheIndex cacheIndex = new PageCacheIndex(url, page.last_changed); await CacheIndexStore.save <PageCacheIndex>(url, cacheIndex, config).ConfigureAwait(false); }
/// <summary> /// Saves a page to the memory cache /// </summary> /// <param name="page"></param> /// <param name="config"></param> public void savePage(IonPage page, IonConfig config) { string pageUrl = PagesURLs.getPageURL(config, page.identifier); _pageMemoryCache.add(pageUrl, page); }
/// <summary> /// Returns a page from the memory cache with the desired URL. If the page is not in cache, then null will be returned /// </summary> /// <param name="pageURL"></param> /// <returns></returns> private IonPage getPage(string pageURL) { IonPage page = _pageMemoryCache.get(pageURL); return(page); }