public async Task <(bool TokenExpired, List <ClassCache> classCaches)> UpdateTimetable(string accountId, string token, int reminderIndex, int weekCount = _DefaultWeekCount)
        {
            DateTime          startOfWeek = WeekHelper.GetStartDayOfWeek();
            DateTime          endOfWeek   = startOfWeek.AddDays(WeekHelper.Interval_EndOfWeek);
            List <ClassCache> caches      = new List <ClassCache>();

            for (int i = 0; i < weekCount; i++)
            {
                var result = await GetTimetable(startOfWeek, endOfWeek, accountId, token);

                if (result.TokenExpired)
                {
                    return(true, null);
                }

                ClassCache cache = await LoadCache(startOfWeek, accountId);

                if (result.Classes != null)
                {
                    cache = await UpdateTimetableInternal(result.Classes, cache, startOfWeek, accountId, reminderIndex);
                }
                caches.Add(cache);

                startOfWeek = startOfWeek.AddDays(WeekHelper.Interval_StartOfNextWeek);
                endOfWeek   = endOfWeek.AddDays(WeekHelper.Interval_StartOfNextWeek);
            }

            return(false, caches);
        }
        // To meet the Microsoft Store submission requirement.
        public static ClassCache LoadTestCache()
        {
            ClassCache ret      = new ClassCache(WeekHelper.GetStartDayOfWeek(), new List <Class>(), new FileInfo("test.json"));
            DateTime   baseTime = WeekHelper.GetStartDayOfWeek().AddDays(WeekHelper.Interval_StartOfNextWeek).AddHours(9);

            ret.ClassList.Add(new Class
            {
                ModuleCode = "EAP021",
                Location   = "Foundation Building-FB321",
                StartTime  = baseTime,
                EndTime    = baseTime.AddHours(2)
            });
            ret.ClassList.Add(new Class
            {
                ModuleCode = "MTH013",
                Location   = "Science Building Block B-SB222",
                StartTime  = baseTime.AddDays(1).AddHours(6),
                EndTime    = baseTime.AddDays(1).AddHours(8)
            });
            ret.ClassList.Add(new Class
            {
                ModuleCode = "CSE001",
                Location   = "Science Building Block A-SA101",
                StartTime  = baseTime.AddDays(2).AddHours(2),
                EndTime    = baseTime.AddDays(2).AddHours(4)
            });
            ret.ClassList.Add(new Class
            {
                ModuleCode = "EAP021",
                Location   = "Foundation Building-FB321",
                StartTime  = baseTime.AddDays(3).AddHours(2),
                EndTime    = baseTime.AddDays(3).AddHours(4)
            });
            ret.ClassList.Add(new Class
            {
                ModuleCode = "MTH013",
                Location   = "Science Building Block B-SB222",
                StartTime  = baseTime.AddDays(3).AddHours(6),
                EndTime    = baseTime.AddDays(3).AddHours(8)
            });
            ret.ClassList.Add(new Class
            {
                ModuleCode = "MTH007",
                Location   = "Science Building Block D-SD325",
                StartTime  = baseTime.AddDays(4).AddHours(2),
                EndTime    = baseTime.AddDays(4).AddHours(4)
            });
            return(ret);
        }
 public static string GetCacheFileName(string accountId, DateTime startOfWeek)
 {
     return(string.Format(@"cache\{0}\timetable-{1}.json", accountId, WeekHelper.GetDateStr(startOfWeek)));
 }
        private async Task <(bool TokenExpired, List <Class> Classes)> GetTimetable(DateTime from, DateTime to, string accountId, string token)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    // Get timetable
                    string _url = "http://portalapp.xjtlu.edu.cn/edu-app/api/userTimeTable/findStudentsTimeTablesById?userId={0}&userType=S&fromDate={1}&toDate={2}";
                    client.DefaultRequestHeaders.Add("Authorization", token);
                    HttpResponseMessage response = await client.GetAsync(string.Format(_url, accountId, WeekHelper.GetDateStr(from), WeekHelper.GetDateStr(to)));

                    if (response.StatusCode == System.Net.HttpStatusCode.Forbidden)
                    {
                        return(true, null);
                    }
                    if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    {
                        return(false, null);
                    }
                    string responseStr = await response.Content.ReadAsStringAsync();

                    JObject rootObj = JObject.Parse(responseStr);
                    return(false, rootObj["data"]["timeTables"].ToObject <List <Class> >());
                }
            }
            catch
            {
                return(false, null);
            }
        }