Compare commits

...

10 Commits

Author SHA1 Message Date
c757102256 Merge pull request #1 from Thepuppetqueen57/build-script
Added a build script
2026-01-14 21:06:00 -07:00
7b31b2a1b1 Added a build script
Use -r to run the program after building and use -c to clear the build
folder after running (just after building if u dont use -r)
2026-01-14 19:59:44 -08:00
e63912fac5 Use custom icons for navbar 2026-01-13 18:00:10 -07:00
e7a37a7cee Make this work properly on windows 2026-01-13 17:20:59 -07:00
df4a86216b Add a simple get() func using libcurl 2026-01-13 15:27:08 -07:00
efb32eb0f7 Fix being able to break out of the parser 2026-01-13 15:13:45 -07:00
a4d7484952 Set minimum size 2026-01-13 14:37:48 -07:00
b999efe016 Add testing parser 2026-01-13 14:34:39 -07:00
fd405bd9fd Forgot to set window title 2026-01-13 14:20:44 -07:00
e93cb69c55 Format on save 2026-01-13 14:12:00 -07:00
14 changed files with 180 additions and 16 deletions

3
.gitignore vendored
View File

@@ -11,6 +11,9 @@ CTestTestfile.cmake
_deps _deps
CMakeUserPresets.json CMakeUserPresets.json
build/ build/
.vs/
CMakeSettings.json
.DS_STORE
# CLion # CLion
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can # JetBrains specific template is maintained in a separate JetBrains.gitignore that can

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 4.2.1) cmake_minimum_required(VERSION 4.1.1)
project(CrabCrawler VERSION 0.1 LANGUAGES CXX) project(CrabCrawler VERSION 0.1 LANGUAGES CXX)
@@ -6,14 +6,27 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets) find_package(Qt6 REQUIRED COMPONENTS Widgets)
find_package(CURL REQUIRED)
qt_standard_project_setup() qt_standard_project_setup()
qt_add_resources(RESOURCES resources.qrc)
add_executable(CrabCrawler set(SOURCES
src/main.cpp src/main.cpp
src/ui/navbar.cpp src/ui/navbar.cpp
src/ui/content.cpp
${RESOURCES}
) )
if(WIN32)
add_executable(CrabCrawler WIN32 ${SOURCES})
else()
add_executable(CrabCrawler ${SOURCES})
endif()
target_link_libraries(CrabCrawler target_link_libraries(CrabCrawler
PRIVATE Qt6::Widgets PRIVATE Qt6::Widgets
${CURL_LIBRARIES}
) )

34
debug-build.sh Executable file
View File

@@ -0,0 +1,34 @@
# This has only been tested on Linux Mint
#!/bin/bash
CLEAR_BUILD=false
RUN_PROGRAM=false
# Checks flags
# Idk why case statements look so weird in bash but it works lol
# Use -r to run the program after building and use -c to clear the build folder after running
while getopts "cr" opt; do
case "$opt" in
c)
CLEAR_BUILD=true
;;
r)
RUN_PROGRAM=true
;;
esac
done
# Builds Crab Crawler
cmake -DCMAKE_BUILD_TYPE=Release -S ./ -B ./build
cmake --build ./build
# Runs the program if the -r flag is provided
if $RUN_PROGRAM; then
echo "Running the Build..."
./build/CrabCrawler
fi
if $CLEAR_BUILD; then
echo "Clearing build folder..."
rm -rf build
fi

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path fill="#ffffff" d="M201.4 297.4C188.9 309.9 188.9 330.2 201.4 342.7L361.4 502.7C373.9 515.2 394.2 515.2 406.7 502.7C419.2 490.2 419.2 469.9 406.7 457.4L269.3 320L406.6 182.6C419.1 170.1 419.1 149.8 406.6 137.3C394.1 124.8 373.8 124.8 361.3 137.3L201.3 297.3z"/></svg>

After

Width:  |  Height:  |  Size: 485 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path fill="#ffffff" d="M439.1 297.4C451.6 309.9 451.6 330.2 439.1 342.7L279.1 502.7C266.6 515.2 246.3 515.2 233.8 502.7C221.3 490.2 221.3 469.9 233.8 457.4L371.2 320L233.9 182.6C221.4 170.1 221.4 149.8 233.9 137.3C246.4 124.8 266.7 124.8 279.2 137.3L439.2 297.3z"/></svg>

After

Width:  |  Height:  |  Size: 485 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path fill="#ffffff" d="M129.9 292.5C143.2 199.5 223.3 128 320 128C373 128 421 149.5 455.8 184.2C456 184.4 456.2 184.6 456.4 184.8L464 192L416.1 192C398.4 192 384.1 206.3 384.1 224C384.1 241.7 398.4 256 416.1 256L544.1 256C561.8 256 576.1 241.7 576.1 224L576.1 96C576.1 78.3 561.8 64 544.1 64C526.4 64 512.1 78.3 512.1 96L512.1 149.4L500.8 138.7C454.5 92.6 390.5 64 320 64C191 64 84.3 159.4 66.6 283.5C64.1 301 76.2 317.2 93.7 319.7C111.2 322.2 127.4 310 129.9 292.6zM573.4 356.5C575.9 339 563.7 322.8 546.3 320.3C528.9 317.8 512.6 330 510.1 347.4C496.8 440.4 416.7 511.9 320 511.9C267 511.9 219 490.4 184.2 455.7C184 455.5 183.8 455.3 183.6 455.1L176 447.9L223.9 447.9C241.6 447.9 255.9 433.6 255.9 415.9C255.9 398.2 241.6 383.9 223.9 383.9L96 384C87.5 384 79.3 387.4 73.3 393.5C67.3 399.6 63.9 407.7 64 416.3L65 543.3C65.1 561 79.6 575.2 97.3 575C115 574.8 129.2 560.4 129 542.7L128.6 491.2L139.3 501.3C185.6 547.4 249.5 576 320 576C449 576 555.7 480.6 573.4 356.5z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

7
resources.qrc Normal file
View File

@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>icons/angle-left-solid-full.svg</file>
<file>icons/angle-right-solid-full.svg</file>
<file>icons/arrows-rotate-solid-full.svg</file>
</qresource>
</RCC>

View File

@@ -4,13 +4,17 @@
#include <QDebug> #include <QDebug>
#include "ui/navbar.h" #include "ui/navbar.h"
#include "ui/content.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
app.setStyle("fusion");
QWidget window; QWidget window;
window.resize(800, 500); window.setWindowTitle("Crab Crawler");
window.setMinimumSize(800, 600);
window.resize(800, 600);
auto *layout = new QVBoxLayout(&window); auto *layout = new QVBoxLayout(&window);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
@@ -18,11 +22,12 @@ int main(int argc, char *argv[])
auto *navBar = new NavBar(&window); auto *navBar = new NavBar(&window);
layout->addWidget(navBar); layout->addWidget(navBar);
layout->addStretch();
QObject::connect(navBar, &NavBar::addressEntered, [](const QString &text) { auto *content = new Content(&window);
qDebug() << "navigate to:" << text; layout->addWidget(content, 1);
});
QObject::connect(navBar, &NavBar::addressEntered, [content](const QString &text)
{ qDebug() << "navigate to:" << text; });
window.show(); window.show();
return app.exec(); return app.exec();

31
src/ui/content.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "content.h"
#include <QVBoxLayout>
#include <QDebug>
Content::Content(QWidget *parent) : QWidget(parent)
{
auto *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
display = new QTextEdit(this);
display->setReadOnly(true);
layout->addWidget(display);
}
void Content::parseCrabcontent(const QString &input)
{
QStringList lines = input.split('\n', Qt::SkipEmptyParts);
QString result;
for (const QString &line : lines)
{
if (line.startsWith("text:"))
{
result += "<p>" + line.mid(5).trimmed().toHtmlEscaped() + "</p>\n";
}
}
display->setHtml(result);
}

17
src/ui/content.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include <QWidget>
#include <QString>
#include <QTextEdit>
class Content : public QWidget
{
Q_OBJECT
public:
explicit Content(QWidget *parent = nullptr);
void parseCrabcontent(const QString &input);
private:
QTextEdit *display;
};

View File

@@ -9,19 +9,22 @@ NavBar::NavBar(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
auto *layout = new QHBoxLayout(this); auto *layout = new QHBoxLayout(this);
layout->setContentsMargins(6, 6, 6, 6); layout->setContentsMargins(2, 6, 6, 6);
layout->setSpacing(6); layout->setSpacing(2);
m_back = new QToolButton(this); m_back = new QToolButton(this);
m_back->setIcon(style()->standardIcon(QStyle::SP_ArrowBack)); m_back->setIcon(QIcon(":/icons/angle-left-solid-full.svg"));
m_back->setIconSize(QSize(24, 24));
m_back->setAutoRaise(true); m_back->setAutoRaise(true);
m_forward = new QToolButton(this); m_forward = new QToolButton(this);
m_forward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward)); m_forward->setIcon(QIcon(":/icons/angle-right-solid-full.svg"));
m_forward->setIconSize(QSize(24, 24));
m_forward->setAutoRaise(true); m_forward->setAutoRaise(true);
m_refresh = new QToolButton(this); m_refresh = new QToolButton(this);
m_refresh->setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); m_refresh->setIcon(QIcon(":/icons/arrows-rotate-solid-full.svg"));
m_refresh->setIconSize(QSize(24, 24));
m_refresh->setAutoRaise(true); m_refresh->setAutoRaise(true);
m_address = new QLineEdit(this); m_address = new QLineEdit(this);
@@ -37,9 +40,8 @@ NavBar::NavBar(QWidget *parent)
connect(m_forward, &QToolButton::clicked, this, &NavBar::forwardClicked); connect(m_forward, &QToolButton::clicked, this, &NavBar::forwardClicked);
connect(m_refresh, &QToolButton::clicked, this, &NavBar::refreshClicked); connect(m_refresh, &QToolButton::clicked, this, &NavBar::refreshClicked);
connect(m_address, &QLineEdit::returnPressed, this, [this] { connect(m_address, &QLineEdit::returnPressed, this, [this]
emit addressEntered(m_address->text()); { emit addressEntered(m_address->text()); });
});
} }
QLineEdit *NavBar::addressBar() const QLineEdit *NavBar::addressBar() const

46
src/util/http.c Normal file
View File

@@ -0,0 +1,46 @@
#include <curl/curl.h>
struct HttpResponse
{
long status;
char *body;
};
static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t total = size * nmemb;
struct HttpResponse *resp = (struct HttpResponse *)userdata;
size_t old_len = resp->body ? strlen(resp->body) : 0;
char *new_body = (char *)realloc(resp->body, old_len + total + 1);
if (!new_body)
return 0;
resp->body = new_body;
memcpy(resp->body + old_len, ptr, total);
resp->body[old_len + total] = '\0';
return total;
}
struct HttpResponse get(const char *url)
{
struct HttpResponse resp = {0, NULL};
CURL *curl = curl_easy_init();
if (!curl)
return resp;
resp.body = (char *)malloc(1);
resp.body[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp.status);
curl_easy_cleanup(curl);
return resp;
}