Skip to content

Commit

Permalink
Now links can be saved to a file
Browse files Browse the repository at this point in the history
  • Loading branch information
ngn13 committed Feb 4, 2024
1 parent 616e4e4 commit 6ade637
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
kisalt
data/
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM alpine as build

RUN apk update && apk upgrade
RUN apk add --no-cache build-base wget boost-dev openssl-dev
RUN apk add --no-cache build-base wget boost-dev openssl-dev jsoncpp-dev

WORKDIR /app
COPY src ./src
Expand All @@ -25,5 +25,5 @@ RUN make && rm -r crow
FROM alpine as main
COPY --from=build /app /
EXPOSE 8080
RUN apk add --no-cache libstdc++ libgcc libcrypto3
RUN apk add --no-cache libstdc++ libgcc libcrypto3 jsoncpp
ENTRYPOINT ["/kisalt"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ SRCS:=$(wildcard src/*.cpp)
CC=g++

kisalt: $(SRCS)
$(CC) -o $@ $^ -lcrypto
$(CC) -o $@ $^ -lcrypto -ljsoncpp
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,22 @@ kisalt is a simple link shortener written with [Crow](https://github.com/CrowCpp
You can easily deploy the app with docker and place it behind a proxy:
```bash
docker run -d --restart=unless-stopped \
-v $PWD/data:/data \
-p 127.0.0.1:8080:8080 \
-e URL=https://k.example.com \
ghcr.io/ngn13/kisalt
```
Change the `URL` accordingly.
Change the `URL` accordingly.

To disable the saving the links, you can use the `NOSAVE` option.
A volume is not needed when using this option:
```bash
docker run -d --restart=unless-stopped \
-p 127.0.0.1:8080:8080 \
-e URL=https://k.example.com \
-e NOSAVE=1 \
ghcr.io/ngn13/kisalt
```

### Usage
You can use the web interface to shorten links, or you can directly use the API:
Expand All @@ -22,5 +33,5 @@ curl https://k.example.com/add\?url=<url>
```

### Todo
- Save links to a database
- ~~Save links to a database~~
- Better web UI
4 changes: 4 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "config.hpp"

std::string envurl = nullptr==getenv("URL") ? "http://127.0.0.1:8080/" : getenv("URL");
bool envsave = nullptr==getenv("NOSAVE");
5 changes: 5 additions & 0 deletions src/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once
#include <string>

extern bool envsave;
extern std::string envurl;
94 changes: 85 additions & 9 deletions src/link.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,101 @@
#include <openssl/sha.h>
#include <json/json.h>
#include "config.hpp"
#include <algorithm>
#include <iostream>
#include "link.hpp"
#include "log.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <string>
#include <random>
#include <list>

std::list<struct Link> links;

std::string find_org(std::string org) {
for(auto const& i : links) {
if(i.org.compare(org)==0)
return i.url;
}
return "";
}

std::string find_url(std::string url) {
for(auto const& i : links) {
if(i.url.compare(url)==0)
return i.org;
}
return "";
}

bool load_links() {
std::ifstream stream = std::ifstream("data/links.json");
if(stream.fail())
return false;

std::string json, buf = std::string(4096, '\0');
while (stream.read(& buf[0], 4096)) {
json.append(buf, 0, stream.gcount());
}
json.append(buf, 0, stream.gcount());
stream.close();

Json::Value root;
JSONCPP_STRING err;
Json::CharReaderBuilder builder;

const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
if (!reader->parse(json.c_str(), json.c_str() + json.length(),
&root, &err)) {
error("Cannot load saved links file");
return false;
}

if(root["links"].empty())
return false;

for(auto const& l : root["links"]){
links.push_front({
.org = l["org"].asString(),
.url = l["url"].asString(),
});
}

info("Loaded total of %d saved links", root["links"].size());
return true;
}

bool save_links() {
if(!envsave)
return true;

Json::Value root, link;
for(auto const& i : links) {
link["url"] = i.url;
link["org"] = i.org;
root["links"].append(link);
}

Json::StreamWriterBuilder builder;
const std::string json = Json::writeString(builder, root);
std::ofstream jsonfile;

jsonfile.open("data/links.json");
if(jsonfile.fail()){
error("Failed to open the links file");
return false;
}

jsonfile << json;
jsonfile.close();
return true;
}

std::string add_url(std::string org) {
std::string found = find_url(org);
std::string found = find_org(org);
if(!found.empty())
return found;

Expand All @@ -37,13 +120,6 @@ std::string add_url(std::string org) {
.url = url,
});

save_links();
return url;
}

std::string find_url(std::string url) {
for(auto const& i : links) {
if(i.url.compare(url)==0)
return i.org;
}
return "";
}
9 changes: 9 additions & 0 deletions src/link.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
#pragma once
#include <openssl/sha.h>
#include <json/json.h>
#include "config.hpp"
#include <algorithm>
#include <iostream>
#include "link.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <string>
#include <random>
#include <list>

extern std::list<struct Link> links;
Expand All @@ -13,3 +21,4 @@ struct Link {

std::string add_url(std::string);
std::string find_url(std::string);
bool load_links();
26 changes: 26 additions & 0 deletions src/log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <cstdarg>
#include "log.hpp"
#include <cstdio>
#include <string>

void error(std::string msg, ...){
va_list args;
va_start(args, msg);

printf(BOLD RED "ERROR: " RESET);
vprintf(msg.c_str(), args);
printf(RESET"\n");

va_end(args);
}

void info(std::string msg, ...){
va_list args;
va_start(args, msg);

printf(BOLD BLUE "INFO : " RESET);
vprintf(msg.c_str(), args);
printf(RESET"\n");

va_end(args);
}
12 changes: 12 additions & 0 deletions src/log.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once
#include <cstdarg>
#include <cstdio>
#include <string>

#define RED "\x1b[31m"
#define BOLD "\x1b[1m"
#define BLUE "\x1b[34m"
#define RESET "\x1b[0m"

void error(std::string, ...);
void info(std::string, ...);
12 changes: 10 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <crow/settings.h>
#include <crow/app.h>
#include "config.hpp"
#include "link.hpp"
#include "log.hpp"
#include <crow.h>
#include <random>

std::string envurl = nullptr==getenv("URL") ? "http://127.0.0.1:8080/" : getenv("URL");

std::string join_url(std::string url) {
if(envurl[envurl.length()-1] == '/')
return envurl+url;
Expand All @@ -15,7 +15,15 @@ std::string join_url(std::string url) {
int main(){
crow::SimpleApp app;
app.loglevel(crow::LogLevel::Warning);
if(!envsave){
info("NOSAVE is set, not loading any saved links");
goto SKIP_LOAD;
}

if(!load_links())
info("No saved links, loading an empty list");

SKIP_LOAD:
CROW_ROUTE(app, "/add")([](const crow::request& req, crow::response& res){
char* url = req.url_params.get("url");

Expand Down
4 changes: 3 additions & 1 deletion static/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ form input {
font-size: 20px;
outline: none;
border: solid 1px #DFDFDF;
border-radius: 5px;
color: white;
padding: 10px;
}

form button {
border-radius: 5px;
border: none;
background: #101010;
background: none;
padding: 10px;
font-size: 20px;
outline: none;
Expand Down
2 changes: 1 addition & 1 deletion static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/ngn13/kisalt/publish.yml">
</div>
<form id="form">
<input id="url" placeholder="enter a URL" type="text">
<input id="url" placeholder="enter a URL" type="text" required>
<button id="btn" type="submit">submit</button>
</form>
</main>
Expand Down

0 comments on commit 6ade637

Please sign in to comment.