1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
|
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <ctime>
#include <filesystem>
#include <regex>
#include <QApplication>
#include <QCompleter>
#include <QStringList>
#include <QColor>
#include <QPalette>
#include <QAbstractItemView>
#include <QRandomGenerator>
#include "include/json.hpp"
#include "mainwindow.h"
#include "./ui_mainwindow.h"
using namespace std;
using json = nlohmann::json;
static inline void PrintConst(string &pathc); //formats the template file with the requested data and prints out the constellation info
static string RandomConst(); //select a random constellation from the available ones
static inline void PrintList(); //prints out the list of the available constellations
static void Error(string &err, int type); //shows an error message
static void Help(); //prints out the help message
#ifdef _WIN32
string path = "C:\\starfetch\\";
string SEP = "\\";
#else
string path = "/usr/local/share/starfetch/";
string SEP = "/";
#endif // _WIN32
static QString oldText = "";
static QStringList wordList = {
"help", "-r", "-l", "-h", "random", "list", "-n antlia",
"-n apus", "-n aquarius", "-n ara", "-n aries", "-n bootes", "-n cancer", "-n canes_venatici", "-n cassiopeia",
"-n corona_borealis", "-n crux", "-n cygnus", "-n gemini", "-n leo", "-n libra", "-n lupus", "-n lyra",
"-n monoceros", "-n ophiuchus", "-n orion", "-n pisces", "-n sagittarius", "-n scorpio", "-n taurus", "-n ursa_major",
"-n ursa_minor", "-n virgo"
};
static QCompleter *completer = new QCompleter(wordList, nullptr);
Ui::MainWindow *UI;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
UI = ui;
QPalette p = ui->textEdit->palette();
p.setColor(QPalette::Base, Qt::black);
p.setColor(QPalette::Text, Qt::green);
ui->textEdit->setPalette(p);
ui->textEdit->setText(static_cast<QString>("Type 'help' to see the available command line options"));
ui->lineEdit->setCompleter(completer);
completer->popup()->setStyleSheet("background-color:rgb(54, 57, 63); color:white;");
connect(ui->lineEdit, &QLineEdit::returnPressed, this, &MainWindow::on_pushButton_clicked);
}
MainWindow::~MainWindow()
{
delete completer;
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
std::string pathc = path; //path to the constellation file
std::string userInput = static_cast<std::string>(ui->lineEdit->text().toStdString());
if (userInput.empty())
{
return;
}
if(userInput == "-r" || userInput == "random") //if there's no additional arguments
{
pathc += RandomConst(); //selects a random constellation
}
else if (userInput == "-h" || userInput == "help")
{
Help();
ui->lineEdit->setText(static_cast<QString>(""));
return;
}
else if (userInput.find("-n ") != std::string::npos)
{
pathc += "constellations" + SEP; //updating the path to the constellations folder
string subStr = std::regex_replace(userInput, std::regex("-n "), "");
pathc += subStr; //adding the name of the requested constellation to the path
pathc += ".json";
}
else if (userInput == "-l" || userInput == "list")
{
PrintList();
ui->lineEdit->setText(static_cast<QString>(""));
return;
}
else
{
Error(userInput, 1); //if the reqeusted option isn't recognized, an error occours
ui->lineEdit->setText(static_cast<QString>(""));
return;
}
ui->lineEdit->setText(static_cast<QString>(""));
PrintConst(pathc); //prints the constellation
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
static inline void PrintConst(string &pathc)
{
ifstream c(pathc); //opens the file containing constellation info
ifstream f(path+"template"); //opens the output template file
stringstream strStream;
string s, l, subStr;
json j;
if(f.is_open())
{
strStream << f.rdbuf(); //read the template
s = strStream.str(); //converts it to a string
replace(s.begin(), s.end(), '^', ' '); //replace '^' with the '\e' to print bold/colored text
f.close(); //closes the template
}
if(c.is_open())
{
c >> j; //parse the selected JSON file
//fills the template with dats
s.replace(s.find("%0"), string("%0").size(), j["title"].get<string>());
s.replace(s.find("%11"), string("%11").size(), j["name"].get<string>());
s.replace(s.find("%12"), string("%12").size(), j["quadrant"].get<string>());
s.replace(s.find("%13"), string("%13").size(), j["right ascension"].get<string>());
s.replace(s.find("%14"), string("%14").size(), j["declination"].get<string>());
s.replace(s.find("%15"), string("%15").size(), j["area"].get<string>());
s.replace(s.find("%16"), string("%16").size(), j["main stars"].get<string>());
//renders the constellation's graph from the coordinates specified in the JSON file
for(int i=1;i<=10;i++) //for each of the lines (10)
{
l="";
for(int k=1;k<=22;k++) //for each of the columns of the graph (22)
//if the JSON file specifies a star at position k
if(j["graph"]["line"+to_string(i)].find(to_string(k)) != j["graph"]["line"+to_string(i)].end())
l+=j["graph"]["line"+to_string(i)][to_string(k)].get<string>(); //put the star (which is stored into the JSON fine, might change this in the future)
else
for (int z=1;z<4;z++)
l+=" "; //put a space
for (int x=1;x<22;x++)
l+=" ";
//insert the line into the template
s.replace(s.find("%"+to_string(i)), string("%"+to_string(i)).size(), l);
}
c.close();
if (s.find("requestedColor") != std::string::npos)
{
s = std::regex_replace(s, std::regex("requestedColor"), "");
s = std::regex_replace(s, std::regex("0m"), "");
s = std::regex_replace(s, std::regex("\\["), "");
s = std::regex_replace(s, std::regex("│"), "");
s = std::regex_replace(s, std::regex("──"), "");
s = std::regex_replace(s, std::regex("┘"), "");
s = std::regex_replace(s, std::regex("└"), "");
s = std::regex_replace(s, std::regex("┌"), "");
s = std::regex_replace(s, std::regex("┐"), "");
s = std::regex_replace(s, std::regex("─"), "");
}
UI->textEdit->setText(static_cast<QString>(s.c_str())); //prints the output
}
}
static string RandomConst()
{
size_t pos;
string s;
//SHOULD BE IMPROVED IN THE FUTURE
//gets every constellation name in the "constellation/" directory, and exits when two randomly generated numbers are equal, resulting in picking a random file
for (const auto & entry : filesystem::directory_iterator(path+"constellations" + SEP))
{
pos = entry.path().u8string().find("constellations" + SEP);
s = entry.path().u8string().substr(pos);
if(s != "constellations/.DS_Store" && QRandomGenerator::global()->bounded(0, 11) == QRandomGenerator::global()->bounded(0, 11))
break;
}
return s;
}
static inline void PrintList()
{
string s;
oldText = "";
QString outStr = static_cast<string>("✦ Available constellations:\n").c_str();
UI->textEdit->setText(outStr + oldText + static_cast<QString>("\n"));
//prints every constellation name from the files name in the "constellations/" directory
for (const auto & entry : filesystem::directory_iterator(path+"constellations" + SEP))
{
s = entry.path().u8string().substr(entry.path().u8string().find("constellations" + SEP)+15); //from "/usr/local/opt/starfetch/res/constellations/xxxxxx" to "xxxxxx"
s = s.substr(0, s.length()-5);
if(s != ".DS_")
{
oldText += static_cast<QString>(s.c_str()) + static_cast<QString>("\n");
UI->textEdit->setText(outStr + oldText);
}
}
oldText = "";
}
static void Error(string &err, int code)
{
switch(code) //each error has a specific code
{
case 0: //0 for the missing input
UI->textEdit->setText(static_cast<QString>("Error: you must input a constellation name after -n."));
break;
case 1: //1 for the invalid argument
UI->textEdit->setText(static_cast<QString>(static_cast<string>("Error: '" + err + "' isn't a valid argument.").c_str()));
break;
case 2: //2 for the invalid constellation name
UI->textEdit->setText(static_cast<QString>("Error: the constellation you asked for isn't recognized."));
break;
}
Help(); //after any error occours, the help message is shown
}
static void Help()
{
std::ostringstream ss;
ifstream f(path + "help_message.txt");
ss << f.rdbuf();
string str = ss.str();
UI->textEdit->setText(static_cast<QString>(str.c_str()));
f.close();
}
|