Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
v1.1.0-1
Browse files Browse the repository at this point in the history
Added new features
  • Loading branch information
gh0st17 authored Oct 16, 2022
2 parents b386e90 + c84dc0e commit fc7a3ef
Show file tree
Hide file tree
Showing 11 changed files with 615 additions and 281 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ orleans.codegen.cs
*.xml
*.html
*.ico
*.ics
Resource.rc
Resource.aps
resource.h
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
- Выбор группы из списка
- Просмотр списка групп
- Загрузка списка групп в кэш и его очистка
- Загрузка рассписания на конкретную неделю
- Загрузка текущего рассписания и на конкретную неделю
- Поддержка HTTP[S] и Socks4/5 прокси
- Поддержка вывода в файл ics

# Справка по использованию

Expand All @@ -29,6 +31,9 @@ TimeTable.exe --clear
-l
--clear, - Очистить весь кэш
-c
--ics, - Вывод в ics файл
--proxy, - Использовать прокси
<протокол://адрес:порт>
```

# FAQ
Expand Down
184 changes: 184 additions & 0 deletions TimeTable/Manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include "Manager.hpp"

#undef max

const string Manager::today_url() {
return base_url + "index.php?group=" + p.group_names[p.group - 1];
}

const string Manager::week_url() {
return today_url() + "&week=" + to_string(p.week);
}

const string Manager::group_url() {
return base_url + "groups.php?department=Институт+№"
+ to_string(p.dep) + "&course=" + to_string(p.course);
}

const string Manager::getPtimeString(const ptime& time, const char* format) {
locale loc(cout.getloc(),
new time_facet(format));

stringstream ss;
ss.imbue(loc);
ss << time;
return ss.str();
}

void Manager::getTimeTable() {
try {
if (p.clear) {
unsigned cnt{ 0 };
for (const auto& file : directory_iterator("./")) {
if (file.path().extension() == ".xml") {
cout << file.path().filename().u8string() << endl;
remove(file.path());
cnt++;
}
}
cout << "Удалено файлов: " << cnt << endl;
}
else if (p.list)
return;
else if (p.group && p.week)
tt = parser.parse(p, week_url());
else if (p.group && !p.week)
tt = parser.parse(p, today_url());
else {
cout << "Введите номер группы: ";
while (!(cin >> p.group) || !p.group || p.group > p.group_names.size()) {
cout << "Введите номер группы: ";
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
}
tt = parser.parse(p, today_url());
}
}
catch (bad_alloc const&) {
cerr << "Ошибка выделения памяти\n";
}
catch (const exception& e) {
cerr << e.what() << endl;
}
catch (const char* e) {
cerr << e << endl;
}
}

void Manager::printTimeTable() {
cout << tt.group << "\n\n";

if (tt.week)
cout << "Учебная неделя №" << tt.week << "\n\n";

for (const auto& day : tt.days) {
cout << day.date << endl;
for (const auto& item : day.items) {
cout << '[' << item.item_type << "] " << item.name << endl <<
getPtimeString(item.time, "%H:%M") << " - " <<
getPtimeString(item.time + minutes(90), "%H:%M") << " / ";

if (item.educators.size())
for (const auto& educator : item.educators)
cout << educator << " / ";

for (const auto& place : item.places) {
cout << place;
if (place != item.places.back())
cout << " / ";
}
cout << endl;
}
cout << endl;
}
}

void Manager::writeIcsTimeTable() {
stringstream filename;
filename << tt.group << "_Week_";
if (tt.week)
filename << tt.week;
else
filename << "Today";
filename << ".ics";

cout << "Вывод в файл " << filename.str() << endl;

ofstream ofs(filename.str());
ofs << "BEGIN:VCALENDAR\nVERSION:2.0\n" <<
"PRODID: ghost17 | Alexey Sorokin\n" <<
"CALSCALE: GREGORIAN\n\n";

for (const auto& day : tt.days) {
for (const auto& item : day.items) {
ofs << "BEGIN:VEVENT\nDTSTART:" <<
getPtimeString(item.time, "%Y%m%dT%H%M%S") << endl <<
"DTEND:" <<
getPtimeString(item.time + minutes(90), "%Y%m%dT%H%M%S") << endl <<
"SUMMARY:" << item.name << endl << "LOCATION:" << item.item_type <<
" / ";

for (const auto& place : item.places) {
ofs << place;
if (place != item.places.back())
ofs << " / ";
}

if (item.educators.size()) {
ofs << " / ";
for (const auto& educator : item.educators) {
ofs << educator;
if (educator != item.educators.back())
ofs << " / ";
}
}

ofs << "\nEND:VEVENT\n\n";
}
}

ofs.close();
}

Manager::Manager(int& argc, char* argv[]) {
try {
p.checkArgc(argc);
p = Params(argv[1], argv[2]);
if (argc > 3)
parser.parse_group(p, group_url(), false);
else
parser.parse_group(p, group_url(), true);

p = Params(p, argc, argv);
}
catch (bad_alloc const&) {
cerr << "Ошибка выделения памяти\n";
exit(1);
}
catch (const exception& e) {
cerr << e.what() << endl;
exit(1);
}
catch (const char* e) {
cerr << e << endl;
exit(1);
}

cout.imbue(locale(locale::classic(), russian_facet));
date_facet::input_collection_type short_weekdays, long_month;
copy(&short_weekday_names[0], &short_weekday_names[7],
back_inserter(short_weekdays));
copy(&long_month_names[0], &long_month_names[11],
back_inserter(long_month));
russian_facet->short_weekday_names(short_weekdays);
russian_facet->long_month_names(long_month);
russian_facet->format("%a, %d %B");
}

void Manager::run() {
getTimeTable();
if (p.ics)
writeIcsTimeTable();
else
printTimeTable();
}
43 changes: 43 additions & 0 deletions TimeTable/Manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <filesystem>
#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>

#include "Params.hpp"
#include "Parser.hpp"

using namespace std;
using namespace std::filesystem;

class Manager {
private:
Params p;
Parser parser;
TimeTable tt;
const string base_url = "http://mai.ru/education/studies/schedule/";

const char* const short_weekday_names[8] = {
"Вс", "Пн", "Вт","Ср", "Чт", "Пт", "Сб", "Сб"
};
const char* const long_month_names[12] = {
"января", "февраля", "марта","апреля", "мая",
"июня", "июля", "августа", "сентября", "октября",
"ноября", "декабря"
};
date_facet* russian_facet = new date_facet();

const string today_url();
const string week_url();
const string group_url();
const string getPtimeString(const ptime& time, const char* format);

void getTimeTable();
void printTimeTable();
void writeIcsTimeTable();

public:
Manager(int& argc, char* argv[]);

void run();
};
100 changes: 58 additions & 42 deletions TimeTable/Params.cpp
Original file line number Diff line number Diff line change
@@ -1,61 +1,77 @@
#include "Params.hpp"

Params::Params(int argc, char* argv[]) {
if (argc < 3)
printHelp();
using namespace std;

string param;
dep = stoi(argv[1]), course = stoi(argv[2]);
Params::Params(char* arg1, char* arg2) {
dep = stoi(arg1), course = stoi(arg2);
if (dep > 12 || dep == 0 ||
course > 6 || course == 0)
printHelp();
else
filename = to_string(dep) + '-' + to_string(course) + ".xml";
}

filename = to_string(dep) + '-' + to_string(course) + ".xml";
Params::Params(Params& p, int& argc, char* argv[]) {
*this = p;
string param;

if (argc > 3) {
for (size_t i = 3; i < argc; i++) {
param = string(argv[i]);
if (param == "--group" || param == "-g")
if (i + 1 < argc)
group = stoi(argv[++i]);
else
throw "Номер группы пропущен";
else if (param == "--week" || param == "-w") {
if (i + 1 < argc) {
week = stoi(argv[++i]);
if ((!week || week > 18) && !list && !clear)
throw "Такой недели не существует";
}
else
throw "Номер недели пропущен";
for (size_t i = 3; i < argc; i++) {
param = string(argv[i]);
if (param == "--group" || param == "-g") {
if (i + 1 < argc)
group = stoi(argv[++i]);
else
throw "Номер группы пропущен";
}
else if (param == "--week" || param == "-w") {
if (i + 1 < argc) {
week = stoi(argv[++i]);
if ((!week || week > 18) && !list && !clear)
throw "Такой недели не существует";
}
else if (param == "--list" || param == "-l")
list = true;
else if (param == "--clear" || param == "-c") {
clear = true;
return;
else
throw "Номер недели пропущен";
}
else if (param == "--proxy") {
if (i + 1 < argc) {
proxy = argv[++i];
}
else
throw ("Неизвестный параметр " + param).c_str();
throw "Адрес прокси пропущен";
}
else if (param == "--list" || param == "-l")
list = true;
else if (param == "--ics")
ics = true;
else if (param == "--clear" || param == "-c") {
clear = true;
return;
}
else
throw ("Неизвестный параметр " + param).c_str();
}

parse_group(*this, false);
if (argc > 3 && (!group || group > group_names.size()) && !list && !clear)
throw "Номер группы не существует";
}

if ((!group || group > group_names.size()) && !list && !clear)
throw "Номер группы не существует или не задан";
} else
parse_group(*this, true);
void Params::checkArgc(int& argc) {
if (argc < 3)
printHelp();
}

void Params::printHelp() {
cout << "TimeTable.exe {Институт} {Курс} --group <Число> --week <Число>\n";
cout << "TimeTable.exe {Институт} {Курс} --list\n";
cout << "TimeTable.exe --clear\n\n";
cout << " Институт - Номер института от 1 до 12\n";
cout << " Курс - Номер курса от 1 до 6\n";
cout << " --group, - Номер группы из списка\n -g\n";
cout << " --week, - Номер недели от 1 до 18\n -w\n";
cout << " --list, - Показать только список групп\n -l\n";
cout << " --clear, - Очистить весь кэш\n -c\n";
cout << "TimeTable.exe {Институт} {Курс} --group <Число> --week <Число>\n" <<
"TimeTable.exe {Институт} {Курс} --list\n" <<
"TimeTable.exe --clear\n\n" <<
" Институт - Номер института от 1 до 12\n" <<
" Курс - Номер курса от 1 до 6\n" <<
" --group, - Номер группы из списка\n -g\n" <<
" --week, - Номер недели от 1 до 18\n -w\n" <<
" --list, - Показать только список групп\n -l\n" <<
" --clear, - Очистить весь кэш\n -c\n" <<
" --ics, - Вывод в ics файл\n" <<
" --proxy, - Использовать прокси\n" <<
" <протокол://адрес:порт>\n";
exit(1);
}
Loading

0 comments on commit fc7a3ef

Please sign in to comment.