adds upload cron && fixes date formatting

This commit is contained in:
Christian Beutel
2024-03-28 18:36:59 +01:00
parent 15dcc2a629
commit 1d8520fa67
11 changed files with 83 additions and 34 deletions

5
.gitignore vendored
View File

@@ -7,5 +7,10 @@ search/meilisearch
search/data.ms search/data.ms
search/dumps search/dumps
web/uploads/*
web/cookie.txt
run.sh run.sh
build*.sh build*.sh
data/

View File

@@ -53,6 +53,10 @@ services:
BODY_SIZE_LIMIT: Infinity BODY_SIZE_LIMIT: Infinity
PUBLIC_POCKETBASE_URL: http://db:8090 PUBLIC_POCKETBASE_URL: http://db:8090
PUBLIC_DISABLE_SIGNUP: false PUBLIC_DISABLE_SIGNUP: false
UPLOAD_USER: Flomp
UPLOAD_PASSWORD: 12345678
volumes:
- ./data/uploads:/app/uploads
ports: ports:
- "3000:3000" - "3000:3000"
networks: networks:

View File

@@ -6,8 +6,15 @@ RUN npm ci --omit=dev
EXPOSE 3000 EXPOSE 3000
ENV NODE_ENV=production ENV NODE_ENV=production
COPY ./cron.sh /etc/periodic/15min/cron
RUN chmod +x /etc/periodic/15min/cron
RUN mkdir /app/uploads
RUN apk add curl
ENV PUBLIC_POCKETBASE_URL=http://127.0.0.1:8090 ENV PUBLIC_POCKETBASE_URL=http://127.0.0.1:8090
ENV MEILI_URL=http://127.0.0.1:7700 ENV MEILI_URL=http://127.0.0.1:7700
ENV PUBLIC_DISABLE_SIGNUP=false ENV PUBLIC_DISABLE_SIGNUP=false
ENV UPLOAD_USER=
ENV UPLOAD_PASSWORD=
CMD [ "node", "build" ] CMD crond && node build

58
web/cron.sh Normal file
View File

@@ -0,0 +1,58 @@
#!/bin/ash
# API endpoint URL
API_URL="http://localhost:3000/api/v1"
# Folder containing files to upload
UPLOAD_FOLDER="/app/uploads"
# Credentials for login
USERNAME=$UPLOAD_USER
PASSWORD=$UPLOAD_PASSWORD
login() {
local username="$1"
local password="$2"
response=$(curl -c cookie.txt --location --request POST "$API_URL/auth/login" --header 'Content-Type: application/json' --data-raw "{\"username\": \"$username\", \"password\": \"$password\"}")
# Check if login was successful (look for "200 OK" in response headers)
if [ $? -eq 0 ] && [ "$(echo "$response" | grep -c "token")" -eq 1 ]; then
echo "Login successful. Cookie obtained."
else
echo "Login failed. Unable to obtain cookie."
exit 1
fi
}
# Function to upload file and delete if successful
upload_and_delete() {
local file="$1"
ls $file
# API call to upload file
response=$(curl -b cookie.txt --location --request PUT "$API_URL/trail/upload" --header 'Content-Type: application/gpx+xml' --data-binary "@$file")
# Check if API call was successful (status code 200)
if [ $? -eq 0 ] && [ "$(echo "$response" | grep -c "author")" -eq 1 ]; then
echo "File $file uploaded successfully."
# Delete the file
rm "$file"
echo "File $file deleted."
else
echo $response
echo "Failed to upload file $file."
fi
}
# Login to obtain cookie
login "$USERNAME" "$PASSWORD"
# Iterate over each file in the folder
for file in "$UPLOAD_FOLDER"/*; do
# Check if file exists and is a regular file
if [ -f "$file" ]; then
upload_and_delete "$file"
fi
done

10
web/package-lock.json generated
View File

@@ -15,7 +15,6 @@
"@types/leaflet.awesome-markers": "^2.0.28", "@types/leaflet.awesome-markers": "^2.0.28",
"@types/three": "^0.161.2", "@types/three": "^0.161.2",
"crypto-random-string": "^5.0.0", "crypto-random-string": "^5.0.0",
"date-fns": "^3.3.1",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet-gpx": "^1.7.0", "leaflet-gpx": "^1.7.0",
@@ -1757,15 +1756,6 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/date-fns": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz",
"integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",

View File

@@ -40,7 +40,6 @@
"@types/leaflet.awesome-markers": "^2.0.28", "@types/leaflet.awesome-markers": "^2.0.28",
"@types/three": "^0.161.2", "@types/three": "^0.161.2",
"crypto-random-string": "^5.0.0", "crypto-random-string": "^5.0.0",
"date-fns": "^3.3.1",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet-gpx": "^1.7.0", "leaflet-gpx": "^1.7.0",

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { SummitLog } from "$lib/models/summit_log"; import type { SummitLog } from "$lib/models/summit_log";
import { format, parse } from "date-fns"; import { parse } from "date-fns";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Dropdown, { type DropdownItem } from "../base/dropdown.svelte"; import Dropdown, { type DropdownItem } from "../base/dropdown.svelte";

View File

@@ -6,11 +6,10 @@
import { createForm } from "$lib/vendor/svelte-form-lib/index"; import { createForm } from "$lib/vendor/svelte-form-lib/index";
import { util } from "$lib/vendor/svelte-form-lib/util"; import { util } from "$lib/vendor/svelte-form-lib/util";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { date, object, string } from "yup";
import Datepicker from "../base/datepicker.svelte"; import Datepicker from "../base/datepicker.svelte";
import Modal from "../base/modal.svelte"; import Modal from "../base/modal.svelte";
import TextField from "../base/text_field.svelte"; import TextField from "../base/text_field.svelte";
import { date, object, string } from "yup";
import { parse } from "date-fns";
export let openModal: (() => void) | undefined = undefined; export let openModal: (() => void) | undefined = undefined;
export let closeModal: (() => void) | undefined = undefined; export let closeModal: (() => void) | undefined = undefined;
@@ -18,13 +17,7 @@
const summitLogSchema = object<SummitLog>({ const summitLogSchema = object<SummitLog>({
id: string().optional(), id: string().optional(),
date: date() date: date().required("Required").typeError($_("invalid-date")),
.transform((value, originalValue, context) => {
if (context.isType(value)) return value;
return parse(originalValue, "dd.MM.yyyy", new Date());
})
.required("Required")
.typeError($_("invalid-date")),
text: string().optional(), text: string().optional(),
}); });
@@ -37,6 +30,7 @@
}, },
}); });
$: form.set(util.cloneDeep($summitLog)); $: form.set(util.cloneDeep($summitLog));
$: console.log($summitLog);
</script> </script>
<Modal <Modal

View File

@@ -2,7 +2,7 @@ import { SummitLog } from "$lib/models/summit_log";
import { ClientResponseError } from "pocketbase"; import { ClientResponseError } from "pocketbase";
import { writable, type Writable } from "svelte/store"; import { writable, type Writable } from "svelte/store";
export const summitLog: Writable<SummitLog> = writable(new SummitLog(new Date().toISOString())); export const summitLog: Writable<SummitLog> = writable(new SummitLog(new Date().toISOString().substring(0, 10)));
export async function summit_logs_create(summitLog: SummitLog) { export async function summit_logs_create(summitLog: SummitLog) {
const r = await fetch('/api/v1/summit-log', { const r = await fetch('/api/v1/summit-log', {

View File

@@ -167,7 +167,7 @@ export async function trails_search_bounding_box(northEast: LatLng, southWest: L
export async function trails_show(id: string, loadGPX?: boolean, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) { export async function trails_show(id: string, loadGPX?: boolean, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f(`/api/v1/trail/${id}?` + new URLSearchParams({ const r = await f(`/api/v1/trail/${id}?` + new URLSearchParams({
expand: "category,waypoints,summit_logs,lists_via_trails", expand: "category,waypoints,summit_logs",
}), { }), {
method: 'GET', method: 'GET',
}) })

View File

@@ -40,7 +40,6 @@
import "$lib/vendor/leaflet-elevation/src/index.css"; import "$lib/vendor/leaflet-elevation/src/index.css";
import { createForm } from "$lib/vendor/svelte-form-lib"; import { createForm } from "$lib/vendor/svelte-form-lib";
import cryptoRandomString from "crypto-random-string"; import cryptoRandomString from "crypto-random-string";
import { format } from "date-fns";
import type { GPX, Icon, LeafletEvent, Map } from "leaflet"; import type { GPX, Icon, LeafletEvent, Map } from "leaflet";
import "leaflet.awesome-markers/dist/leaflet.awesome-markers.css"; import "leaflet.awesome-markers/dist/leaflet.awesome-markers.css";
import "leaflet/dist/leaflet.css"; import "leaflet/dist/leaflet.css";
@@ -384,14 +383,8 @@
savedWaypoint.marker = marker; savedWaypoint.marker = marker;
} }
function beforeSummitLogModalOpen() {
summitLog.set(new SummitLog(format(new Date(), "yyyy-MM-dd")));
openSummitLogModal();
}
function saveSummitLog(e: CustomEvent<SummitLog>) { function saveSummitLog(e: CustomEvent<SummitLog>) {
const savedSummitLog = e.detail; const savedSummitLog = e.detail;
savedSummitLog.date = format(savedSummitLog.date, "yyyy-MM-dd");
let editedSummitLogIndex = $form.expand.summit_logs.findIndex( let editedSummitLogIndex = $form.expand.summit_logs.findIndex(
(s) => s.id == savedSummitLog.id, (s) => s.id == savedSummitLog.id,
); );
@@ -413,7 +406,6 @@
e: CustomEvent<{ text: string; value: string }>, e: CustomEvent<{ text: string; value: string }>,
) { ) {
if (e.detail.value === "edit") { if (e.detail.value === "edit") {
currentSummitLog.date = format(currentSummitLog.date, "yyyy-MM-dd");
summitLog.set(currentSummitLog); summitLog.set(currentSummitLog);
openSummitLogModal(); openSummitLogModal();
} else if (e.detail.value === "delete") { } else if (e.detail.value === "delete") {
@@ -618,7 +610,7 @@
<button <button
class="btn-secondary" class="btn-secondary"
type="button" type="button"
on:click={beforeSummitLogModalOpen} on:click={openSummitLogModal}
><i class="fa fa-plus mr-2"></i>{$_("add-entry")}</button ><i class="fa fa-plus mr-2"></i>{$_("add-entry")}</button
> >
{#if $lists.length} {#if $lists.length}