Skip to content

Commit

Permalink
CLI v1
Browse files Browse the repository at this point in the history
  • Loading branch information
Daoortor committed Dec 9, 2024
1 parent 357e5bd commit 0cb8cc2
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 13 deletions.
105 changes: 98 additions & 7 deletions app/main.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,103 @@
#include <iostream>
#include <QtCore>
#include <QCommandLineParser>

#include "../common/common.h"
#include "../core/include/pathfinder.h"
#include "../models/include/transportSystem.h"
#include "../lib/CLI11/include/CLI/CLI.hpp"

QTextStream cout(stdout, QIODevice::WriteOnly);
QTextStream cin(stdin, QIODevice::ReadOnly);

void handleRouteCommand(const sdtmaps::TransportSystem &transportSystem, std::vector<std::string> &args) {
std::string startArg;
std::string endArg;
std::string dateArg;
std::string timeArg;
CLI::App app{"route"};
app.add_option("--start", startArg, "ID or full name of the start station")->required();
app.add_option("--end", endArg, "ID or full name of the end station")->required();
app.add_option("--date", dateArg, "departure date in yyyy-mm-dd format; defaults to the first date in the schedule");
app.add_option("--time", timeArg, "departure time in h:mm format; defaults to 0:00");
try {
app.parse(std::vector(args.begin(), args.end() - 1));
} catch (const CLI::ParseError &e) {
std::cerr << e.what() << std::endl;
return;
}
startArg = CLI::detail::remove_quotes(startArg);
endArg = CLI::detail::remove_quotes(endArg);
dateArg = CLI::detail::remove_quotes(dateArg);
timeArg = CLI::detail::remove_quotes(timeArg);

const sdtmaps::Stop *start = transportSystem.getStopById(startArg.c_str());
if (!start) {
start = transportSystem.getStopByName(startArg.c_str());
}
if (!start) {
qDebug() << "Start station '" << startArg.c_str() << "' not found\n";
return;
}
const sdtmaps::Stop *end = transportSystem.getStopById(endArg.c_str());
if (!end) {
end = transportSystem.getStopByName(endArg.c_str());
}
if (!end) {
qDebug() << "End station '" << endArg.c_str() << "' not found\n";
return;
}
QDate initDate = dateArg.empty() ? transportSystem.getStartDate() : QDate::fromString(dateArg.c_str(), "yyyy-mm-dd");
QTime initTime = timeArg.empty() ? QTime(0, 0) : QTime::fromString(dateArg.c_str(), "h:mm");
std::optional<sdtmaps::Journey> result = pathfind(transportSystem, start->id, end->id, QDateTime(initDate, initTime));
if (!result.has_value()) {
qDebug() << "No journey found\n";
return;
}
sdtmaps::Journey &journey = result.value();
cout << journey << Qt::flush;
}

int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName("MNS");
QCoreApplication::setApplicationVersion("1.0");
QCommandLineParser parser;
parser.addVersionOption();
parser.addPositionalArgument("dataset",
"The name of the dataset to load transport data from. Datasets are stored in the " PROJECT_DATA_ROOT_RELATIVE_PATH " directory. Example: 'gtfs_hamburg'.");
parser.process(app);

const QStringList positionalArgs = parser.positionalArguments();
if (positionalArgs.size() != 1) {
std::cerr << "Expected 1 positional argument(s): dataset, but got " << positionalArgs.size() << std::endl;
return EXIT_FAILURE;
}
const QString &dataset = positionalArgs[0];

sdtmaps::TransportSystem transportSystem;

try {
transportSystem = sdtmaps::TransportSystem(QDir(QString(PROJECT_DATA_ROOT "/") + dataset));
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}

int main(int argc, char** argv)
{
// avoid compiler warnings
Q_UNUSED(argc)
Q_UNUSED(argv)
QString s("Hello World!");
cout << s << Qt::endl;
std::string input;
cout << "[" + QCoreApplication::applicationName() + "]$ " << Qt::flush;
while (std::getline(std::cin, input)) {
std::vector<std::string> args = CLI::detail::split_up(input);
if (args.empty()) {
continue;
}
std::string commandName = args[0];
std::ranges::reverse(args);
if (commandName == "route") {
handleRouteCommand(transportSystem, args);
} else {
qDebug() << "Unknown command: " << commandName.c_str();
}
cout << "[" + QCoreApplication::applicationName() + "]$ " << Qt::flush;
}
}
8 changes: 8 additions & 0 deletions common/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef COMMON_H
#define COMMON_H

#define PROJECT_DATA_ROOT_RELATIVE_PATH "/data"

#define PROJECT_DATA_ROOT PROJECT_ROOT_PATH PROJECT_DATA_ROOT_RELATIVE_PATH

#endif //COMMON_H
4 changes: 2 additions & 2 deletions core/src/pathfinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ namespace sdtmaps {

std::optional<Journey> pathfind(const TransportSystem &transportSystem, const QString& sourceId, const QString& targetId, const DateTime &initDateTime
, size_t maxChanges) {
const Stop *source = transportSystem.getStop(sourceId);
const Stop *target = transportSystem.getStop(targetId);
const Stop *source = transportSystem.getStopById(sourceId);
const Stop *target = transportSystem.getStopById(targetId);
// If any of the stops was not found
if (!source || !target) {
return std::nullopt;
Expand Down
5 changes: 4 additions & 1 deletion models/include/transportSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ struct TransportSystem {
// Check if all pointers point inside corresponding containers
[[nodiscard]] bool isValid() const;
// Find stop by id (to be optimized w/search structures)
[[nodiscard]] const Stop *getStop(const QString &stopId) const;
[[nodiscard]] const Stop *getStopById(const QString &stopId) const;
// Find stop by name (to be optimized w/search structures)
[[nodiscard]] const Stop *getStopByName(const QString &stopName) const;
// Find stops by substring (to be optimized w/search structures)
[[nodiscard]] std::vector<Stop *> getStopsBySubstring(const QString &substring) const;
[[nodiscard]] QDate getStartDate() const;
};

}
Expand Down
2 changes: 2 additions & 0 deletions models/include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class DateTime {
DateTime &operator+=(int other);
DateTime &operator-=(int other);

[[nodiscard]] QDateTime toQDateTime() const;

friend QTextStream& operator<<(QTextStream& os, const DateTime &dt);

private:
Expand Down
20 changes: 19 additions & 1 deletion models/src/transportSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ bool TransportSystem::isValid() const {
return routesAreValid && routeStopsAreValid && stopsAreValid && transfersAreValid && stopRoutesAreValid;
}

const Stop *TransportSystem::getStop(const QString &stopId) const {
const Stop *TransportSystem::getStopById(const QString &stopId) const {
for (auto &stop : stops) {
if (stop.id == stopId) {
return &stop;
Expand All @@ -184,4 +184,22 @@ const Stop *TransportSystem::getStop(const QString &stopId) const {
return nullptr;
}

const Stop *TransportSystem::getStopByName(const QString &stopName) const {
for (auto &stop : stops) {
if (stop.name == stopName) {
return &stop;
}
}
return nullptr;
}

QDate TransportSystem::getStartDate() const {
if (stopTimes.empty()) {
return {};
}
return stopTimes[0].arrivalTime.toQDateTime().date();
}



}
7 changes: 5 additions & 2 deletions models/src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ DateTime &DateTime::operator-=(int other) {
return *this;
}

QDateTime DateTime::toQDateTime() const {
return QDateTime::fromSecsSinceEpoch(timestamp);
}

QTextStream& operator<<(QTextStream& os, const DateTime &dt) {
QDateTime QTdt = QDateTime::fromSecsSinceEpoch(dt.timestamp);
return os << QTdt.toString();
return os << dt.toQDateTime().toString();
}

DateTime Ride::startTime() const {
Expand Down

0 comments on commit 0cb8cc2

Please sign in to comment.