1
0
mirror of https://github.com/XFox111/GUTSchedule.git synced 2026-04-22 06:58:01 +03:00

[1.0.7] Added schedule export for profs

Now export preferences are kept
This commit is contained in:
Michael Gordeev
2020-01-23 21:14:27 +03:00
parent 206f2786ef
commit 217d095174
11 changed files with 509 additions and 146 deletions
@@ -30,6 +30,21 @@ namespace GUT.Schedule
private async void Export() private async void Export()
{ {
try try
{
if(Data.DataSet.HttpClient != null)
{
status.Text = "Загрузка расписания с картофельных серверов Бонча";
List<ProfessorSubject> schedule = new List<ProfessorSubject>();
for (DateTime d = Data.StartDate; int.Parse($"{d.Year}{d.Month:00}") <= int.Parse($"{Data.EndDate.Year}{Data.EndDate.Month:00}"); d = d.AddMonths(1))
schedule.AddRange(await Parser.GetProfessorSchedule(Data.DataSet.HttpClient, d));
schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range
status.Text = "Экспортирование в календарь";
Calendar.Export(schedule);
}
else
{ {
status.Text = "Загрузка расписания"; status.Text = "Загрузка расписания";
List<Subject> schedule = await Parser.LoadSchedule(); List<Subject> schedule = await Parser.LoadSchedule();
@@ -38,7 +53,7 @@ namespace GUT.Schedule
status.Text = "Экспортирование в календарь"; status.Text = "Экспортирование в календарь";
Calendar.Export(schedule); Calendar.Export(schedule);
}
status.Text = "Готово"; status.Text = "Готово";
await Task.Delay(1000); await Task.Delay(1000);
@@ -1,14 +1,18 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.OS; using Android.OS;
using Android.Preferences;
using Android.Support.V4.Text; using Android.Support.V4.Text;
using Android.Support.V7.App; using Android.Support.V7.App;
using Android.Text.Method; using Android.Text.Method;
using Android.Views; using Android.Views;
using Android.Widget; using Android.Widget;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
using GUT.Schedule.Models; using GUT.Schedule.Models;
namespace GUT.Schedule namespace GUT.Schedule
@@ -18,35 +22,64 @@ namespace GUT.Schedule
{ {
Button start, end, export; Button start, end, export;
Button forDay, forWeek, forMonth, forSemester; Button forDay, forWeek, forMonth, forSemester;
Spinner faculty, course, group, reminder, calendar; Spinner faculty, course, group, reminder, calendar, user;
CheckBox groupTitle; CheckBox groupTitle;
TextView error; TextView error;
LinearLayout studentParams, profParams;
EditText email, password;
ISharedPreferences prefs;
protected override void OnCreate(Bundle savedInstanceState) protected override void OnCreate(Bundle savedInstanceState)
{ {
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main); SetContentView(Resource.Layout.activity_main);
prefs = PreferenceManager.GetDefaultSharedPreferences(this);
AssignVariables(); AssignVariables();
faculty.SetList(this, Data.Faculties.Select(i => i.Name));
int s = Data.Faculties.FindIndex(i => i.Id == prefs.GetString("Faculty", "-123"));
faculty.SetSelection(s == -1 ? 0 : s);
course.SetList(this, "1234".ToCharArray());
course.SetSelection(prefs.GetInt("Course", 0)); // IDK why but this shit triggers events anyway (even if they are set in the next line. It seem to be that there's some asynchronous shit somewhere there)
// P.S. Fuck Android
AddEvents(); AddEvents();
// Settings spinners' dropdown lists content // Settings spinners' dropdown lists content
faculty.SetList(this, Data.Faculties.Select(i => i.Name)); user.SetList(this, new[]
course.SetList(this, "1234".ToCharArray()); {
reminder.SetList(this, new string[] "Студент",
"Преподаватель"
});
user.SetSelection(prefs.GetInt("User", 0));
reminder.SetList(this, new[]
{ {
"Нет", "Нет",
"Во время начала", "Во время начала",
"За 5 мин", "За 5 мин",
"За 10 мин" "За 10 мин"
}); });
reminder.SetSelection(prefs.GetInt("Reminder", 0));
calendar.SetList(this, Calendar.Calendars.Select(i => i.Name)); calendar.SetList(this, Calendar.Calendars.Select(i => i.Name));
s = Calendar.Calendars.FindIndex(i => i.Id == prefs.GetString("Calendar", "-123"));
calendar.SetSelection(s == -1 ? 0 : s);
end.Text = Data.EndDate.ToShortDateString(); end.Text = Data.EndDate.ToShortDateString();
start.Text = Data.StartDate.ToShortDateString(); start.Text = Data.StartDate.ToShortDateString();
groupTitle.Checked = prefs.GetBoolean("AddGroupToHeader", false);
email.Text = prefs.GetString("email", "");
password.Text = prefs.GetString("password", "");
} }
private void Export_Click(object sender, EventArgs e) private async void Export_Click(object sender, EventArgs e)
{ {
error.Visibility = ViewStates.Gone; error.Visibility = ViewStates.Gone;
@@ -57,15 +90,82 @@ namespace GUT.Schedule
return; return;
} }
HttpClient client = null;
if(user.SelectedItemPosition == 1)
{
Toast.MakeText(ApplicationContext, "Авторизация...", ToastLength.Short).Show();
if (string.IsNullOrWhiteSpace(email.Text) || string.IsNullOrWhiteSpace(password.Text))
{
error.Text = "Ошибка: Введите корректные учетные данные";
error.Visibility = ViewStates.Visible;
return;
}
export.Enabled = false;
client = new HttpClient();
await client.GetAsync("https://cabs.itut.ru/cabinet/");
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabs.itut.ru/cabinet/lib/autentificationok.php");
request.SetContent(
("users", email.Text),
("parole", password.Text));
HttpResponseMessage response = await client.SendAsync(request);
string responseContent = await response.GetString();
export.Enabled = true;
if (!response.IsSuccessStatusCode)
{
error.Text = $"Ошибка авторизации: {response.StatusCode}: {responseContent}";
error.Visibility = ViewStates.Visible;
return;
}
if (!responseContent.StartsWith("1", StringComparison.OrdinalIgnoreCase))
{
error.Text = $"Ошибка авторизации: Неверный e-mail и/или пароль ({string.Join("; ", responseContent.Replace("error=", "", StringComparison.OrdinalIgnoreCase).Split('|'))})";
error.Visibility = ViewStates.Visible;
return;
}
export.Enabled = false;
HttpResponseMessage verificationResponse = await client.GetAsync("https://cabs.itut.ru/cabinet/?login=yes");
export.Enabled = true;
IHtmlDocument doc = new HtmlParser().ParseDocument(await verificationResponse.GetString());
if (!doc.QuerySelectorAll("nobr").Any(i => i.TextContent.Contains("Ведомости")))
{
error.Text = "Ошибка авторизации: Необходимо авторизоваться с аккаунтом преподавателя";
error.Visibility = ViewStates.Visible;
return;
}
Data.Groups = null;
// According to this SO thread: https://stackoverflow.com/questions/1925486/android-storing-username-and-password
// I consider Preferences as safe enough method for storing credentials
PreferenceManager.GetDefaultSharedPreferences(this).Edit().PutBoolean("email", groupTitle.Checked).Apply();
PreferenceManager.GetDefaultSharedPreferences(this).Edit().PutBoolean("password", groupTitle.Checked).Apply();
}
else
{
if(Data.Groups.Count < 1)
{
error.Text = "Ошибка: Не выбрана группа";
error.Visibility = ViewStates.Visible;
return;
}
}
// Forming export parameters // Forming export parameters
Data.DataSet = new DataSet Data.DataSet = new DataSet
{ {
Faculty = Data.Faculties[faculty.SelectedItemPosition].Id, Faculty = Data.Faculties[faculty.SelectedItemPosition].Id,
Group = Data.Groups[group.SelectedItemPosition].Id, Group = Data.Groups?[group.SelectedItemPosition].Id,
Course = course.SelectedItemPosition + 1, Course = course.SelectedItemPosition + 1,
AddGroupToTitle = groupTitle.Checked, AddGroupToTitle = groupTitle.Checked,
Calendar = Calendar.Calendars[calendar.SelectedItemPosition].Id, Calendar = Calendar.Calendars[calendar.SelectedItemPosition].Id,
Reminder = (reminder.SelectedItemPosition - 1) * 5 Reminder = (reminder.SelectedItemPosition - 1) * 5,
HttpClient = client
}; };
StartActivity(new Intent(this, typeof(ExportActivity))); StartActivity(new Intent(this, typeof(ExportActivity)));
@@ -83,13 +183,16 @@ namespace GUT.Schedule
start.Text = Data.StartDate.ToShortDateString(); start.Text = Data.StartDate.ToShortDateString();
} }
private async void UpdateGroupsList(object sender, AdapterView.ItemSelectedEventArgs e) private async void UpdateGroupsList()
{ {
if (course.SelectedItem == null) if (course.SelectedItem == null)
return; return;
await Parser.LoadGroups(Data.Faculties[faculty.SelectedItemPosition].Id, course.SelectedItemPosition + 1); await Parser.LoadGroups(Data.Faculties[faculty.SelectedItemPosition].Id, course.SelectedItemPosition + 1);
group.SetList(this, Data.Groups.Select(i => i.Name)); group.SetList(this, Data.Groups.Select(i => i.Name));
int s = Data.Groups?.FindIndex(i => i.Id == prefs.GetString("Group", "-123")) ?? 0;
group.SetSelection(s == -1 ? 0 : s);
} }
private void SetDate(int days) private void SetDate(int days)
@@ -115,15 +218,57 @@ namespace GUT.Schedule
group = FindViewById<Spinner>(Resource.Id.group); group = FindViewById<Spinner>(Resource.Id.group);
reminder = FindViewById<Spinner>(Resource.Id.reminder); reminder = FindViewById<Spinner>(Resource.Id.reminder);
calendar = FindViewById<Spinner>(Resource.Id.calendar); calendar = FindViewById<Spinner>(Resource.Id.calendar);
user = FindViewById<Spinner>(Resource.Id.user);
error = FindViewById<TextView>(Resource.Id.error); error = FindViewById<TextView>(Resource.Id.error);
groupTitle = FindViewById<CheckBox>(Resource.Id.groupTitle); groupTitle = FindViewById<CheckBox>(Resource.Id.groupTitle);
studentParams = FindViewById<LinearLayout>(Resource.Id.studentParams);
profParams = FindViewById<LinearLayout>(Resource.Id.professorParams);
email = FindViewById<EditText>(Resource.Id.email);
password = FindViewById<EditText>(Resource.Id.password);
} }
private void AddEvents() private void AddEvents()
{ {
faculty.ItemSelected += UpdateGroupsList; faculty.ItemSelected += (s, e) =>
course.ItemSelected += UpdateGroupsList; {
prefs.Edit().PutString("Faculty", Data.Faculties[e.Position].Id).Apply();
UpdateGroupsList();
};
course.ItemSelected += (s, e) =>
{
prefs.Edit().PutInt("Course", e.Position).Apply();
UpdateGroupsList();
};
user.ItemSelected += (s, e) =>
{
prefs.Edit().PutInt("User", e.Position).Apply();
switch (e.Position)
{
case 0:
studentParams.Visibility = ViewStates.Visible;
groupTitle.Visibility = ViewStates.Visible;
profParams.Visibility = ViewStates.Gone;
break;
case 1:
studentParams.Visibility = ViewStates.Gone;
groupTitle.Visibility = ViewStates.Gone;
profParams.Visibility = ViewStates.Visible;
break;
}
};
calendar.ItemSelected += (s, e) =>
prefs.Edit().PutString("Calendar", Calendar.Calendars[e.Position].Id).Apply();
reminder.ItemSelected += (s, e) =>
prefs.Edit().PutInt("Reminder", e.Position).Apply();
group.ItemSelected += (s, e) =>
prefs.Edit().PutString("Group", Data.Groups[e.Position].Id).Apply();
groupTitle.Click += (s, e) =>
prefs.Edit().PutBoolean("AddGroupToHeader", groupTitle.Checked).Apply();
forDay.Click += (s, e) => SetDate(0); forDay.Click += (s, e) => SetDate(0);
forWeek.Click += (s, e) => SetDate(6); forWeek.Click += (s, e) => SetDate(6);
+47 -3
View File
@@ -46,7 +46,7 @@ namespace GUT.Schedule
foreach (Subject item in schedule) foreach (Subject item in schedule)
{ {
Android.Content.ContentValues eventValues = new Android.Content.ContentValues(); ContentValues eventValues = new ContentValues();
eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, data.Calendar); eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, data.Calendar);
@@ -65,7 +65,7 @@ namespace GUT.Schedule
// For some reason Google calendars ignore HasAlarm = false and set reminder for 30 minutes. Local calendars don't seem to have this issue // For some reason Google calendars ignore HasAlarm = false and set reminder for 30 minutes. Local calendars don't seem to have this issue
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, item.StartTime.ToUnixTime()); eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, item.StartTime.ToUnixTime());
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, Extensions.ToUnixTime(item.EndTime)); eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, item.EndTime.ToUnixTime());
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID); eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID);
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID); eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID);
@@ -76,7 +76,51 @@ namespace GUT.Schedule
// Settings reminder // Settings reminder
if(data.Reminder != -5) if(data.Reminder != -5)
{ {
Android.Content.ContentValues reminderValues = new Android.Content.ContentValues(); ContentValues reminderValues = new ContentValues();
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment));
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, data.Reminder);
Application.Context.ContentResolver.Insert(CalendarContract.Reminders.ContentUri, reminderValues);
}
}
}
public static void Export(IEnumerable<ProfessorSubject> schedule)
{
DataSet data = Data.DataSet;
foreach (ProfessorSubject item in schedule)
{
ContentValues eventValues = new ContentValues();
eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, data.Calendar);
eventValues.Put(CalendarContract.Events.InterfaceConsts.Title, string.Format("{0}. {1} ({2})",
item.Order,
item.Name,
item.Type));
eventValues.Put(CalendarContract.Events.InterfaceConsts.Description, item.Groups);
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventLocation, item.Cabinet);
eventValues.Put(CalendarContract.Events.InterfaceConsts.Availability, 0);
eventValues.Put(CalendarContract.Events.InterfaceConsts.HasAlarm, data.Reminder != -5);
// For some reason Google calendars ignore HasAlarm = false and set reminder for 30 minutes. Local calendars don't seem to have this issue
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, item.StartTime.ToUnixTime());
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, item.EndTime.ToUnixTime());
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID);
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID);
eventValues.Put(CalendarContract.Events.InterfaceConsts.CustomAppPackage, Application.Context.PackageName);
Uri response = Application.Context.ContentResolver.Insert(CalendarContract.Events.ContentUri, eventValues);
// Settings reminder
if(data.Reminder != -5)
{
ContentValues reminderValues = new ContentValues();
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment)); reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment));
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, data.Reminder); reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, data.Reminder);
+22
View File
@@ -1,6 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Android.Content; using Android.Content;
using Android.Widget; using Android.Widget;
@@ -45,5 +48,24 @@ namespace GUT.Schedule
/// <returns><see cref="long"/> which is represented by total milliseconds count passed since 1970</returns> /// <returns><see cref="long"/> which is represented by total milliseconds count passed since 1970</returns>
public static long ToUnixTime(this DateTime dt) => public static long ToUnixTime(this DateTime dt) =>
(long)dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; (long)dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
public static void SetContent(this HttpRequestMessage request, params (string key, string value)[] values)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
Dictionary<string, string> body = new Dictionary<string, string>();
foreach ((string key, string value) in values)
body.Add(key, value);
request.Content = new FormUrlEncodedContent(body);
}
public static async Task<string> GetString(this HttpResponseMessage response)
{
if (response == null)
throw new ArgumentNullException(nameof(response));
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
return Encoding.GetEncoding("Windows-1251").GetString(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
}
} }
} }
@@ -75,6 +75,7 @@
<Compile Include="Extensions.cs" /> <Compile Include="Extensions.cs" />
<Compile Include="Activities\MainActivity.cs" /> <Compile Include="Activities\MainActivity.cs" />
<Compile Include="Models\DataSet.cs" /> <Compile Include="Models\DataSet.cs" />
<Compile Include="Models\ProfessorSubject.cs" />
<Compile Include="Parser.cs" /> <Compile Include="Parser.cs" />
<Compile Include="Resources\Resource.designer.cs" /> <Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
+4 -1
View File
@@ -1,4 +1,6 @@
namespace GUT.Schedule.Models using System.Net.Http;
namespace GUT.Schedule.Models
{ {
public class DataSet public class DataSet
{ {
@@ -8,5 +10,6 @@
public string Group { get; set; } public string Group { get; set; }
public int Reminder { get; set; } public int Reminder { get; set; }
public bool AddGroupToTitle { get; set; } public bool AddGroupToTitle { get; set; }
public HttpClient HttpClient { get; set; }
} }
} }
@@ -0,0 +1,44 @@
using System;
namespace GUT.Schedule.Models
{
public class ProfessorSubject
{
public string Name { get; set; }
public string Type { get; set; }
public string Cabinet { get; set; }
public string Order { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Groups { get; set; }
public ProfessorSubject(string name, string type, string cabinet, string groups, int year, int month, int day, string schedule)
{
Name = name;
Type = type;
Cabinet = cabinet;
Groups = groups;
string[] time = schedule.Split('-');
StartTime = new DateTime(year, month, day, int.Parse(time[0].Split('.')[0]), int.Parse(time[0].Split('.')[1]), 0);
EndTime = new DateTime(year, month, day, int.Parse(time[1].Split('.')[0]), int.Parse(time[1].Split('.')[1]), 0);
Order = time[0] switch
{
"09.00" => "1",
"10.45" => "2",
"13.00" => "3",
"14.45" => "4",
"16.30" => "5",
"18.15" => "6",
"20.00" => "7",
"10.30" => "2", //Расписание для пар по физ-ре
"12.00" => "3",
"13.30" => "4",
"15.00" => "5",
"18.00" => "7",
_ => ""
};
}
}
}
+35 -1
View File
@@ -89,7 +89,6 @@ namespace GUT.Schedule
public static async Task LoadGroups(string facultyId, int course) public static async Task LoadGroups(string facultyId, int course)
{ {
Data.Groups = new List<(string, string)>();
using HttpClient client = new HttpClient(); using HttpClient client = new HttpClient();
Dictionary<string, string> requestBody = new Dictionary<string, string> Dictionary<string, string> requestBody = new Dictionary<string, string>
{ {
@@ -107,6 +106,7 @@ namespace GUT.Schedule
HttpResponseMessage response = await client.SendAsync(request); HttpResponseMessage response = await client.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync(); string responseBody = await response.Content.ReadAsStringAsync();
Data.Groups = new List<(string, string)>();
foreach (string s in responseBody.Split(';')) foreach (string s in responseBody.Split(';'))
try { Data.Groups.Add((s.Split(',')[0], s.Split(',')[1])); } try { Data.Groups.Add((s.Split(',')[0], s.Split(',')[1])); }
catch { } catch { }
@@ -122,5 +122,39 @@ namespace GUT.Schedule
return $"205.{now.Year - 2001}{now.Year - 2000}/2"; return $"205.{now.Year - 2001}{now.Year - 2000}/2";
} }
public static async Task<List<ProfessorSubject>> GetProfessorSchedule(HttpClient client, DateTime date)
{
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabs.itut.ru/cabinet/project/cabinet/forms/pr_raspisanie_kalendar.php");
request.SetContent(
("month", date.Month.ToString()),
("year", date.Year.ToString()),
("type_z", "0"));
HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
string responseContent = await response.GetString().ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(responseContent);
IHtmlDocument doc = new HtmlParser().ParseDocument(responseContent);
List<ProfessorSubject> schedule = new List<ProfessorSubject>();
foreach(var i in doc.QuerySelectorAll("td").Where(i => i.GetAttribute("style") == "text-align: center; vertical-align: top"))
for (int k = 0; k < i.QuerySelectorAll("i").Length; k++)
{
ProfessorSubject item = new ProfessorSubject(
name: i.QuerySelectorAll("b")[k * 2 + 1].TextContent,
type: i.QuerySelectorAll("i")[k].TextContent,
cabinet: i.ChildNodes[k * 13 + 12].TextContent,
groups: i.ChildNodes[k * 13 + 7].TextContent,
year: date.Year,
month: date.Month,
day: int.Parse(i.QuerySelectorAll("b")[0].TextContent),
schedule: i.QuerySelectorAll("b")[k * 2 + 2].TextContent
);
schedule.Add(item);
}
return schedule;
}
} }
} }
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="106" android:versionName="1.0.6" package="com.xfox111.gut.schedule" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="107" android:versionName="1.0.7" package="com.xfox111.gut.schedule" android:installLocation="auto">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28" /> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="ГУТ.Расписание" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"></application> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="ГУТ.Расписание" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"></application>
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.READ_CALENDAR" />
+119 -107
View File
@@ -3590,253 +3590,265 @@ namespace GUT.Schedule
public const int parent_matrix = 2131230844; public const int parent_matrix = 2131230844;
// aapt resource value: 0x7F08007D // aapt resource value: 0x7F08007D
public const int pin = 2131230845; public const int password = 2131230845;
// aapt resource value: 0x7F08007E // aapt resource value: 0x7F08007E
public const int progress_circular = 2131230846; public const int pin = 2131230846;
// aapt resource value: 0x7F08007F // aapt resource value: 0x7F08007F
public const int progress_horizontal = 2131230847; public const int professorParams = 2131230847;
// aapt resource value: 0x7F080080 // aapt resource value: 0x7F080080
public const int radio = 2131230848; public const int progress_circular = 2131230848;
// aapt resource value: 0x7F080081 // aapt resource value: 0x7F080081
public const int reminder = 2131230849; public const int progress_horizontal = 2131230849;
// aapt resource value: 0x7F080082 // aapt resource value: 0x7F080082
public const int right = 2131230850; public const int radio = 2131230850;
// aapt resource value: 0x7F080083 // aapt resource value: 0x7F080083
public const int right_icon = 2131230851; public const int reminder = 2131230851;
// aapt resource value: 0x7F080084 // aapt resource value: 0x7F080084
public const int right_side = 2131230852; public const int right = 2131230852;
// aapt resource value: 0x7F080085 // aapt resource value: 0x7F080085
public const int save_image_matrix = 2131230853; public const int right_icon = 2131230853;
// aapt resource value: 0x7F080086 // aapt resource value: 0x7F080086
public const int save_non_transition_alpha = 2131230854; public const int right_side = 2131230854;
// aapt resource value: 0x7F080087 // aapt resource value: 0x7F080087
public const int save_scale_type = 2131230855; public const int save_image_matrix = 2131230855;
// aapt resource value: 0x7F080088 // aapt resource value: 0x7F080088
public const int screen = 2131230856; public const int save_non_transition_alpha = 2131230856;
// aapt resource value: 0x7F080089 // aapt resource value: 0x7F080089
public const int scroll = 2131230857; public const int save_scale_type = 2131230857;
// aapt resource value: 0x7F08008D
public const int scrollable = 2131230861;
// aapt resource value: 0x7F08008A // aapt resource value: 0x7F08008A
public const int scrollIndicatorDown = 2131230858; public const int screen = 2131230858;
// aapt resource value: 0x7F08008B // aapt resource value: 0x7F08008B
public const int scrollIndicatorUp = 2131230859; public const int scroll = 2131230859;
// aapt resource value: 0x7F08008C
public const int scrollView = 2131230860;
// aapt resource value: 0x7F08008E
public const int search_badge = 2131230862;
// aapt resource value: 0x7F08008F // aapt resource value: 0x7F08008F
public const int search_bar = 2131230863; public const int scrollable = 2131230863;
// aapt resource value: 0x7F08008C
public const int scrollIndicatorDown = 2131230860;
// aapt resource value: 0x7F08008D
public const int scrollIndicatorUp = 2131230861;
// aapt resource value: 0x7F08008E
public const int scrollView = 2131230862;
// aapt resource value: 0x7F080090 // aapt resource value: 0x7F080090
public const int search_button = 2131230864; public const int search_badge = 2131230864;
// aapt resource value: 0x7F080091 // aapt resource value: 0x7F080091
public const int search_close_btn = 2131230865; public const int search_bar = 2131230865;
// aapt resource value: 0x7F080092 // aapt resource value: 0x7F080092
public const int search_edit_frame = 2131230866; public const int search_button = 2131230866;
// aapt resource value: 0x7F080093 // aapt resource value: 0x7F080093
public const int search_go_btn = 2131230867; public const int search_close_btn = 2131230867;
// aapt resource value: 0x7F080094 // aapt resource value: 0x7F080094
public const int search_mag_icon = 2131230868; public const int search_edit_frame = 2131230868;
// aapt resource value: 0x7F080095 // aapt resource value: 0x7F080095
public const int search_plate = 2131230869; public const int search_go_btn = 2131230869;
// aapt resource value: 0x7F080096 // aapt resource value: 0x7F080096
public const int search_src_text = 2131230870; public const int search_mag_icon = 2131230870;
// aapt resource value: 0x7F080097 // aapt resource value: 0x7F080097
public const int search_voice_btn = 2131230871; public const int search_plate = 2131230871;
// aapt resource value: 0x7F080099
public const int selected = 2131230873;
// aapt resource value: 0x7F080098 // aapt resource value: 0x7F080098
public const int select_dialog_listview = 2131230872; public const int search_src_text = 2131230872;
// aapt resource value: 0x7F080099
public const int search_voice_btn = 2131230873;
// aapt resource value: 0x7F08009B
public const int selected = 2131230875;
// aapt resource value: 0x7F08009A
public const int select_dialog_listview = 2131230874;
// aapt resource value: 0x7F080004 // aapt resource value: 0x7F080004
public const int SHIFT = 2131230724; public const int SHIFT = 2131230724;
// aapt resource value: 0x7F08009A
public const int shortcut = 2131230874;
// aapt resource value: 0x7F08009B
public const int showCustom = 2131230875;
// aapt resource value: 0x7F08009C // aapt resource value: 0x7F08009C
public const int showHome = 2131230876; public const int shortcut = 2131230876;
// aapt resource value: 0x7F08009D // aapt resource value: 0x7F08009D
public const int showTitle = 2131230877; public const int showCustom = 2131230877;
// aapt resource value: 0x7F08009E // aapt resource value: 0x7F08009E
public const int smallLabel = 2131230878; public const int showHome = 2131230878;
// aapt resource value: 0x7F08009F // aapt resource value: 0x7F08009F
public const int snackbar_action = 2131230879; public const int showTitle = 2131230879;
// aapt resource value: 0x7F0800A0 // aapt resource value: 0x7F0800A0
public const int snackbar_text = 2131230880; public const int smallLabel = 2131230880;
// aapt resource value: 0x7F0800A1 // aapt resource value: 0x7F0800A1
public const int snap = 2131230881; public const int snackbar_action = 2131230881;
// aapt resource value: 0x7F0800A2 // aapt resource value: 0x7F0800A2
public const int snapMargins = 2131230882; public const int snackbar_text = 2131230882;
// aapt resource value: 0x7F0800A3 // aapt resource value: 0x7F0800A3
public const int spacer = 2131230883; public const int snap = 2131230883;
// aapt resource value: 0x7F0800A4 // aapt resource value: 0x7F0800A4
public const int split_action_bar = 2131230884; public const int snapMargins = 2131230884;
// aapt resource value: 0x7F0800A5 // aapt resource value: 0x7F0800A5
public const int src_atop = 2131230885; public const int spacer = 2131230885;
// aapt resource value: 0x7F0800A6 // aapt resource value: 0x7F0800A6
public const int src_in = 2131230886; public const int split_action_bar = 2131230886;
// aapt resource value: 0x7F0800A7 // aapt resource value: 0x7F0800A7
public const int src_over = 2131230887; public const int src_atop = 2131230887;
// aapt resource value: 0x7F0800A8 // aapt resource value: 0x7F0800A8
public const int start = 2131230888; public const int src_in = 2131230888;
// aapt resource value: 0x7F0800A9 // aapt resource value: 0x7F0800A9
public const int status = 2131230889; public const int src_over = 2131230889;
// aapt resource value: 0x7F0800AA // aapt resource value: 0x7F0800AA
public const int stretch = 2131230890; public const int start = 2131230890;
// aapt resource value: 0x7F0800AB // aapt resource value: 0x7F0800AB
public const int submenuarrow = 2131230891; public const int status = 2131230891;
// aapt resource value: 0x7F0800AC // aapt resource value: 0x7F0800AC
public const int submit_area = 2131230892; public const int stretch = 2131230892;
// aapt resource value: 0x7F0800AD
public const int studentParams = 2131230893;
// aapt resource value: 0x7F0800AE
public const int submenuarrow = 2131230894;
// aapt resource value: 0x7F0800AF
public const int submit_area = 2131230895;
// aapt resource value: 0x7F080005 // aapt resource value: 0x7F080005
public const int SYM = 2131230725; public const int SYM = 2131230725;
// aapt resource value: 0x7F0800AD
public const int tabMode = 2131230893;
// aapt resource value: 0x7F0800AE
public const int tag_transition_group = 2131230894;
// aapt resource value: 0x7F0800AF
public const int tag_unhandled_key_event_manager = 2131230895;
// aapt resource value: 0x7F0800B0 // aapt resource value: 0x7F0800B0
public const int tag_unhandled_key_listeners = 2131230896; public const int tabMode = 2131230896;
// aapt resource value: 0x7F0800B1 // aapt resource value: 0x7F0800B1
public const int text = 2131230897; public const int tag_transition_group = 2131230897;
// aapt resource value: 0x7F0800B2 // aapt resource value: 0x7F0800B2
public const int text2 = 2131230898; public const int tag_unhandled_key_event_manager = 2131230898;
// aapt resource value: 0x7F0800B7
public const int textinput_counter = 2131230903;
// aapt resource value: 0x7F0800B8
public const int textinput_error = 2131230904;
// aapt resource value: 0x7F0800B9
public const int textinput_helper_text = 2131230905;
// aapt resource value: 0x7F0800B3 // aapt resource value: 0x7F0800B3
public const int textSpacerNoButtons = 2131230899; public const int tag_unhandled_key_listeners = 2131230899;
// aapt resource value: 0x7F0800B4 // aapt resource value: 0x7F0800B4
public const int textSpacerNoTitle = 2131230900; public const int text = 2131230900;
// aapt resource value: 0x7F0800B5 // aapt resource value: 0x7F0800B5
public const int textStart = 2131230901; public const int text2 = 2131230901;
// aapt resource value: 0x7F0800B6
public const int text_input_password_toggle = 2131230902;
// aapt resource value: 0x7F0800BA // aapt resource value: 0x7F0800BA
public const int time = 2131230906; public const int textinput_counter = 2131230906;
// aapt resource value: 0x7F0800BB // aapt resource value: 0x7F0800BB
public const int title = 2131230907; public const int textinput_error = 2131230907;
// aapt resource value: 0x7F0800BC // aapt resource value: 0x7F0800BC
public const int titleDividerNoCustom = 2131230908; public const int textinput_helper_text = 2131230908;
// aapt resource value: 0x7F0800B6
public const int textSpacerNoButtons = 2131230902;
// aapt resource value: 0x7F0800B7
public const int textSpacerNoTitle = 2131230903;
// aapt resource value: 0x7F0800B8
public const int textStart = 2131230904;
// aapt resource value: 0x7F0800B9
public const int text_input_password_toggle = 2131230905;
// aapt resource value: 0x7F0800BD // aapt resource value: 0x7F0800BD
public const int title_template = 2131230909; public const int time = 2131230909;
// aapt resource value: 0x7F0800BE // aapt resource value: 0x7F0800BE
public const int top = 2131230910; public const int title = 2131230910;
// aapt resource value: 0x7F0800BF // aapt resource value: 0x7F0800BF
public const int topPanel = 2131230911; public const int titleDividerNoCustom = 2131230911;
// aapt resource value: 0x7F0800C0 // aapt resource value: 0x7F0800C0
public const int touch_outside = 2131230912; public const int title_template = 2131230912;
// aapt resource value: 0x7F0800C1 // aapt resource value: 0x7F0800C1
public const int transition_current_scene = 2131230913; public const int top = 2131230913;
// aapt resource value: 0x7F0800C2 // aapt resource value: 0x7F0800C2
public const int transition_layout_save = 2131230914; public const int topPanel = 2131230914;
// aapt resource value: 0x7F0800C3 // aapt resource value: 0x7F0800C3
public const int transition_position = 2131230915; public const int touch_outside = 2131230915;
// aapt resource value: 0x7F0800C4 // aapt resource value: 0x7F0800C4
public const int transition_scene_layoutid_cache = 2131230916; public const int transition_current_scene = 2131230916;
// aapt resource value: 0x7F0800C5 // aapt resource value: 0x7F0800C5
public const int transition_transform = 2131230917; public const int transition_layout_save = 2131230917;
// aapt resource value: 0x7F0800C6 // aapt resource value: 0x7F0800C6
public const int uniform = 2131230918; public const int transition_position = 2131230918;
// aapt resource value: 0x7F0800C7 // aapt resource value: 0x7F0800C7
public const int unlabeled = 2131230919; public const int transition_scene_layoutid_cache = 2131230919;
// aapt resource value: 0x7F0800C8 // aapt resource value: 0x7F0800C8
public const int up = 2131230920; public const int transition_transform = 2131230920;
// aapt resource value: 0x7F0800C9 // aapt resource value: 0x7F0800C9
public const int useLogo = 2131230921; public const int uniform = 2131230921;
// aapt resource value: 0x7F0800CA // aapt resource value: 0x7F0800CA
public const int view_offset_helper = 2131230922; public const int unlabeled = 2131230922;
// aapt resource value: 0x7F0800CB // aapt resource value: 0x7F0800CB
public const int visible = 2131230923; public const int up = 2131230923;
// aapt resource value: 0x7F0800CC // aapt resource value: 0x7F0800CC
public const int withText = 2131230924; public const int useLogo = 2131230924;
// aapt resource value: 0x7F0800CD // aapt resource value: 0x7F0800CD
public const int wrap_content = 2131230925; public const int user = 2131230925;
// aapt resource value: 0x7F0800CE
public const int view_offset_helper = 2131230926;
// aapt resource value: 0x7F0800CF
public const int visible = 2131230927;
// aapt resource value: 0x7F0800D0
public const int withText = 2131230928;
// aapt resource value: 0x7F0800D1
public const int wrap_content = 2131230929;
static Id() static Id()
{ {
@@ -19,6 +19,18 @@
android:textStyle="bold" android:textStyle="bold"
android:textSize="16dp"/> android:textSize="16dp"/>
<Spinner
android:id="@+id/user"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/studentParams"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -48,6 +60,37 @@
android:id="@+id/group" android:id="@+id/group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:id="@+id/professorParams"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="E-mail"/>
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textWebEmailAddress"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Пароль"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textWebPassword"/>
</LinearLayout>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"