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);
        }
        public async Task <ClassCache> LoadCache(DateTime startOfWeek, string accountId)
        {
            if (IsTestAccount)
            {
                return(LoadTestCache());
            }

            string path = GetCacheFilePath(accountId, startOfWeek);

            return(await System.Threading.Tasks.Task.Run(() =>
            {
                if (!File.Exists(path))
                {
                    return null;
                }
                try
                {
                    ClassCache ret = JsonConvert.DeserializeObject <ClassCache>(File.ReadAllText(path));
                    ret.Path = new FileInfo(path);
                    return ret;
                }
                catch (JsonException)
                {
                    File.Delete(path);
                    return null;
                }
            }));
        }
        private async System.Threading.Tasks.Task DeleteAppointmentFromExchange(ClassCache oldCache)
        {
            CalendarFolder calendarFolder = null;

            for (int i = 0; i < 3; i++)
            {
                if (calendarFolder != null)
                {
                    break;
                }
                try
                {
                    calendarFolder = await CalendarFolder.Bind(Service, WellKnownFolderName.Calendar);
                }
                catch (ServiceRequestException) { }

                await System.Threading.Tasks.Task.Delay(50);
            }

            int attempt = 0;

            // Delete appointment from calendar
            CalendarView calendarView = new CalendarView(oldCache.StartOfWeek, oldCache.GetEndDayOfWeek());

            for (int i = 0; i < oldCache.ClassList.Count;)
            {
                if (attempt >= 3)
                {
#if DEBUG
                    System.Console.WriteLine("DEBUG - Too many delete attempts failed");
#endif
                    attempt = 0;
                    i++;
                    continue;
                }

                try
                {
                    Class       cls     = oldCache.ClassList[i];
                    Appointment appoint = await Appointment.Bind(Service, cls.AppointmentId);

                    appoint?.Delete(DeleteMode.SoftDelete);

                    attempt = 0;
                    i++;
#if DEBUG
                    System.Console.WriteLine("DEBUG - Deleted appointment {0}", cls.ModuleCode);
#endif
                }
                catch (ServiceRequestException)
                {
                    attempt++;
#if DEBUG
                    System.Console.WriteLine("DEBUG - Delete failed, attempt: ", attempt);
#endif
                }

                await System.Threading.Tasks.Task.Delay(50); // Avoid timeout execption
            }
        }
        /// <summary>
        /// Compare provided class list and local cache to determin which one has the latest class list, then update to calendar.
        /// </summary>
        /// <param name="table">Provided class list</param>
        /// <param name="cache">Local cache</param>
        /// <param name="startOfWeek">Start date of the week</param>
        /// <param name="accountId">XJTLU Account Portal Internal ID</param>
        /// <param name="reminderIndex">Seleted reminder index</param>
        /// <returns>The updated cache with latest class list</returns>
        private async Task <ClassCache> UpdateTimetableInternal(List <Class> table, ClassCache cache, DateTime startOfWeek, string accountId, int reminderIndex)
        {
            ClassCache ret  = cache;
            bool       flag = false; // need to update

            if (ret != null)
            {
                if (!ret.IsLatestCache(table, reminderIndex))
                {
                    flag = true;

                    ret.ClassList = table;
                    ret.ReminderSelectionIndex = reminderIndex;
                }
            }
            else
            {
                flag = true;
                ret  = new ClassCache(startOfWeek, table, new FileInfo(GetCacheFilePath(accountId, startOfWeek)));
                ret.ReminderSelectionIndex = reminderIndex;
            }

            // Add appointment to calendar
            if (flag)
            {
                await ExportToExchangeCalendar(table, reminderIndex);

                await ret.SaveCache();
            }

            return(ret);
        }
        // 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 async Task <List <Class> > LoadClassListFromCache(DateTime startOfWeek, string accountId, int weekCount = _DefaultWeekCount)
        {
            List <Class> ret   = new List <Class>();
            DateTime     start = startOfWeek;

            for (int i = 0; i < weekCount; i++)
            {
                ClassCache cache = await LoadCache(start, accountId);

                if (cache != null)
                {
                    ret.AddRange(cache.ClassList);
                }
            }
            return(ret);
        }
Esempio n. 7
0
 public static DateTime GetEndDayOfWeek(this ClassCache classCache)
 {
     return(classCache.StartOfWeek.AddDays(6));
 }