mirror of
https://github.com/XFox111/GUTSchedule.git
synced 2026-04-22 06:58:01 +03:00
Complete application (Date range failed)
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
using Android.Database;
|
using Android.Database;
|
||||||
|
using Android.Net;
|
||||||
using Android.Provider;
|
using Android.Provider;
|
||||||
using Android.Support.V4.Content;
|
using Android.Support.V4.Content;
|
||||||
|
using Java.Util;
|
||||||
|
|
||||||
namespace GUT.Schedule
|
namespace GUT.Schedule
|
||||||
{
|
{
|
||||||
@@ -21,7 +24,7 @@ namespace GUT.Schedule
|
|||||||
CalendarContract.Calendars.InterfaceConsts.AccountType,
|
CalendarContract.Calendars.InterfaceConsts.AccountType,
|
||||||
};
|
};
|
||||||
|
|
||||||
using CursorLoader loader = new CursorLoader(Application.Context, calendarsUri, calendarsProjection, null, null, null);
|
using Android.Support.V4.Content.CursorLoader loader = new Android.Support.V4.Content.CursorLoader(Application.Context, calendarsUri, calendarsProjection, null, null, null);
|
||||||
ICursor cursor = (ICursor)loader.LoadInBackground();
|
ICursor cursor = (ICursor)loader.LoadInBackground();
|
||||||
|
|
||||||
cursor.MoveToNext();
|
cursor.MoveToNext();
|
||||||
@@ -32,5 +35,44 @@ namespace GUT.Schedule
|
|||||||
cursor.MoveToNext();
|
cursor.MoveToNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Export(string calendarId, IEnumerable<Subject> schedule, int? remindBefore, bool addGroupToTitle)
|
||||||
|
{
|
||||||
|
foreach (Subject item in schedule)
|
||||||
|
AddEvent(calendarId, item, remindBefore, addGroupToTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddEvent(string calendarId, Subject subject, int? reminderMinutes, bool addHeader)
|
||||||
|
{
|
||||||
|
ContentValues eventValues = new ContentValues();
|
||||||
|
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, calendarId);
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.Title, $"{subject.Order}.{(addHeader ? $" [{subject.Group}]" : "")} {subject.Name} ({subject.Type})");
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.Description, subject.Professor);
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventLocation, string.Join(';', subject.Cabinets));
|
||||||
|
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.Availability, 0);
|
||||||
|
|
||||||
|
if(reminderMinutes.HasValue)
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.HasAlarm, true);
|
||||||
|
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, subject.StartTime.ToUnixTime());
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, Extensions.ToUnixTime(subject.EndTime));
|
||||||
|
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID);
|
||||||
|
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID);
|
||||||
|
|
||||||
|
Uri response = Application.Context.ContentResolver.Insert(CalendarContract.Events.ContentUri, eventValues);
|
||||||
|
|
||||||
|
if (reminderMinutes.HasValue)
|
||||||
|
{
|
||||||
|
ContentValues reminderValues = new ContentValues();
|
||||||
|
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment));
|
||||||
|
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Method, 1);
|
||||||
|
reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, reminderMinutes.Value);
|
||||||
|
|
||||||
|
Application.Context.ContentResolver.Insert(CalendarContract.Reminders.ContentUri, reminderValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,16 @@ namespace GUT.Schedule
|
|||||||
public static List<(string Id, string Name)> Faculties { get; set; }
|
public static List<(string Id, string Name)> Faculties { get; set; }
|
||||||
public static List<(string Id, string Name)> Groups { get; set; }
|
public static List<(string Id, string Name)> Groups { get; set; }
|
||||||
public static List<(string Id, string Name)> Calendars { get; set; }
|
public static List<(string Id, string Name)> Calendars { get; set; }
|
||||||
|
public static List<Subject> Schedule { get; set; }
|
||||||
|
public static int FirstWeekDay { get; set; }
|
||||||
public static DateTime StartDate { get; set; } = DateTime.Today;
|
public static DateTime StartDate { get; set; } = DateTime.Today;
|
||||||
public static DateTime EndDate { get; set; } = DateTime.Today.AddDays(7);
|
public static DateTime EndDate { get; set; } = DateTime.Today.AddDays(7);
|
||||||
|
|
||||||
public static (int faculty, int group, int calendar, int reminder) ExportData { get; set; }
|
public static int Faculty { get; set; }
|
||||||
|
public static int Group { get; set; }
|
||||||
|
public static int Course { get; set; }
|
||||||
|
public static int Calendar { get; set; }
|
||||||
|
public static int Reminder { get; set; }
|
||||||
|
public static bool AddTitle { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
|
using Android.Widget;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GUT.Schedule
|
namespace GUT.Schedule
|
||||||
@@ -7,13 +8,30 @@ namespace GUT.Schedule
|
|||||||
[Activity(Theme = "@style/AppTheme.NoActionBar")]
|
[Activity(Theme = "@style/AppTheme.NoActionBar")]
|
||||||
public class ExportActivity : Activity
|
public class ExportActivity : Activity
|
||||||
{
|
{
|
||||||
|
TextView status;
|
||||||
protected override async void OnCreate(Bundle savedInstanceState)
|
protected override async void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
SetContentView(Resource.Layout.export_progress);
|
SetContentView(Resource.Layout.export_progress);
|
||||||
|
|
||||||
await Task.Delay(5000);
|
status = FindViewById<TextView>(Resource.Id.status);
|
||||||
|
|
||||||
|
status.Text = "Загрузка расписания";
|
||||||
|
await Parser.LoadSchedule();
|
||||||
|
|
||||||
|
status.Text = "Экспортирование в календарь";
|
||||||
|
int minutes = Data.Reminder switch
|
||||||
|
{
|
||||||
|
1 => 0,
|
||||||
|
2 => 5,
|
||||||
|
3 => 10,
|
||||||
|
_ => -1
|
||||||
|
};
|
||||||
|
Calendar.Export(Data.Calendars[Data.Calendar].Id, Data.Schedule, minutes < 0 ? (int?)null : minutes, Data.AddTitle);
|
||||||
|
|
||||||
|
status.Text = "Готово";
|
||||||
|
|
||||||
|
await Task.Delay(3000);
|
||||||
base.OnBackPressed();
|
base.OnBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
namespace GUT.Schedule
|
namespace GUT.Schedule
|
||||||
@@ -19,5 +13,16 @@ namespace GUT.Schedule
|
|||||||
ArrayAdapter adapter = new ArrayAdapter(context, Resource.Layout.support_simple_spinner_dropdown_item, array.ToList());
|
ArrayAdapter adapter = new ArrayAdapter(context, Resource.Layout.support_simple_spinner_dropdown_item, array.ToList());
|
||||||
spinner.Adapter = adapter;
|
spinner.Adapter = adapter;
|
||||||
}
|
}
|
||||||
|
public static DateTime GetDateFromWeeks(int week, int weekday)
|
||||||
|
{
|
||||||
|
DateTime dt = new DateTime(DateTime.Today.Year, 9, Data.FirstWeekDay);
|
||||||
|
|
||||||
|
dt = dt.AddDays(--week * 7);
|
||||||
|
dt = dt.AddDays(--weekday);
|
||||||
|
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
public static long ToUnixTime(this DateTime dt) =>
|
||||||
|
(long)dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,6 +69,7 @@
|
|||||||
<Compile Include="Resources\Resource.designer.cs" />
|
<Compile Include="Resources\Resource.designer.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="StartActivity.cs" />
|
<Compile Include="StartActivity.cs" />
|
||||||
|
<Compile Include="Subject.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Resources\AboutResources.txt" />
|
<None Include="Resources\AboutResources.txt" />
|
||||||
@@ -104,6 +105,9 @@
|
|||||||
<Folder Include="Resources\drawable\" />
|
<Folder Include="Resources\drawable\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AngleSharp">
|
||||||
|
<Version>0.13.0</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="System.Net.Http">
|
<PackageReference Include="System.Net.Http">
|
||||||
<Version>4.3.4</Version>
|
<Version>4.3.4</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Linq;
|
|||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Support.Design.Widget;
|
|
||||||
using Android.Support.V7.App;
|
using Android.Support.V7.App;
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
@@ -70,6 +69,11 @@ namespace GUT.Schedule
|
|||||||
error.Visibility = ViewStates.Visible;
|
error.Visibility = ViewStates.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Data.Faculty = faculty.SelectedItemPosition;
|
||||||
|
Data.Group = group.SelectedItemPosition;
|
||||||
|
Data.Course = course.SelectedItemPosition + 1;
|
||||||
|
Data.Reminder = reminder.SelectedItemPosition;
|
||||||
|
Data.AddTitle = groupTitle.Checked;
|
||||||
|
|
||||||
StartActivity(new Intent(this, typeof(ExportActivity)));
|
StartActivity(new Intent(this, typeof(ExportActivity)));
|
||||||
}
|
}
|
||||||
@@ -113,6 +117,7 @@ namespace GUT.Schedule
|
|||||||
calendar = FindViewById<Spinner>(Resource.Id.calendar);
|
calendar = FindViewById<Spinner>(Resource.Id.calendar);
|
||||||
|
|
||||||
error = FindViewById<TextView>(Resource.Id.error);
|
error = FindViewById<TextView>(Resource.Id.error);
|
||||||
|
groupTitle = FindViewById<CheckBox>(Resource.Id.groupTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddEvents()
|
private void AddEvents()
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using System;
|
using AngleSharp.Dom;
|
||||||
|
using AngleSharp.Html.Dom;
|
||||||
|
using AngleSharp.Html.Parser;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -8,6 +12,52 @@ namespace GUT.Schedule
|
|||||||
{
|
{
|
||||||
public static class Parser
|
public static class Parser
|
||||||
{
|
{
|
||||||
|
public static async Task LoadSchedule()
|
||||||
|
{
|
||||||
|
Data.Schedule = new List<Subject>();
|
||||||
|
using HttpClient client = new HttpClient();
|
||||||
|
Dictionary<string, string> requestBody = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "group_el", "0" },
|
||||||
|
{ "kurs", Data.Course.ToString() },
|
||||||
|
{ "type_z", "1" },
|
||||||
|
{ "faculty", Data.Faculties[Data.Faculty].Id },
|
||||||
|
{ "group", Data.Groups[Data.Group].Id },
|
||||||
|
{ "ok", "Показать" },
|
||||||
|
{ "schet", GetCurrentSemester() }
|
||||||
|
};
|
||||||
|
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabinet.sut.ru/raspisanie_all_new")
|
||||||
|
{
|
||||||
|
Content = new FormUrlEncodedContent(requestBody)
|
||||||
|
};
|
||||||
|
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
HttpResponseMessage response = await client.SendAsync(request);
|
||||||
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
HtmlParser parser = new HtmlParser();
|
||||||
|
IHtmlDocument doc = parser.ParseDocument(responseBody);
|
||||||
|
|
||||||
|
string groupName = doc.QuerySelectorAll("#group option").FirstOrDefault(i => i.HasAttribute("selected")).TextContent;
|
||||||
|
|
||||||
|
IHtmlCollection<IElement> pairs = doc.QuerySelectorAll(".pair");
|
||||||
|
foreach (IElement item in pairs)
|
||||||
|
{
|
||||||
|
string name, type, professor, place;
|
||||||
|
int order, weekday;
|
||||||
|
string[] weeks;
|
||||||
|
|
||||||
|
name = item.QuerySelector(".subect strong")?.TextContent ?? "Неизвестный предмет (см. Расписание)";
|
||||||
|
type = item.QuerySelector(".type").TextContent.Replace("(", "").Replace(")", "");
|
||||||
|
professor = item.QuerySelector(".teacher")?.GetAttribute("title") ?? "";
|
||||||
|
place = item.QuerySelector(".aud")?.TextContent ?? "СПбГУТ";
|
||||||
|
order = int.Parse(item.GetAttribute("pair") ?? "2") - 1;
|
||||||
|
weeks = item.QuerySelector(".weeks").TextContent.Replace("(", "").Replace("н)", "").Split(", ");
|
||||||
|
weekday = int.Parse(item.GetAttribute("weekday"));
|
||||||
|
Data.Schedule.AddRange(Subject.GetSubject(name, type, professor, place, order, weeks, weekday, groupName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task LoadFaculties()
|
public static async Task LoadFaculties()
|
||||||
{
|
{
|
||||||
Data.Faculties = new List<(string, string)>();
|
Data.Faculties = new List<(string, string)>();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
android:layout_margin="20dp"/>
|
android:layout_margin="20dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/status"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Загрузка"
|
android:text="Загрузка"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Android.Support.V4.Content;
|
|||||||
using Android.Support.V7.App;
|
using Android.Support.V7.App;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace GUT.Schedule
|
namespace GUT.Schedule
|
||||||
{
|
{
|
||||||
@@ -45,6 +46,10 @@ namespace GUT.Schedule
|
|||||||
status.Text = "Загрузка списка факультетов";
|
status.Text = "Загрузка списка факультетов";
|
||||||
await Parser.LoadFaculties();
|
await Parser.LoadFaculties();
|
||||||
|
|
||||||
|
status.Text = "Загрузка дат смещения";
|
||||||
|
using (HttpClient client = new HttpClient())
|
||||||
|
Data.FirstWeekDay = int.Parse(await client.GetStringAsync("https://xfox111.net/schedule_offset.txt"));
|
||||||
|
|
||||||
StartActivity(new Intent(this, typeof(MainActivity)));
|
StartActivity(new Intent(this, typeof(MainActivity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace GUT.Schedule
|
||||||
|
{
|
||||||
|
public class Subject
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Professor { get; set; }
|
||||||
|
public string[] Cabinets { get; set; }
|
||||||
|
public string Order { get; set; }
|
||||||
|
public DateTime StartTime { get; set; }
|
||||||
|
public DateTime EndTime { get; set; }
|
||||||
|
public string Group { get; set; }
|
||||||
|
|
||||||
|
public static List<Subject> GetSubject(string name, string type, string professor, string place, int order, string[] weeks, int weekday, string group)
|
||||||
|
{
|
||||||
|
List<Subject> subjects = new List<Subject>();
|
||||||
|
string[] cabinets = place.Replace("ауд.: ", "").Replace("; Б22", "").Split(';');
|
||||||
|
string pair = order < 10 ? order.ToString() : $"Ф{order - 81}";
|
||||||
|
|
||||||
|
foreach (string week in weeks)
|
||||||
|
subjects.Add(new Subject(name, type, professor, cabinets, pair, int.Parse(week), weekday, group));
|
||||||
|
|
||||||
|
return subjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subject(string name, string type, string prof, string[] cabs, string order, int week, int weekday, string group)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Type = type;
|
||||||
|
Professor = prof;
|
||||||
|
Cabinets = cabs;
|
||||||
|
Order = order;
|
||||||
|
Group = group;
|
||||||
|
|
||||||
|
StartTime = Extensions.GetDateFromWeeks(week, weekday);
|
||||||
|
StartTime = StartTime.Add(TimeSpan.Parse(order switch
|
||||||
|
{
|
||||||
|
"1" => "9:00",
|
||||||
|
"2" => "10:45",
|
||||||
|
"3" => "13:00",
|
||||||
|
"4" => "14:45",
|
||||||
|
"5" => "16:30",
|
||||||
|
"6" => "18:15",
|
||||||
|
"7" => "20:00",
|
||||||
|
"Ф1" => "9:00", //Расписание для пар по физ-ре
|
||||||
|
"Ф2" => "10:30",
|
||||||
|
"Ф3" => "12:00",
|
||||||
|
"Ф4" => "13:30",
|
||||||
|
"Ф5" => "15:00",
|
||||||
|
"Ф6" => "16:30",
|
||||||
|
"Ф7" => "18:00",
|
||||||
|
_ => "9:00"
|
||||||
|
}));
|
||||||
|
EndTime = StartTime + TimeSpan.FromMinutes(order.Contains("Ф") ? 90 : 95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user