using GUTSchedule.Models; using GUTSchedule.UWP.Controls; using System; using Windows.Security.Credentials; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Windows.UI.Popups; using System.Threading.Tasks; using Windows.ApplicationModel.Resources; using Windows.Storage; using Microsoft.Services.Store.Engagement; using Windows.ApplicationModel; using Windows.ApplicationModel.Core; namespace GUTSchedule.UWP.Pages { public sealed partial class MainPage : Page { private readonly PasswordVault vault = new PasswordVault(); private readonly ResourceLoader resources = ResourceLoader.GetForCurrentView(); static readonly ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; private List<(string, string)> _availableOccupations; private List<(string, string)> AvailableOccupations { get => _availableOccupations; set { _availableOccupations = value; applyForOccupation.Visibility = value.Count > 0 ? Visibility.Visible : Visibility.Collapsed; } } public MainPage() => InitializeComponent(); private async void Page_Loaded(object sender, RoutedEventArgs args) { try { PackageVersion ver = Package.Current.Id.Version; version.Text = $"v{ver.Major}.{ver.Minor}.{ver.Build}.{ver.Revision}"; authorize.IsChecked = (bool?)settings.Values["Authorize"] ?? true; if (vault.RetrieveAll() is IReadOnlyList credentials && credentials.Count > 0) { email.Text = credentials.First().UserName; credentials.First().RetrievePassword(); password.Password = credentials.First().Password; } rememberCredential.IsChecked = (bool?)settings.Values["RememberCredential"] ?? true; faculty.ItemsSource = (await Parser.GetFaculties()).Select(i => new ComboBoxItem { Content = i.name, Tag = i.id, IsSelected = (string)settings.Values["Faculty"] == i.id }).ToList(); faculty.SelectedIndex = (faculty.ItemsSource as List).FindIndex(i => i.IsSelected); if (faculty.SelectedIndex < 0) faculty.SelectedIndex = 0; course.SelectedIndex = (int?)settings.Values["Course"] ?? 0; startDate.Date = DateTime.Today; endDate.Date = startDate.Date.Value.AddDays(6); reminder.SelectedIndex = (int?)settings.Values["Reminder"] ?? 2; addGroupToTitle.IsChecked = (bool?)settings.Values["AddGroupToTitle"] ?? false; try { AvailableOccupations = await Parser.CheckAvailableOccupations(email.Text, password.Password); } catch { AvailableOccupations = new List<(string, string)>(); } } catch (HttpRequestException e) { PushInternetExceptionMessage(e, () => Page_Loaded(sender, args)); return; } catch (Exception e) { MessageDialog dialog = new MessageDialog(e.Message, e.GetType().ToString()); dialog.Commands.Add(new UICommand("OK", (command) => CoreApplication.Exit())); await dialog.ShowAsync(); } } private async void AppBarButton_Click(object sender, RoutedEventArgs e) { switch (((FrameworkElement)sender).Tag) { case "clear": ClearCalendarControl clearControl = new ClearCalendarControl(); ContentDialogResult result = await clearControl.ShowAsync(); if(result == ContentDialogResult.Primary) { await Calendar.Clear(clearControl.SelectedCalendars, clearControl.ClearUpcomingOnly); await new MessageDialog(resources.GetString("clearScheduleDone"), resources.GetString("clearScheduleTitle/Title")).ShowAsync(); } break; case "about": Frame.Navigate(typeof(AboutPage)); break; case "report": if (StoreServicesFeedbackLauncher.IsSupported()) await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync(); else await Launcher.LaunchUriAsync(new Uri("mailto:feedback@xfox111.net")); break; } } private void ChangeAuthorizationMethod(object sender, RoutedEventArgs e) { if (credentialMethod == null) return; if (authorize.IsChecked.Value) { credentialMethod.Visibility = Visibility.Visible; defaultMethod.Visibility = Visibility.Collapsed; } else { credentialMethod.Visibility = Visibility.Collapsed; defaultMethod.Visibility = Visibility.Visible; } settings.Values["Authorize"] = authorize.IsChecked; } private void SetTodayDate(object sender, RoutedEventArgs e) => startDate.Date = DateTime.Today; private void SetEndDate(object sender, RoutedEventArgs e) => endDate.Date = startDate.Date.Value.AddDays(int.Parse(((FrameworkElement)sender).Tag as string)); private void SetForSemester(object sender, RoutedEventArgs e) { if (DateTime.Today.Month == 1) endDate.Date = new DateTime(DateTime.Today.Year, 1, 31); else if (DateTime.Today.Month > 8) endDate.Date = new DateTime(DateTime.Today.Year + 1, 1, 31); else endDate.Date = new DateTime(DateTime.Today.Year, 8, 31); } private async void Export(object sender, RoutedEventArgs args) { errorPlaceholder.Visibility = Visibility.Collapsed; if (startDate.Date > endDate.Date) { errorPlaceholder.Text = resources.GetString("invalidDateRangeError"); errorPlaceholder.Visibility = Visibility.Visible; return; } ExportParameters exportParameters; if (authorize.IsChecked.Value) { if (string.IsNullOrWhiteSpace(email.Text) || string.IsNullOrWhiteSpace(password.Password)) { errorPlaceholder.Text = resources.GetString("invalidAuthorizationError"); errorPlaceholder.Visibility = Visibility.Visible; return; } exportParameters = new CabinetExportParameters { Email = email.Text, Password = password.Password, EndDate = endDate.Date.Value.DateTime, StartDate = startDate.Date.Value.DateTime }; if (rememberCredential.IsChecked.Value) vault.Add(new PasswordCredential { UserName = email.Text, Password = password.Password, Resource = "xfox111.gutschedule" }); else foreach (PasswordCredential credential in vault.RetrieveAll()) vault.Remove(credential); } else { if (group.Items.Count < 1) { errorPlaceholder.Text = resources.GetString("groupSelectionError"); errorPlaceholder.Visibility = Visibility.Visible; return; } exportParameters = new DefaultExportParameters { EndDate = endDate.Date.Value.DateTime, StartDate = startDate.Date.Value.DateTime, Course = (course.SelectedIndex + 1).ToString(), FacultyId = ((ComboBoxItem)faculty.SelectedItem).Tag as string, GroupId = ((ComboBoxItem)group.SelectedItem).Tag as string }; } loading.Visibility = Visibility.Visible; TopAppBar.Visibility = Visibility.Collapsed; try { status.Text = resources.GetString("loadingStatus"); List schedule = await Parser.GetSchedule(exportParameters); status.Text = resources.GetString("calendarExportStatus"); await Calendar.Export(schedule, addGroupToTitle.IsChecked.Value, (reminder.SelectedIndex - 1) * 5); status.Text = resources.GetString("doneStatus"); await Task.Delay(1000); } catch (HttpRequestException e) { PushInternetExceptionMessage(e, () => Export(sender, args)); return; } catch (Exception e) { MessageDialog dialog = new MessageDialog(e.Message, e.GetType().ToString()); dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed)); await dialog.ShowAsync(); } loading.Visibility = Visibility.Collapsed; TopAppBar.Visibility = Visibility.Visible; } private void Faculty_SelectionChanged(object sender, SelectionChangedEventArgs e) { UpdateGroupsList(); settings.Values["Faculty"] = ((ComboBoxItem)faculty.SelectedItem).Tag; } private void Course_SelectionChanged(object sender, SelectionChangedEventArgs e) { UpdateGroupsList(); settings.Values["Course"] = course.SelectedIndex; } private void Reminder_SelectionChanged(object sender, SelectionChangedEventArgs e) => settings.Values["Reminder"] = reminder.SelectedIndex; private void Group_SelectionChanged(object sender, SelectionChangedEventArgs e) { if(group.SelectedItem != null) settings.Values["Group"] = ((ComboBoxItem)group.SelectedItem).Tag; } private void RememberCredential_Checked(object sender, RoutedEventArgs e) { settings.Values["RememberCredential"] = rememberCredential.IsChecked; if(!rememberCredential.IsChecked.Value) foreach (PasswordCredential credential in vault.RetrieveAll()) vault.Remove(credential); } private void AddGroupToTitle_Checked(object sender, RoutedEventArgs e) => settings.Values["AddGroupToTitle"] = rememberCredential.IsChecked; private async void UpdateGroupsList() { List<(string id, string name)> groups = await Parser.GetGroups(((ComboBoxItem)faculty.SelectedItem).Tag as string, (course.SelectedIndex + 1).ToString()); group.ItemsSource = groups.Select(i => new ComboBoxItem { Content = i.name, Tag = i.id, IsSelected = (string)settings.Values["Group"] == i.id }).ToList(); group.SelectedIndex = (group.ItemsSource as List).FindIndex(i => i.IsSelected); if (group.SelectedIndex < 0) group.SelectedIndex = 0; } public async void PushInternetExceptionMessage(HttpRequestException e, Action retryAction) { MessageDialog dialog = new MessageDialog(resources.GetString("connectionFailMessage"), e.Message); dialog.Commands.Add(new UICommand(resources.GetString("repeat"), (command) => retryAction())); dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed)); dialog.CancelCommandIndex = 1; dialog.DefaultCommandIndex = 0; await dialog.ShowAsync(); } private async void ValidateCredential(object sender, RoutedEventArgs e) { try { validateCredential.IsEnabled = false; await Parser.VaildateAuthorization(email.Text, password.Password); if (rememberCredential.IsChecked.Value) vault.Add(new PasswordCredential { UserName = email.Text, Password = password.Password, Resource = "xfox111.gutschedule" }); else foreach (PasswordCredential credential in vault.RetrieveAll()) vault.Remove(credential); AvailableOccupations = await Parser.CheckAvailableOccupations(email.Text, password.Password); await new MessageDialog(resources.GetString("validationSuccess")).ShowAsync(); } catch (Exception ex) { await new MessageDialog($"{resources.GetString("validationFailed")}\n{ex.Message}").ShowAsync(); } validateCredential.IsEnabled = true; } private async void ApplyForLesson(object sender, RoutedEventArgs e) { try { applyForOccupation.Visibility = Visibility.Collapsed; AvailableOccupations = await Parser.CheckAvailableOccupations(email.Text, password.Password); await Parser.ApplyForOccupations(email.Text, password.Password, AvailableOccupations); await new MessageDialog(resources.GetString("attendSuccess")).ShowAsync(); } catch (Exception ex) { await new MessageDialog($"{resources.GetString("attendFailed")}\n{ex.Message}").ShowAsync(); applyForOccupation.Visibility = Visibility.Visible; } } } }