mirror of
https://github.com/XFox111/GUTSchedule.git
synced 2026-04-22 06:58:01 +03:00
Splitted and added UWP project
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GUTSchedule
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns <see cref="DateTime"/> instance based on study week number, weekday and semester start day number
|
||||
/// </summary>
|
||||
/// <param name="week">Number of the study week</param>
|
||||
/// <param name="weekday">Weekday</param>
|
||||
/// <returns><see cref="DateTime"/> instance based on study week number, weekday and semester start day number</returns>
|
||||
public static DateTime GetDateFromWeeks(int week, int weekday)
|
||||
{
|
||||
DateTime dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month >= 8 ? 9 : 2, Data.FirstWeekDay);
|
||||
|
||||
dt = dt.AddDays(--week * 7);
|
||||
dt = dt.AddDays(--weekday);
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" Version="0.13.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace GUTSchedule.Models
|
||||
{
|
||||
public class CabinetSubject
|
||||
{
|
||||
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 Opponent { get; set; }
|
||||
public bool ProfessorSchedule { get; set; }
|
||||
|
||||
public CabinetSubject(string name, string type, string cabinet, string opponent, int year, int month, int day, string schedule, bool profSchedule)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
Cabinet = cabinet;
|
||||
Opponent = opponent;
|
||||
ProfessorSchedule = profSchedule;
|
||||
|
||||
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);
|
||||
switch (time[0])
|
||||
{
|
||||
case "09.00": Order = "1"; break;
|
||||
case "10.45": Order = "2"; break;
|
||||
case "13.00": Order = "3"; break;
|
||||
case "14.45": Order = "4"; break;
|
||||
case "16.30": Order = "5"; break;
|
||||
case "18.15": Order = "6"; break;
|
||||
case "20.00": Order = "7"; break;
|
||||
case "10.30": Order = "2"; break; //Расписание для пар по физ-ре
|
||||
case "12.00": Order = "3"; break;
|
||||
case "13.30": Order = "4"; break;
|
||||
case "15.00": Order = "5"; break;
|
||||
case "18.00": Order = "7"; break;
|
||||
default: Order = ""; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using GUTSchedule.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GUTSchedule
|
||||
{
|
||||
public static class Data
|
||||
{
|
||||
public static List<(string Id, string Name)> Faculties { get; set; }
|
||||
public static List<(string Id, string Name)> Groups { get; set; }
|
||||
public static int FirstWeekDay { get; set; }
|
||||
public static DateTime StartDate { get; set; } = DateTime.Today;
|
||||
public static DateTime EndDate { get; set; } = DateTime.Today.AddDays(7);
|
||||
|
||||
/// <summary>
|
||||
/// Export parameters
|
||||
/// </summary>
|
||||
public static DataSet DataSet { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Net.Http;
|
||||
|
||||
namespace GUTSchedule.Models
|
||||
{
|
||||
public class DataSet
|
||||
{
|
||||
public string Calendar { get; set; }
|
||||
public string Faculty { get; set; }
|
||||
public int Course { get; set; }
|
||||
public string Group { get; set; }
|
||||
public int Reminder { get; set; }
|
||||
public bool AddGroupToTitle { get; set; }
|
||||
public HttpClient HttpClient { get; set; }
|
||||
public bool? IsProfessor { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GUTSchedule.Models
|
||||
{
|
||||
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);
|
||||
string rawTime;
|
||||
switch (order)
|
||||
{
|
||||
case "1": rawTime = "9:00"; break;
|
||||
case "2": rawTime = "10:45"; break;
|
||||
case "3": rawTime = "13:00"; break;
|
||||
case "4": rawTime = "14:45"; break;
|
||||
case "5": rawTime = "16:30"; break;
|
||||
case "6": rawTime = "18:15"; break;
|
||||
case "7": rawTime = "20:00"; break;
|
||||
case "Ф1": rawTime = "9:00"; break; //Расписание для пар по физ-ре
|
||||
case "Ф2": rawTime = "10:30"; break;
|
||||
case "Ф3": rawTime = "12:00"; break;
|
||||
case "Ф4": rawTime = "13:30"; break;
|
||||
case "Ф5": rawTime = "15:00"; break;
|
||||
case "Ф6": rawTime = "16:30"; break;
|
||||
case "Ф7": rawTime = "18:00"; break;
|
||||
default: rawTime = "9:00"; break;
|
||||
}
|
||||
StartTime = StartTime.Add(TimeSpan.Parse(rawTime));
|
||||
EndTime = StartTime + TimeSpan.FromMinutes(order.Contains("Ф") ? 90 : 95);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using AngleSharp.Dom;
|
||||
using AngleSharp.Html.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using GUTSchedule.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GUTSchedule
|
||||
{
|
||||
public static class Parser
|
||||
{
|
||||
public static async Task<List<Subject>> LoadSchedule()
|
||||
{
|
||||
List<Subject> schedule = new List<Subject>();
|
||||
HttpClient client = new HttpClient();
|
||||
Dictionary<string, string> requestBody = new Dictionary<string, string>
|
||||
{
|
||||
{ "group_el", "0" },
|
||||
{ "kurs", Data.DataSet.Course.ToString() },
|
||||
{ "type_z", "1" },
|
||||
{ "faculty", Data.DataSet.Faculty },
|
||||
{ "group", Data.DataSet.Group },
|
||||
{ "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);
|
||||
|
||||
IHtmlDocument doc = new HtmlParser().ParseDocument(await response.Content.ReadAsStringAsync());
|
||||
|
||||
string groupName = Data.Groups.First(i => i.Id == Data.DataSet.Group).Name;
|
||||
|
||||
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").Replace(";", "") ?? "";
|
||||
place = item.QuerySelector(".aud")?.TextContent ?? "СПбГУТ";
|
||||
order = int.Parse(item.GetAttribute("pair")) - 1;
|
||||
weeks = item.QuerySelector(".weeks").TextContent.Replace("(", "").Replace("н)", "").Replace(" ", "").Split(',');
|
||||
weekday = int.Parse(item.GetAttribute("weekday"));
|
||||
|
||||
schedule.AddRange(Subject.GetSubject(name, type, professor, place, order, weeks, weekday, groupName));
|
||||
}
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public static async Task LoadFaculties()
|
||||
{
|
||||
Data.Faculties = new List<(string, string)>();
|
||||
HttpClient client = new HttpClient();
|
||||
Dictionary<string, string> requestBody = new Dictionary<string, string>
|
||||
{
|
||||
{ "choice", "1" },
|
||||
{ "kurs", "0" },
|
||||
{ "type_z", "1" },
|
||||
{ "schet", GetCurrentSemester() }
|
||||
};
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabinet.sut.ru/raspisanie_all_new.php")
|
||||
{
|
||||
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();
|
||||
if (string.IsNullOrWhiteSpace(responseBody))
|
||||
throw new NullReferenceException("Расписание на текущий семестр еще не объявлено");
|
||||
|
||||
foreach (string s in responseBody.Split(';'))
|
||||
try { Data.Faculties.Add((s.Split(',')[0], s.Split(',')[1])); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static async Task LoadGroups(string facultyId, int course)
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
Dictionary<string, string> requestBody = new Dictionary<string, string>
|
||||
{
|
||||
{ "choice", "1" },
|
||||
{ "kurs", course.ToString() },
|
||||
{ "type_z", "1" },
|
||||
{ "faculty", facultyId },
|
||||
{ "schet", GetCurrentSemester() }
|
||||
};
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabinet.sut.ru/raspisanie_all_new.php")
|
||||
{
|
||||
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();
|
||||
Data.Groups = new List<(string, string)>();
|
||||
foreach (string s in responseBody.Split(';'))
|
||||
try { Data.Groups.Add((s.Split(',')[0], s.Split(',')[1])); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
static string GetCurrentSemester()
|
||||
{
|
||||
DateTime now = DateTime.Today;
|
||||
|
||||
if (now.Month > 8)
|
||||
return $"205.{now.Year - 2000}{now.Year - 1999}/1";
|
||||
else
|
||||
return $"205.{now.Year - 2001}{now.Year - 2000}/2";
|
||||
}
|
||||
|
||||
public static async Task<List<CabinetSubject>> GetCabinetSchedule(HttpClient client, DateTime date, bool checkProfSchedule)
|
||||
{
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, $"https://cabs.itut.ru/cabinet/project/cabinet/forms/{(checkProfSchedule ? "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<CabinetSubject> schedule = new List<CabinetSubject>();
|
||||
|
||||
if (!checkProfSchedule)
|
||||
Data.DataSet.Group = doc.QuerySelector(".style_gr b").TextContent;
|
||||
|
||||
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++)
|
||||
{
|
||||
CabinetSubject item = new CabinetSubject(
|
||||
name: i.QuerySelectorAll("b")[k * 2 + 1].TextContent,
|
||||
type: i.QuerySelectorAll("i")[k].TextContent,
|
||||
cabinet: i.QuerySelectorAll("small")[k].NextSibling.TextContent.Replace("; Б22", ""),
|
||||
opponent: i.QuerySelectorAll("i")[k].NextSibling.NextSibling.NodeType == NodeType.Text ?
|
||||
i.QuerySelectorAll("i")[k].NextSibling.NextSibling.TextContent : "",
|
||||
year: date.Year,
|
||||
month: date.Month,
|
||||
day: int.Parse(i.ChildNodes[0].TextContent),
|
||||
schedule: i.QuerySelectorAll("b")[k * 2 + 2].TextContent,
|
||||
checkProfSchedule);
|
||||
schedule.Add(item);
|
||||
}
|
||||
|
||||
// Merge duplicating entries
|
||||
schedule.OrderByDescending(i => i.StartTime);
|
||||
for (int k = 1; k < schedule.Count; k++)
|
||||
if (schedule[k - 1].StartTime == schedule[k].StartTime &&
|
||||
schedule[k - 1].Name == schedule[k].Name &&
|
||||
schedule[k - 1].Type == schedule[k].Type)
|
||||
{
|
||||
schedule[k - 1].Opponent += "\n" + schedule[k].Opponent;
|
||||
schedule[k - 1].Cabinet += "; " + schedule[k].Cabinet;
|
||||
schedule.RemoveAt(k--);
|
||||
}
|
||||
|
||||
return schedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user