//Copies files from LocalCache to SharedLocal private async Task CopyLocalCacheToSharedLocal(ApplicationDataCompositeValue argFeedSubscription) { try { string feedUriString = argFeedSubscription.ElementAt(1).Value.ToString(); string folderName = CreateValidFilename(feedUriString); IStorageItem myLocalCacheIStorageItem = await ApplicationData.Current.LocalCacheFolder.TryGetItemAsync(folderName); IStorageItem mySharedLocalIStorageItem = ApplicationData.Current.SharedLocalFolder; //If I have cached files and policy allows me to access SharedLocalFolder if (myLocalCacheIStorageItem != null && mySharedLocalIStorageItem != null) { StorageFolder myLocalCacheFolder = (StorageFolder)myLocalCacheIStorageItem; StorageFolder mySharedLocalFolder = await ApplicationData.Current.SharedLocalFolder.CreateFolderAsync(folderName, CreationCollisionOption.OpenIfExists); //Delete everything in SharedLocal before copying new IReadOnlyList <StorageFile> fileListSharedLocal = await mySharedLocalFolder.GetFilesAsync(); foreach (StorageFile file in fileListSharedLocal) { await file.DeleteAsync(); } //Copy every file from LocalCache to SharedLocal IReadOnlyList <StorageFile> fileListLocalCache = await myLocalCacheFolder.GetFilesAsync(); foreach (StorageFile file in fileListLocalCache) { await file.CopyAsync(mySharedLocalFolder, file.Name, NameCollisionOption.ReplaceExisting); } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } }
//Loads cached content for a given subscription private async Task LoadFeedCache(ApplicationDataCompositeValue argFeedSubscription) { try { feedsCollection.Clear(); string folderName = CreateValidFilename(argFeedSubscription.ElementAt(1).Value.ToString()); StorageFolder myStorageFolder = null; //If cache folder for subscription exists if (Directory.Exists(ApplicationData.Current.LocalCacheFolder.Path + "\\" + folderName)) { myStorageFolder = await ApplicationData.Current.LocalCacheFolder.GetFolderAsync(folderName); } else if (Directory.Exists(ApplicationData.Current.SharedLocalFolder.Path + "\\" + folderName)) { myStorageFolder = await ApplicationData.Current.SharedLocalFolder.GetFolderAsync(folderName); } if (myStorageFolder != null) { IReadOnlyList <StorageFile> fileList = await myStorageFolder.GetFilesAsync(); foreach (StorageFile file in fileList) { SyndicationItem mySyndicationItem = new SyndicationItem(); BitmapImage myBitmapImage = null; //TODO change .com to something more solid, this will break if we are getting feeds from not .com site //If the file is an article if (file.FileType.ToString() == ".") { Windows.Data.Xml.Dom.XmlDocument myXmlDocument = await Windows.Data.Xml.Dom.XmlDocument.LoadFromFileAsync(file); mySyndicationItem.LoadFromXml(myXmlDocument); var thumbnails = myXmlDocument.GetElementsByTagName("thumbnail"); if (thumbnails.Count > 1) { string thumbnailUriString = thumbnails[1].Attributes[1].InnerText; if (thumbnailUriString.EndsWith(".jpg")) { Uri uriForImage = new Uri(thumbnailUriString); string imageFileName = CreateValidFilename(thumbnailUriString); if (imageFileName.Length > 50) { imageFileName = imageFileName.Substring(imageFileName.Length - 50); } myBitmapImage = new BitmapImage(new System.Uri(myStorageFolder.Path + "\\" + imageFileName)); } } else { Regex rgx = new Regex(@"<img.*src=""(.*)"""); MatchCollection matches = rgx.Matches(mySyndicationItem.Summary.Text); if (matches.Count > 0) { string stringForImage = matches[0].Groups[1].Value; //If Uri has & parameters remove them stringForImage = RemoveAmpFromUri(stringForImage); Uri uriForImage = new Uri(stringForImage); string imageFileName = CreateValidFilename(uriForImage.ToString()); if (imageFileName.Length > 50) { imageFileName = imageFileName.Substring(imageFileName.Length - 50); } imageFileName = AddExtension(imageFileName); myBitmapImage = new BitmapImage(new System.Uri(myStorageFolder.Path + "\\" + imageFileName)); } } CustomRSSItem myCustomRSSItem = new CustomRSSItem(mySyndicationItem, myBitmapImage); feedsCollection.Insert(0, myCustomRSSItem); } } articlesListView.ItemsSource = feedsCollection; } } catch (Exception ex) { Debug.WriteLine(ex.Message); } }
//Download content for a subscription, save it to LocalCache and add it to the collection private async Task CacheFeed(ApplicationDataCompositeValue argFeedSubscription) { try { SyndicationClient client = new SyndicationClient(); client.SetRequestHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"); string feedUriString = argFeedSubscription.ElementAt(1).Value.ToString(); SyndicationFeed feed = await client.RetrieveFeedAsync(new Uri(feedUriString)); if (feed != null) { feedsCollection.Clear(); //Cache my content cache files to LocalCache inside per feed folder //Create folder if it does not exist string folderName = CreateValidFilename(feedUriString); StorageFolder myStorageFolder = await ApplicationData.Current.LocalCacheFolder.CreateFolderAsync(folderName, CreationCollisionOption.OpenIfExists); //Delete any old files in folder IReadOnlyList <StorageFile> fileListLocalCache = await myStorageFolder.GetFilesAsync(); foreach (StorageFile file in fileListLocalCache) { await file.DeleteAsync(); } ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings; int postLimit = int.Parse(localSettings.Values["#postsToDownload"].ToString()); //Cache every article foreach (SyndicationItem mySyndicationItem in feed.Items) { //Do not cache more posts that specified by user setting if (feedsCollection.Count == postLimit) { break; } CustomRSSItem myCustomRSSItem = null; //Cache posts string articleFileName = ""; Regex rgx1 = new Regex(@".*/(.+)"); MatchCollection matches1 = rgx1.Matches(mySyndicationItem.Id); if (matches1.Count > 0) { articleFileName = CreateValidFilename(matches1[0].Groups[1].Value); var xmlDoc = mySyndicationItem.GetXmlDocument(SyndicationFormat.Atom10); IStorageFile myIStorageFile = await myStorageFolder.CreateFileAsync(articleFileName, CreationCollisionOption.ReplaceExisting); await xmlDoc.SaveToFileAsync(myIStorageFile); //Download and cache images BitmapImage myBitmapImage = null; //Get image from thumbnail element var thumbnails = xmlDoc.GetElementsByTagName("thumbnail"); if (thumbnails.Count > 1) { string thumbnailUriString = thumbnails[1].Attributes[0].InnerText; if (thumbnailUriString.EndsWith(".jpg")) { Uri uriForImage = new Uri(thumbnailUriString); string imageFileName = CreateValidFilename(thumbnailUriString); if (imageFileName.Length > 50) { imageFileName = imageFileName.Substring(imageFileName.Length - 50); } HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"); IBuffer myIBuffer = await httpClient.GetBufferAsync(uriForImage); IStorageFile myImageFile = await myStorageFolder.CreateFileAsync(imageFileName, CreationCollisionOption.OpenIfExists); Stream stream = await myImageFile.OpenStreamForWriteAsync(); stream.Write(myIBuffer.ToArray(), 0, myIBuffer.ToArray().Length); myBitmapImage = new BitmapImage(new Uri(myImageFile.Path)); await stream.FlushAsync(); } } else //Retrieve .jpg from img link from summary text { Regex rgx = new Regex(@"<img.*src=""(.*)"""); MatchCollection matches = rgx.Matches(mySyndicationItem.Summary.Text); if (matches.Count > 0) { string stringForImage = matches[0].Groups[1].Value; //If Uri has & parameters remove them stringForImage = RemoveAmpFromUri(stringForImage); Uri uriForImage = new Uri(stringForImage); string imageFileName = CreateValidFilename(uriForImage.ToString()); if (imageFileName.Length > 50) { imageFileName = imageFileName.Substring(imageFileName.Length - 50); } imageFileName = AddExtension(imageFileName); HttpClient httpClient = new HttpClient(); IBuffer myIBuffer = await httpClient.GetBufferAsync(uriForImage); IStorageFile myImageFile = await myStorageFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting); Stream stream = await myImageFile.OpenStreamForWriteAsync(); stream.Write(myIBuffer.ToArray(), 0, myIBuffer.ToArray().Length); myBitmapImage = new BitmapImage(new Uri(myImageFile.Path)); } } if (myBitmapImage != null) { //If we have an RSSItem and an image, add them to collection myCustomRSSItem = new CustomRSSItem(mySyndicationItem, myBitmapImage); feedsCollection.Add(myCustomRSSItem); } } } articlesListView.ItemsSource = feedsCollection; //Copy what was just cached to SharedLocal Task t = CopyLocalCacheToSharedLocal(argFeedSubscription); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } }