Beispiel #1
0
        /// <summary>
        /// Saves QuizAccessTimes and QuizIdentities to the progress data file.
        /// </summary>
        public static void SaveQuizAccessData()
        {
            Directory.CreateDirectory(APP_CFG_DIR);

            QuizProgressDataRoot dataRoot;
            string dataRaw;

            if (File.Exists(ConfigManager.Config.StorageConfig.QuizProgressFile))
            {
                dataRaw  = AtomicIO.AtomicRead(ConfigManager.Config.StorageConfig.QuizProgressFile);
                dataRoot = JsonConvert.DeserializeObject <QuizProgressDataRoot>(dataRaw);

                if (dataRoot.FileFormatVersion == null || new Version(dataRoot.FileFormatVersion).CompareTo(MetaData.GetLatestQuizVersion()) < 0)
                {
                    // Existing quiz file has an older file format - backup before upgrade
                    BackupProgress();
                }

                dataRoot.FileFormatVersion = MetaData.QUIZ_FILE_FORMAT_VERSION;
            }
            else
            {
                dataRoot = new QuizProgressDataRoot(MetaData.QUIZ_FILE_FORMAT_VERSION);
            }

            dataRoot.QuizAccessTimes = QuizAccessTimes;
            dataRoot.QuizIdentities  = QuizIdentities;

#if DEBUG
            dataRaw = JsonConvert.SerializeObject(dataRoot, Formatting.Indented);
#else
            dataRaw = JsonConvert.SerializeObject(dataRoot);
#endif
            AtomicIO.AtomicWrite(ConfigManager.Config.StorageConfig.QuizProgressFile, dataRaw);
        }
Beispiel #2
0
        /// <summary>
        /// Merges two QuizProgDataRoots into one, by adding all quiz progress datas into one. If duplicates exist, the one with best progress will be selected.
        /// If same, progressFile1 will have priority
        /// </summary>
        /// <param name="progressFile1">The path to the first quiz progress data file. This one has priority over progressFile2</param>
        /// <param name="progressFile2">The path to the second quiz progress data file.</param>
        /// <param name="savePath">The path where the merged file should be saved</param>
        /// <returns>True if the merge was successful, otherwise false</returns>
        public static bool Merge(string progressFile1, string progressFile2, string savePath)
        {
            BackupHelper.BackupFile(progressFile1, Path.Combine(Path.GetDirectoryName(progressFile1), "SteelQuiz Progress Backups"), false);
            BackupHelper.BackupFile(progressFile2, Path.Combine(Path.GetDirectoryName(progressFile2), "SteelQuiz Progress Backups"), false);
            if (File.Exists(savePath) && savePath != progressFile1 && savePath != progressFile2)
            {
                BackupHelper.BackupFile(savePath, Path.Combine(Path.GetDirectoryName(savePath), "SteelQuiz Progress Backups"));
            }

            QuizProgressDataRoot prog1;
            QuizProgressDataRoot prog2;

            try
            {
                prog1 = JsonConvert.DeserializeObject <QuizProgressDataRoot>(AtomicIO.AtomicRead(progressFile1));

                prog2 = JsonConvert.DeserializeObject <QuizProgressDataRoot>(AtomicIO.AtomicRead(progressFile2));
            }
            catch (AtomicException ex)
            {
                MessageBox.Show("Could not load progress data files:\r\n\r\n" + ex.ToString(), "SteelQuiz", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            QuizProgressDataRoot merged = Merge(prog1, prog2);

#if DEBUG
            AtomicIO.AtomicWrite(savePath, JsonConvert.SerializeObject(merged, Formatting.Indented));
#else
            AtomicIO.AtomicWrite(savePath, JsonConvert.SerializeObject(merged));
#endif

            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Saves the quiz progress data contained in the specified quiz.
        /// </summary>
        /// <param name="quiz">The Quiz object containing the progress data</param>
        public static void SaveQuizProgress(Quiz quiz)
        {
            string dataRaw  = AtomicIO.AtomicRead(ConfigManager.Config.StorageConfig.QuizProgressFile);
            var    dataRoot = JsonConvert.DeserializeObject <QuizProgressDataRoot>(dataRaw);

            if (dataRoot.FileFormatVersion == null || new Version(dataRoot.FileFormatVersion).CompareTo(MetaData.GetLatestQuizVersion()) < 0)
            {
                // Existing quiz file has an older file format - backup before upgrade
                BackupProgress();
            }

            dataRoot.FileFormatVersion = MetaData.QUIZ_FILE_FORMAT_VERSION;

            var data = dataRoot.QuizProgressData.Where(x => x.QuizGUID == quiz.GUID).FirstOrDefault();

            if (data != null)
            {
                dataRoot.QuizProgressData[dataRoot.QuizProgressData.IndexOf(data)] = quiz.ProgressData;
            }
            else
            {
                dataRoot.QuizProgressData.Add(quiz.ProgressData);
            }

#if DEBUG
            dataRaw = JsonConvert.SerializeObject(dataRoot, Formatting.Indented);
#else
            dataRaw = JsonConvert.SerializeObject(dataRoot);
#endif
            AtomicIO.AtomicWrite(ConfigManager.Config.StorageConfig.QuizProgressFile, dataRaw);
        }
Beispiel #4
0
        /// <summary>
        /// Retrieves the quiz progress data object for the specified quiz.
        /// </summary>
        /// <param name="quiz">The quiz whose quiz progress data to load.</param>
        /// <returns>The QuizProgData object belonging to the quiz.</returns>
        private static QuizProgress LoadQuizProgressData(Quiz quiz)
        {
            string dataRaw  = AtomicIO.AtomicRead(ConfigManager.Config.StorageConfig.QuizProgressFile);
            var    dataRoot = JsonConvert.DeserializeObject <QuizProgressDataRoot>(dataRaw);

            var progress = dataRoot.QuizProgressData.Where(x => x.QuizGUID == quiz.GUID).FirstOrDefault();

            if (progress != null)
            {
                // Remove cards from CurrentCards that has been deleted from the quiz
                progress.CurrentCards = progress.CurrentCards.Where(x => quiz.Cards.Select(y => y.Guid).Contains(x)).ToList();

                // Remove progress from cards that have been removed from the quiz
                progress.CardProgress = progress.CardProgress.Where(x => quiz.Cards.Select(y => y.Guid).Contains(x.CardGuid)).ToList();

                // Issue #45 fix - "Learning Progress still 100 % after adding card to quiz without having answered it"
                foreach (var card in quiz.Cards)
                {
                    if (!progress.CardProgress.Select(x => x.CardGuid).Contains(card.Guid))
                    {
                        // CardProgress does not exist for card, create it
                        progress.CardProgress.Add(new CardProgress(card.Guid));
                    }
                }
            }

            return(progress);
        }
Beispiel #5
0
        /// <summary>
        /// Loads QuizAccessTimes and QuizIdentities from the progress data file.
        /// </summary>
        public static void LoadQuizAccessData()
        {
            if (!File.Exists(ConfigManager.Config.StorageConfig.QuizProgressFile))
            {
                return;
            }

            string dataRaw  = AtomicIO.AtomicRead(ConfigManager.Config.StorageConfig.QuizProgressFile);
            var    dataRoot = JsonConvert.DeserializeObject <QuizProgressDataRoot>(dataRaw);

            QuizAccessTimes = dataRoot.QuizAccessTimes;
            QuizIdentities  = dataRoot.QuizIdentities;
        }
Beispiel #6
0
        private static Quiz InternalLoadQuiz(string path)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException("Quiz file does not exist!");
            }

            string quizRaw = AtomicIO.AtomicRead(path);
            Quiz   quiz    = JsonConvert.DeserializeObject <Quiz>(quizRaw);

            Version quizVersion;

            if (quiz.FileFormatVersion == null)
            {
                quizVersion = null;
            }
            else
            {
                quizVersion = new Version(quiz.FileFormatVersion);
            }

            quiz.FileFormatVersion = MetaData.QUIZ_FILE_FORMAT_VERSION;

            if (quizVersion != null && quizVersion.CompareTo(MetaData.GetLatestQuizVersion()) > 0)
            {
                throw new VersionNotSupportedException(VersionNotSupportedException.NotSupportedReason.AppVersionTooOld);
            }

            quiz.QuizIdentity = new QuizIdentity(quiz.GUID, path);
            quiz.ProgressData = LoadQuizProgressData(quiz);

            if (quiz.ProgressData == null)
            {
                // Progress data for quiz does not exist - create new
                quiz.ProgressData = new QuizProgress(quiz);
            }

            QuizIdentities[quiz.GUID]  = quiz.QuizIdentity;
            QuizAccessTimes[quiz.GUID] = DateTime.Now;

            SaveQuizAccessData();

            if (quizVersion.CompareTo(new Version(4, 0, 0, 1)) < 0)
            {
                SaveQuiz(quiz, path);
            }

            return(quiz);
        }
Beispiel #7
0
        public static bool LoadConfig()
        {
            Directory.CreateDirectory(QuizCore.APP_CFG_DIR);

            if (!File.Exists(CONFIG_FILE))
            {
                Config = new Config();
                SaveConfig();
                return(true);
            }

            bool corrupt = false;

            try
            {
                Config = JsonConvert.DeserializeObject <Config>(AtomicIO.AtomicRead(CONFIG_FILE));
            }
            catch (AtomicException)
            {
                corrupt = true;
            }

            if (Config == null)
            {
                corrupt = true;
            }

            if (corrupt)
            {
                var msg = MessageBox.Show("The configuration file for SteelQuiz is corrupt, and must be reset. Reset configuration?", "SteelQuiz", MessageBoxButtons.YesNo,
                                          MessageBoxIcon.Error);
                if (msg == DialogResult.Yes)
                {
                    BackupConfig();
                    File.Delete(CONFIG_FILE);
                    return(LoadConfig());
                }
                else
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #8
0
        private void bgw_quizSearcher_DoWork(object sender, DoWorkEventArgs e)
        {
            foreach (var searchDir in GetSearchDirs())
            {
                try
                {
                    foreach (var file in Directory.EnumerateFiles(searchDir.Path, $"*.{QuizCore.QUIZ_EXTENSION}",
                                                                  searchDir.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                    {
                        if (bgw_quizSearcher.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }

                        string rawQuiz;
                        try
                        {
                            rawQuiz = AtomicIO.AtomicRead(file);
                        }
                        catch (AtomicException)
                        {
                            continue;
                        }
                        var quiz = JsonConvert.DeserializeObject <Quiz>(rawQuiz);

                        if (quiz != null && quiz.GUID == QuizGuid)
                        {
                            NewQuizPath = file;
                            break;
                        }
                    }
                }
                catch
                {
                    continue;
                }
            }
        }
Beispiel #9
0
        private void btn_specifyManually_Click(object sender, EventArgs e)
        {
            if (ofd_quiz.ShowDialog() == DialogResult.OK)
            {
                string rawQuiz = null;
                try
                {
                    rawQuiz = AtomicIO.AtomicRead(ofd_quiz.FileName);
                }
                catch (AtomicException ex)
                {
                    MessageBox.Show("Could not read file:\r\n" + ex.ToString(), "Atomic Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                var quiz = JsonConvert.DeserializeObject <Quiz>(rawQuiz);
                if (quiz.GUID == QuizGuid)
                {
                    NewQuizPath = ofd_quiz.FileName;

                    if (bgw_quizSearcher.IsBusy)
                    {
                        bgw_quizSearcher.CancelAsync();
                    }
                    else
                    {
                        DialogResult = DialogResult.OK;
                    }
                }
                else
                {
                    MessageBox.Show("The selected quiz is not the right one. SteelQuiz is looking for the following quiz:\r\n\r\n" +
                                    $"Old name: {Path.GetFileNameWithoutExtension(OldQuizPath)}\r\nGuid: {QuizGuid.ToString()}",
                                    "Guid does not match", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
Beispiel #10
0
 public static void SaveConfig()
 {
     Directory.CreateDirectory(QuizCore.APP_CFG_DIR);
     AtomicIO.AtomicWrite(CONFIG_FILE, JsonConvert.SerializeObject(Config, Formatting.Indented));
 }
Beispiel #11
0
        public static void SaveQuiz(Quiz quiz, string path)
        {
            string quizRaw = JsonConvert.SerializeObject(quiz, Formatting.Indented);

            AtomicIO.AtomicWrite(path, quizRaw);
        }