private IObservable<Library> AskUserAboutLibraryUpdate( Library library, NedEngine.Engine.LibraryInfo updatedLibraryInfo )
        {
            string dialogMessage;
            string dialogHeader;
            if( updatedLibraryInfo.Version == library.Version )
            {
                dialogHeader = FileLanguage.MainPage_UpdateNotNecessaryHeader;
                dialogMessage = FileLanguage.MainPage_UpdateNotNecessaryMessage;
            }
            else
            {
                dialogHeader = FileLanguage.MainPage_NewVersionAvailableHeader;
                dialogMessage = FileLanguage.MainPage_NewVersionAvailableMessage;
            }

            if( MessageBox.Show( dialogMessage, dialogHeader, MessageBoxButton.OKCancel ) == MessageBoxResult.OK )
            {
                return Observable.Return( library );
            }
            else
            {
                return Observable.Empty<Library>();
            }
        }
 private IObservable<Library> CheckForUpdates( Library library )
 {
     if( library.CatalogueCount == -1 )
     {
         return Observable.Return<Library>( library );
     }
     else
     {
         return App.Engine.GetLibraryInfo( library )
                          .ObserveOnDispatcher()
                          .SelectMany( libraryInfo => AskUserAboutLibraryUpdate( library, libraryInfo ) );
     }
 }
 public void PrepareToUpdateLibraryData( Library library )
 {
     using( IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication() )
     {
         string libraryDirectory = Utils.LibraryDirPath( LoggedUser, library );
         if( isf.DirectoryExists( libraryDirectory ) )
         {
             if( isf.FileExists( Utils.LibraryXmlPath( LoggedUser, library ) ) && !isf.FileExists( Utils.LibraryXmlPreviousPath( LoggedUser, library ) ) )
             {
                 isf.MoveFile( Utils.LibraryXmlPath( LoggedUser, library ), Utils.LibraryXmlPreviousPath( LoggedUser, library ) );
             }
             else
             {
                 //shouldnt happen, will lose recent history
                 isf.DeleteFile( Utils.LibraryXmlPath( LoggedUser, library ) );
             }
         }
     }
 }
 public IObservable<Library> UpdateLibrary( Library library )
 {
     return CheckForUpdates( library )
            .SelectMany( CancelDownloadsFromLibrary )
            .Do(
            lib =>
            {
                PrepareToUpdateLibraryData( lib );
                lib.CatalogueCount = -1;
            } )
            .SelectMany( DownloadLibrary );
 }
 public IObservable<Library> DownloadLibrary( Library library )
 {
     return Transport.GetLibraryXml( library.ServerId )
                     .ObserveOnDispatcher()
                     .Do( libUpdate =>
                        {
                            library.Version = libUpdate.Version;
                            library.CatalogueCount = LibraryModel.GetCatalogueCount( libUpdate.Contents );
                            Library.SaveLibraryContents( libUpdate.Contents, library, LoggedUser );
                            Library.PrepareDiffXml( library, LoggedUser );
                        } )
                    .Select( _ => library );
 }
 public IObservable<LibraryInfo> GetLibraryInfo( Library library )
 {
     return Transport.GetLibraryInfo( library.ServerId );
 }
 public void DeleteLibrary( Library library )
 {
     LoggedUser.Libraries.Remove( library );
     CancelDownloadsFromLibrary( library ).Subscribe(
         lib =>
         {
             App.Engine.StatisticsManager.LogRemoveLibrary( lib );
             DeleteLibraryData( lib );
         } );
 }
 public static XDocument GetLibraryContents(Library libToLoad, User owner)
 {
     XDocument result = null;
     using (IsolatedStorageFile appDirectory = IsolatedStorageFile.GetUserStoreForApplication())
     using (var stream = appDirectory.OpenFile(Utils.LibraryXmlPath(owner, libToLoad), FileMode.Open, FileAccess.Read))
     {
         result = XDocument.Load(stream);
     }
     return result;
 }
        public IObservable<Unit> AddLibrary( string libraryId )
        {
            return Observable.Return( libraryId )
                             .SelectMany( id =>
                                 {
                                     if( String.IsNullOrEmpty( id ) )
                                     {
                                         return Observable.Throw<LibraryInfo>( new ArgumentException( FileLanguage.Error_LibraryIdEmpty ) );
                                     }

                                     if( LoggedUser.Libraries.Count( library => library.ServerId == libraryId ) != 0 )
                                     {
                                         return Observable.Throw<LibraryInfo>( new ArgumentException( FileLanguage.LIBRARY_ALREADY_EXISTS ) );
                                     }

                                     return Transport.GetLibraryInfo( id );
                                 } )
                             .ObserveOnDispatcher()
                             .Do( libInfo =>
                                 {
                                     Library library = new Library( libInfo.Id, libInfo.Title, libInfo.Version );
                                     StatisticsManager.LogAddLibrary( library );
                                     LoggedUser.Libraries.Add( library );
                                 } )
                             .Select( _ => new Unit() );
        }
        public IObservable<Library> CancelDownloadsFromLibrary( Library library )
        {
            var downloadsInLibrary = LoggedUser.Downloads.Where( download => download.LibraryId == library.ServerId ).ToList();
            LoggedUser.Downloads.Remove( downloadsInLibrary );

            return DownloadManager.CancelDownloads( downloadsInLibrary )
                                  .FinishedToNext()
                                  .Select( _ => library );
        }
        private static void updateXml(XDocument newXml, Library library, User owner)
        {
            //step 2 cleanup empty categories
            var emptyCategories =
                from newElement in newXml.Descendants(LibraryModel.NedNodeTag)
                where newElement.Attribute(LibraryModel.NedNodeTypeAttribute).Value == LibraryModel.CategoryTagType
                    && newElement.Descendants(LibraryModel.NedNodeTag).Count() == 0
                select newElement;
            for ( int i = emptyCategories.Count() - 1; i >= 0; i--)
            {
                XElement category = emptyCategories.ElementAt(i);
                string categoryToDeleteId = category.Attribute(LibraryModel.NedNodeIdAttribute).Value;
                foreach (CategoryModelItem categoryModelItem in App.Engine.LibraryModel.CategoryItems)
                {
                    if (categoryModelItem.Id == categoryToDeleteId)
                    {
                        categoryModelItem.IsChanged = false;
                        break;
                    }
                }
                category.Remove();
            }

            //step 3 cleanup empty catalogues
            var emptyCatalogs =
                from newElement in newXml.Descendants(LibraryModel.NedNodeTag)
                where newElement.Attribute(LibraryModel.NedNodeTypeAttribute).Value == LibraryModel.CatalogueTagType
                    && newElement.Descendants(LibraryModel.NedNodeTag).Count() == 0
                select newElement;

            for (int i = emptyCatalogs.Count() - 1; i >= 0; i--)
            {
                XElement catalogue = emptyCatalogs.ElementAt(i);
                string catalogueToDeleteId = catalogue.Attribute(LibraryModel.NedNodeIdAttribute).Value;
                foreach (CatalogueModelItem catalogueModelItem in App.Engine.LibraryModel.CatalogueItems)
                {
                    if (catalogueModelItem.Id == catalogueToDeleteId)
                    {
                        catalogueModelItem.IsChanged = false;
                        break;
                    }
                }
                catalogue.Remove();
            }

            //step 4 save diff xml and remove previous library xml
            using (IsolatedStorageFile appDirectory = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (newXml.Root != null)
                {
                    using (var stream = appDirectory.OpenFile(Utils.LibraryXmlDiffPath(owner, library), FileMode.Create))
                    {
                        newXml.Save(stream);
                    }
                }
                else
                {
                    if (appDirectory.FileExists(Utils.LibraryXmlDiffPath(owner, library)))
                    {
                        appDirectory.DeleteFile(Utils.LibraryXmlDiffPath(owner, library));
                    }
                }
                if (appDirectory.FileExists(Utils.LibraryXmlPreviousPath(owner, library)))
                {
                    appDirectory.DeleteFile(Utils.LibraryXmlPreviousPath(owner, library));
                }
            }
        }
        public static void SaveLibraryContents(string updatedContents, Library libToUpdate, User owner)
        {
            using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                string libraryDirectoryPath = Utils.LibraryDirPath(owner, libToUpdate);
                if (!isolatedStorage.DirectoryExists(libraryDirectoryPath))
                {
                    isolatedStorage.CreateDirectory(libraryDirectoryPath);
                    isolatedStorage.CreateDirectory("shared/transfers/" + libraryDirectoryPath);
                }

                using (StreamWriter writer = new StreamWriter(new IsolatedStorageFileStream(Utils.LibraryXmlPath(owner, libToUpdate), FileMode.Create, isolatedStorage)))
                {
                    writer.Write(updatedContents);
                }
            }
        }
        public static void PrepareDiffXml(Library library, User owner)
        {
            XDocument oldLib;
            XDocument newLib;
            XDocument oldDiff = null;
            using (IsolatedStorageFile appDirectory = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if(!appDirectory.FileExists(Utils.LibraryXmlPreviousPath(owner, library)))
                {
                    return;
                }
                using (var stream = appDirectory.OpenFile(Utils.LibraryXmlPreviousPath(owner, library), FileMode.Open, FileAccess.Read))
                {
                    oldLib = XDocument.Load(stream);
                }
                using (var stream = appDirectory.OpenFile(Utils.LibraryXmlPath(owner, library), FileMode.Open, FileAccess.Read))
                {
                    newLib = XDocument.Load(stream);
                }
                if(appDirectory.FileExists(Utils.LibraryXmlDiffPath(owner, library)))
                {
                    using (var stream = appDirectory.OpenFile(Utils.LibraryXmlDiffPath(owner, library), FileMode.Open, FileAccess.Read))
                    {
                        oldDiff = XDocument.Load(stream);
                    }
                }
            }

            XElement changesRoot = new XElement("changes");
            XDocument changes = new XDocument(changesRoot);

            List<XElement> newNodes = new List<XElement>(newLib.Descendants(LibraryModel.NedNodeTag));

            //step 1 - leave in newLib xml only changed elements
            for( int i = newNodes.Count - 1; i>= 0; i --)
            {
                XElement newNode = newNodes[i];
                var oldNodesSearch =
                    from oldElements in oldLib.Descendants(LibraryModel.NedNodeTag)
                    where (string)oldElements.Attribute(LibraryModel.NedNodeIdAttribute) == (string)newNode.Attribute(LibraryModel.NedNodeIdAttribute)
                    select oldElements;

                if (oldNodesSearch.Count() > 0)
                {
                    if (areItemsEqual(newNode, oldNodesSearch.First()) &&  newNode.Descendants(LibraryModel.NedNodeTag).Count() == 0)
                    {
                        if(oldDiff == null || (from oldDiffNode in oldDiff.Root.Descendants(LibraryModel.NedNodeTag)
                                                   where oldDiffNode.Attribute(LibraryModel.NedNodeIdAttribute).Value == newNode.Attribute(LibraryModel.NedNodeIdAttribute).Value
                                                   select oldDiff).Count() <= 0)
                        newNode.Remove();
                    }
                }
            }

            updateXml(newLib, library, owner);
        }
 public void LogRemoveLibrary( Library library )
 {
     Statistics.Add( LibraryStatisticItem.CreateRemoveLibraryEven( LoggedUser.LoggedUser, library ) );
 }
 public void DeleteLibraryData( Library library )
 {
     using( IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication() )
     {
         string libraryDirectory = Utils.LibraryDirPath( LoggedUser, library );
         if( isf.DirectoryExists( libraryDirectory ) )
         {
             isf.RecursivelyDeleteDirectory( libraryDirectory );
         }
     }
 }
        // Load library and return it's id
        public string LoadLibrary( Library library )
        {
            ActiveLibrary = library;

            LibraryDocument = Library.GetLibraryContents( ActiveLibrary, App.Engine.LoggedUser );
            LibraryDocument.Changed += OnLibraryDocumentChanged;

            ChangedContent = Library.GetChangedContent( ActiveLibrary, App.Engine.LoggedUser );

            LibraryId = LibraryDocument.Root.Attribute( NedNodeIdAttribute ).Value;

            var mediaItemsQuery =
                from nedNodeElements in LibraryDocument.Descendants( NedNodeTag )
                from nedNodeChildren in nedNodeElements.Element( NedNodeChildrenTag ).Elements()
                where (string)nedNodeElements.Attribute( NedNodeTypeAttribute ) == CategoryTagType
                select new MediaItemsListModelItem()
                {
                    Id = nedNodeChildren.Attribute( NedNodeIdAttribute ).Value,
                    LibraryId = this.LibraryId,
                    ParentId = nedNodeElements.Attribute( NedNodeIdAttribute ).Value,
                    Title = nedNodeChildren.Element( TitleTag ).Value,
                    FileName = nedNodeChildren.Attribute( NedNodeDataAttribute ) != null ? nedNodeChildren.Attribute( NedNodeDataAttribute ).Value : String.Empty,
                    ItemType = MediaItemsListModelItem.GetTypeFromString( nedNodeChildren.Attribute( NedNodeTypeAttribute ).Value ),
                    Description = nedNodeChildren.Element( NedNodeDescriptionTag ) != null ? nedNodeChildren.Element( NedNodeDescriptionTag ).Value : String.Empty,
                    ExternalLinks = ( from linkElement in nedNodeChildren.Elements( NedNodeLinkTag ) select linkElement.Value ).ToList(),
                    Keywords = ( from keywordElement in nedNodeChildren.Elements( NedNodeKeywordTag ) select keywordElement.Value ).ToList(),
                    IsChanged = ChangedContent != null ? ( from changedElements in ChangedContent.Root.Descendants( NedNodeTag )
                                                           where changedElements.Attribute( NedNodeIdAttribute ).Value == nedNodeChildren.Attribute( NedNodeIdAttribute ).Value
                                                           select changedElements ).Count() > 0 : false
                };
            ObservableCollection<MediaItemsListModelItem> AllMediaItemsTemp = new ObservableCollection<MediaItemsListModelItem>();
            foreach( MediaItemsListModelItem item in mediaItemsQuery )
            { // To avoid multiple observers notifications on initialization
                AllMediaItemsTemp.Add( item );
            }
            MediaItems = AllMediaItemsTemp;

            var categoryItemsQuery =
                from nedNodeElements in LibraryDocument.Descendants( NedNodeTag )
                from nedNodeChildren in nedNodeElements.Element( NedNodeChildrenTag ).Elements()
                where (string)nedNodeElements.Attribute( NedNodeTypeAttribute ) == CatalogueTagType
                select new CategoryModelItem()
                {
                    Id = nedNodeChildren.Attribute( NedNodeIdAttribute ).Value,
                    ParentId = nedNodeElements.Attribute( NedNodeIdAttribute ).Value,
                    Title = nedNodeChildren.Element( TitleTag ).Value,
                    IsChanged = ChangedContent != null ? ( from changedElements in ChangedContent.Root.Descendants( NedNodeTag )
                                                           where changedElements.Attribute( NedNodeIdAttribute ).Value == nedNodeChildren.Attribute( NedNodeIdAttribute ).Value
                                                           select changedElements ).Count() > 0 : false
                };
            ObservableCollection<CategoryModelItem> AllCategoryItemsTemp = new ObservableCollection<CategoryModelItem>();
            foreach( CategoryModelItem item in categoryItemsQuery )
            { // To avoid multiple observers notifications on initialization
                AllCategoryItemsTemp.Add( item );
            }
            CategoryItems = AllCategoryItemsTemp;
            foreach( CategoryModelItem catItem in CategoryItems )
            {
                catItem.AddChildren( ( from catChild in MediaItems where catChild.ParentId == catItem.Id select catChild ).ToList() );
            }

            var catalogueItemsQuery =
                from nedNodeElements in LibraryDocument.Descendants( NedNodeTag )
                from nedNodeChildren in nedNodeElements.Element( NedNodeChildrenTag ).Elements()
                where (string)nedNodeElements.Attribute( NedNodeTypeAttribute ) == LibraryTagType
                select new CatalogueModelItem()
                {
                    Id = nedNodeChildren.Attribute( NedNodeIdAttribute ).Value,
                    ParentId = nedNodeElements.Attribute( NedNodeIdAttribute ).Value,
                    Title = nedNodeChildren.Element( TitleTag ).Value,
                    Subtitle = CatalogueModelItem.GetSubtitleString( nedNodeChildren.Element( NedNodeChildrenTag ).Elements().Count<XElement>() ),
                    IsChanged = ChangedContent != null ? ( from changedElements in ChangedContent.Root.Descendants( NedNodeTag )
                                                           where changedElements.Attribute( NedNodeIdAttribute ).Value == nedNodeChildren.Attribute( NedNodeIdAttribute ).Value
                                                           select changedElements ).Count() > 0 : false
                };
            ObservableCollection<CatalogueModelItem> CatalogueItemsTemp = new ObservableCollection<CatalogueModelItem>();
            foreach( CatalogueModelItem item in catalogueItemsQuery )
            { // To avoid multiple observers notifications on initialization
                CatalogueItemsTemp.Add( item );
            }
            CatalogueItems = CatalogueItemsTemp;
            CatalogueItems.CollectionChanged += OnCatalogueItemsPropertyChanged;

            LibraryName = LibraryDocument.Root.Element( TitleTag ).Value;
            UpdateMediaItemsDownloadedStatus();

            return LibraryId;
        }
 public static XDocument GetChangedContent(Library library, User user)
 {
     using (IsolatedStorageFile appDirectory = IsolatedStorageFile.GetUserStoreForApplication())
     {
         if (appDirectory.FileExists(Utils.LibraryXmlDiffPath(user, library)))
         {
             using (var stream = appDirectory.OpenFile(Utils.LibraryXmlDiffPath(user, library), FileMode.Open, FileAccess.Read))
             {
                 return XDocument.Load(stream);
             }
         }
         return null;
     }
 }