Update all dependencies and change language to EN

Update bootstrap required a lot of template work, so I had no change to
split the commit in two separate commits to rebase the language change.
This means, yenu is EN only by now.
This commit is contained in:
Aaron Fischer 2021-07-31 00:05:13 +02:00
parent 1b3b82c7c9
commit 9261893874
13 changed files with 188 additions and 171 deletions

View file

@ -1,38 +1,45 @@
;;; We need to allow http connections because some dependencies are fetched
;;; over http instead of https. See here for more detail:
;;; https://github.com/technomancy/leiningen/blob/master/doc/FAQ.md
(require 'cemerick.pomegranate.aether)
(cemerick.pomegranate.aether/register-wagon-factory!
"http" #(org.apache.maven.wagon.providers.http.HttpWagon.))
(defproject yenu "1.0.1"
:description "yenu -- The image sharing tool for friends"
:url "https://yenu.de/"
:dependencies [[bouncer "1.0.1"]
[compojure "1.6.1"]
[conman "0.7.8"]
[cprop "0.1.11"]
[luminus-immutant "0.2.4"]
[luminus-migrations "0.5.0"]
[luminus-nrepl "0.1.4"]
[metosin/ring-http-response "0.9.0"]
[mount "0.1.12"]
[org.clojure/clojure "1.9.0"]
[org.clojure/tools.cli "0.3.5"]
[org.clojure/tools.logging "0.4.0"]
[org.webjars/jquery "3.3.1"]
[org.webjars/bootstrap "4.1.0"]
[compojure "1.6.2"]
[conman "0.9.1"]
[cprop "0.1.18"]
[luminus-immutant "0.2.5"]
[luminus-migrations "0.7.1"]
[luminus-nrepl "0.1.7"]
[metosin/ring-http-response "0.9.2"]
[mount "0.1.16"]
[clojure.java-time "0.3.2"]
[org.clojure/clojure "1.10.3"]
[org.clojure/tools.cli "1.0.206"]
[org.clojure/tools.logging "1.1.0"]
[org.webjars/jquery "3.6.0"]
[org.webjars/bootstrap "5.0.1"]
[org.webjars/webjars-locator-jboss-vfs "0.1.0"]
[org.webjars.bower/tether "1.4.3"]
[org.webjars.bower/tether "1.4.7"]
[org.webjars.bower/font-awesome "4.7.0"]
[org.xerial/sqlite-jdbc "3.21.0"]
[org.xerial/sqlite-jdbc "3.36.0"]
[ring-webjars "0.2.0"]
[ring-middleware-format "0.7.2"]
[ring/ring-core "1.6.3"]
[ring/ring-defaults "0.3.1"]
[selmer "1.11.7"]
[ring-middleware-format "0.7.4"]
[ring/ring-core "1.9.3"]
[ring/ring-defaults "0.3.3"]
[selmer "1.12.44"]
[hiccup "1.0.5"]
[image-resizer "0.1.10"]
[me.raynes/fs "1.4.6"] ;; R.I.P. Anthony!
[digest "1.4.8"]
[markdown-clj "1.0.2"]
[digest "1.4.10"]
[markdown-clj "1.10.5"]
[clj-exif-orientation "0.2.1"]
[clj-time "0.14.3"]
[buddy/buddy-auth "2.1.0"]]
[buddy/buddy-auth "3.0.1"]]
:min-lein-version "2.0.0"
@ -43,11 +50,11 @@
:main yenu.core
:migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}
:plugins [[lein-cprop "1.0.1"]
[migratus-lein "0.4.3"]
:plugins [[lein-cprop "1.0.3"]
[migratus-lein "0.7.3"]
[lein-immutant "2.1.0"]
[lein-sassc "0.10.4"]
[lein-auto "0.1.2"]]
[lein-sassc "0.10.5"]
[lein-auto "0.1.3"]]
:sassc
[{:src "resources/scss/screen.scss"
:output-to "resources/public/css/screen.css"

View file

@ -2,51 +2,49 @@
{% block content %}
{% if image %}
<h1>Bild editieren</h1>
<p>Hier kann ein bestehendes Bild bearbeitet werden. Das Bild selbst kann nicht
verändert werden (hierzu muss das Bild gelöscht und neu angelegt werden)</p>
<h1>Edit image</h1>
<p>Edit an image metadata. To change the image itself, you need to delete and add a new one.</p>
{% else %}
<h1>Bild hochladen</h1>
<p>Hier kann ein neues Bild der Gallerie hinzugefügt werden. Dabei sind alle
gängigen Bildformate und Auflösungen möglich. Das hochgeladene Bild wird
zugeschnitten (Thumbnail) und skaliert (Detailseite).</p>
<h1>Upload image</h1>
<p>Here you can add a new image to the gallery. You can use all common image types. The uploaded
image will be cropped (Thumbnail) and resized (detail image).</p>
{% endif %}
<form action="{% if image %}/edit/{{ image.id }}{% else %}/upload{% endif %}" enctype="multipart/form-data" method="POST" class="form-horizontal">
{% csrf-field %}
{% if not image %}
<div class="form-group">
<label for="file" class="sr-only">Bild</label>
<div class="mb-3">
<label for="file" class="form-label sr-only">Image</label>
<input id="file" class="form-control" name="file" type="file" />
</div>
{% endif %}
<div class="form-group">
<label for="title">Bildüberschrift</label>
<div class="mb-3">
<label for="title" class="form-label">Image title</label>
<input type="text" name="title" class="form-control"
value="{{ image.title }}"
placeholder="Leer lassen für Dateiname">
placeholder="Leave empty for filename">
</div>
<div class="form-group">
<label for="description">Beschreibung (optional)</label>
<div class="mb-3">
<label for="description" clas="form-label">Description (optional)</label>
<textarea name="description" class="form-control" rows="4">{{image.description }}</textarea>
</div>
<div class="form-group">
<label for="tags">Tags</label>
<div class="mb-3">
<label for="tags" class="form-label">Tags</label>
<input type="text" id="tags" name="tags" class="form-control"
value="{% if tags %}{% for tag in tags %}{{ tag.tagname }} {% endfor %}{% endif %}"
placeholder="Trennen mit Leerzeichen oder Kommas">
placeholder="Separate with space or comma">
</div>
<button type="submit" class="btn btn-success">
<span class="fa fa-floppy-o"></span>
{% if image %}
Bild bearbeiten
Edit image
{% else %}
Bild hochladen
Upload image
{% endif %}
</button>
</form>

View file

@ -1,32 +1,34 @@
{% extends "layout.html" %}
{% block content %}
<h1>Kommentarstream</h1>
<h1>Comments</h1>
<ul class="list-unlisted">
{% for comment in comments %}
<hr/>
<li class="media mb-3">
<img src="https://robohash.org/{{ comment.author }}?size=40x40" class="d-flex mr-3"/>
<div class="media-body">
<i>{{ comment.created_at|parse-date|date:"dd-MM-yyyy HH:mm" }} Uhr</i>
von <strong>{{ comment.author }}</strong>
<br/>
<small><a href="/show/{{ comment.image_id }}#{{ comment.id }}">
{% if comment.title %}
{{ comment.title }}
{% else %}
Zum Bild
{% endif %}
</a>
</small>
<div>
{{ comment.comment|markdown-to-html|safe }}
</div>
<div class="container">
{% for comment in comments %}
<hr/>
<div class="row">
<div class="col-1">
<img src="https://robohash.org/{{ comment.author }}?size=40x40" class="d-flex mr-3"/>
</div>
<div class="col-11">
<i>{{ comment.created_at|parse-date|date:"dd-MM-yyyy HH:mm" }}</i>
from <strong>{{ comment.author }}</strong>
<br/>
<small><a href="/show/{{ comment.image_id }}#{{ comment.id }}">
{% if comment.title %}
{{ comment.title }}
{% else %}
Zum Bild
{% endif %}
</a>
</small>
<div>
{{ comment.comment|markdown-to-html|safe }}
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}

View file

@ -2,20 +2,20 @@
{% block content %}
<div class="btn-group float-right clearfix" role="group">
<div class="btn-group pull-right clearfix" role="group">
{% if next-image %}
<a class="btn btn-secondary" href="/show/{{ next-image.id }}" id="next-image">
{% else %}
<a class="btn btn-secondary disabled" href="#">
{% endif %}
<span class="fa fa-arrow-left"></span> Neuer
<span class="fa fa-arrow-left"></span> Newer
</a>
<a class="btn btn-secondary" href="/">
<span class="fa fa-home"></span>
Gallerie
Gallery
</a>
{% if prev-image %}
@ -24,7 +24,7 @@
<a class="btn btn-secondary disabled" href="#">
{% endif %}
Älter <span class="fa fa-arrow-right"></span>
Older <span class="fa fa-arrow-right"></span>
</a>
</div>
@ -47,60 +47,63 @@
<div id="detail-attributes">
{% ifequal identity ":creator" %}
<div class="btn-group float-right clearfix" role="group">
<div class="btn-group pull-right clearfix" role="group">
<a class="btn btn-primary btn-sm" href="/edit/{{ image.id }}">
<span class="fa fa-pencil"></span>
Bearbeiten
Edit
</a>
<a class="btn btn-danger btn-sm" href="/delete/{{ image.id }}">
<span class="fa fa-trash"></span>
Löschen
Delete
</a>
</div>
{% endifequal %}
<p>{{ image.created_at|parse-date|date:"dd.MM.yyyy, HH:mm" }} Uhr</p>
<p>{{ image.created_at|parse-date|date:"dd.MM.yyyy, HH:mm" }}</p>
{% if image.description|length > 0 %}
<div class="col-md7">
<p>{{ image.description|markdown-to-html|safe }}</p>
</div>
{% endif %}
<ul class="list-unlisted">
{% for comment in comments %}
<li class="media mb-3">
<div class="container">
{% for comment in comments %}
<a name="{{ comment.id }}"></a>
<img src="https://robohash.org/{{ comment.author }}?size=50x50" class="d-flex mr-3"/>
<div class="media-body">
<h5 class="mt-0 mb-1">{{ comment.author }}</h5>
{% ifequal identity ":creator" %}
<a class="btn btn-sm btn-danger" href="/delete-comment/{{ comment.id}}">Löschen</a>
{% endifequal %}
{{ comment.comment|markdown-to-html|safe }}
<div class="row">
<div class="col-1">
<img src="https://robohash.org/{{ comment.author }}?size=50x50" class="d-flex mr-3"/>
</div>
<div class="col-11">
<h5 class="mt-0 mb-1">{{ comment.author }}</h5>
{% ifequal identity ":creator" %}
<a class="btn btn-sm btn-danger" href="/delete-comment/{{ comment.id}}">Delete</a>
{% endifequal %}
{{ comment.comment|markdown-to-html|safe }}
</div>
</div>
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
<form action="/add-comment/{{ image.id }}" method="POST" class="form-horizontal">
{% csrf-field %}
<div class="form-group">
<label for="author">Name</label>
<div class="mb-3">
<label for="author" class="form-label">Name</label>
<input type="text" name="author" class="form-control"
value="{{ saved-author }}"
placeholder="Bitte einen Namen wählen (wird beim nächsten Mal gespeichert)">
</div>
<div class="form-group">
<label for="comment">Kommentar</label>
<div class="mb-3">
<label for="comment" class="form-label">Comment</label>
<textarea name="comment" class="form-control" rows="3"
placeholder="Es kann auch Markdown-Syntax verwendet werden"></textarea>
</div>
<button type="submit" class="btn btn-success">
<span class="fa fa-floppy-o"></span>
Kommentar hinzufügen
Add Comment
</button>
</form>
</div>

View file

@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% block content %}
<h1><span class="text-danger">Fehler: {{status}}</span></h1>
<h1><span class="text-danger">Error: {{status}}</span></h1>
<hr>
{% if title %}
<h2 class="without-margin">{{title}}</h2>

View file

@ -9,60 +9,66 @@
{% endif %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-toggleable-md bg-dark navbar-dark">
{% if identity %}
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
{% endif %}
<a class="navbar-brand" href="/">
<img src="/img/logo.png">
yenu
</a>
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto mt-2 mt-md-0">
{% if identity %}
{% ifequal identity ":creator" %}
<li class="nav-item">
<a class="nav-link" href="/upload">
<span class="fa fa-upload"></span>
Hochladen
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/comments">
<span class="fa fa-comments"></span>
Kommentarstream
</a>
</li>
<!--
<li class="nav-item">
<a class="nav-link" href="/statistics">
<span class="fa fa-bar-chart"></span>
Statistik
</a>
</li>
-->
{% endifequal %}
{% if identity %}
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
{% endif %}
<li class="nav-item">
<a class="nav-link" href="/feed?password={{ passwordhash }}" >
<span class="fa fa-rss-square"></span>
RSS-Feed
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">
<span class="fa fa-sign-out"></span>
Ausloggen
</a>
</li>
{% endif %}
<a class="navbar-brand" href="/">
<img src="/img/logo.png">
yenu
</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto mt-2 mt-md-0">
{% if identity %}
{% ifequal identity ":creator" %}
<li class="nav-item">
<a class="nav-link" href="/upload">
<span class="fa fa-upload"></span>
Upload
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/comments">
<span class="fa fa-comments"></span>
Comments
</a>
</li>
<!--
<li class="nav-item">
<a class="nav-link" href="/statistics">
<span class="fa fa-bar-chart"></span>
Statistics
</a>
</li>
-->
{% endifequal %}
<li class="nav-item">
<a class="nav-link" href="/feed?password={{ passwordhash }}" >
<span class="fa fa-rss-square"></span>
RSS-Feed
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">
<span class="fa fa-sign-out"></span>
Logout
</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<div id="content" class="col-md-12">
<div id="content" class="container col-md-12">
{% if flash.message %}
<div class="alert alert-{{ flash.type }}" role="alert">
{{ flash.message }}
@ -73,9 +79,11 @@
{% endblock %}
</div>
<div class="col-md-12 text-right mt-4 mb-1 text-muted">
<div class="col-md-12mt-4 mb-1">
<hr>
<p>{{ footer }}</p>
<div class="container text-muted text-end">
<p>{{ footer }}</p>
</div>
</div>
{% style "/assets/bootstrap/css/bootstrap.min.css" %}

View file

@ -6,13 +6,13 @@
<div class="col-lg-5 col-sm-12">
<img src="/img/logo_big.png">
<p>Um die Seite anzusehen oder die Aktion auszuführen wird ein Passwort benötigt.</p>
<p>To access this area, you need a password.</p>
<form method="POST" class="form-horizontal">
{% csrf-field %}
<div class="form-group">
<label for="title">Passwort</label>
<div class="mb-3">
<label for="title" class="form-label">Password</label>
<input type="password" name="password" class="form-control" autofocus>
</div>

View file

@ -1,6 +1,6 @@
{% extends "layout.html" %}
{% block content %}
<h1>Statistiken</h1>
<h1>Stats</h1>
<img src="/img/warning_clojure.png">
{% endblock %}

View file

@ -5,11 +5,10 @@
[ring.util.anti-forgery :refer [anti-forgery-field]]
[yenu.helpers.images :as image-helper]
[ring.middleware.anti-forgery :refer [*anti-forgery-token*]]
[clj-time.format :as time-format]
[yenu.config :refer [env]]
[yenu.db.core :as db]
[digest :as digest]
[clj-time.core :as time])
[java-time :refer [local-date-time]])
(:use [markdown.core]))
(declare ^:dynamic *identity*)
@ -19,7 +18,7 @@
(filter/add-filter! :inc inc)
(filter/add-filter! :dec dec)
(filter/add-filter! :markdown-to-html md-to-html-string)
(filter/add-filter! :parse-date #(time/to-time-zone (time-format/parse %) (time/default-time-zone)))
(filter/add-filter! :parse-date #(local-date-time "yyyy-MM-dd HH:mm:ss" %))
(defn footer []
(if (= (:count (db/get-image-count)) 0)
@ -27,7 +26,7 @@
(let [first-year (subs (:created_at (db/get-first-year)) 0 4)
recent-year (subs (:created_at (db/get-recent-year)) 0 4)
copy (if (= first-year recent-year) first-year (str first-year " - " recent-year))]
(str "© " copy " " (clojure.string/join ", " (:authors env))))))
(str "© " copy " " (:authors env)))))
(defn render-file [template & [params]]
(content-type

View file

@ -74,20 +74,20 @@
(do
(add-image-to-database imghash title description tags)
(-> (redirect "/upload")
(assoc :flash {:message "Upload erfolgreich." :type "success"})))
(assoc :flash {:message "Upload successfull" :type "success"})))
(-> (redirect "/upload")
(assoc :flash {:message "Fehler beim Upload." :type "danger"})))))
(assoc :flash {:message "Upload failed" :type "danger"})))))
(GET "/delete/:id" [id :as request]
(delete-image! id request)
(-> (redirect "/page/1")
(assoc :flash {:message "Bild wurde gelöscht" :type "danger"})))
(assoc :flash {:message "Image deleted" :type "danger"})))
(GET "/delete-comment/:id" [id]
(let [image-id (image-id-from-comment id)]
(db/delete-comment! {:id id})
(-> (redirect (str "/show/" image-id))
(assoc :flash {:message "Kommentar wurde gelöscht" :type "danger"}))))
(assoc :flash {:message "Comment deleted" :type "danger"}))))
(GET "/edit/:id" [id :as request]
(edit-image-form id request))
@ -95,7 +95,7 @@
(POST "/edit/:id" [id title description tags :as request]
(edit-image! id title description tags request)
(-> (redirect (str "/show/" id))
(assoc :flash {:message "Bild wurde bearbeitet" :type "success"})))
(assoc :flash {:message "Image edited" :type "success"})))
(GET "/statistics" []
(layout/render-file "statistics.html"))

View file

@ -17,15 +17,15 @@
(if user-identity
(let [updated-session (assoc session :identity user-identity)]
(-> (redirect next-url)
(assoc :flash {:message "Erfolgreich eingeloggt." :type "success"})
(assoc :flash {:message "Login successfull" :type "success"})
(assoc :session updated-session)))
(-> (redirect (format "/login?next=%s" next-url))
(assoc :flash {:message "Falsches Passwort." :type "danger"})))))
(assoc :flash {:message "Wrong password" :type "danger"})))))
(defn logout! [request]
(-> (redirect "/login")
(assoc :session {})
(assoc :flash {:message "Erfolgreich ausgeloggt." :type "success"})))
(assoc :flash {:message "Logout successfull" :type "success"})))
(defroutes auth-routes
(GET "/login" [:as request]

View file

@ -30,15 +30,15 @@
(if (< num 2)
""
(h/html
[:nav.float-right.clearfix {:aria-label "Page navigation"}
[:nav.pull-right.clearfix {:aria-label "Page navigation"}
[:ul.pagination.d-none.d-sm-none.d-xs-none.d-md-flex
(page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Zurück"))
(page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Prev"))
(cond
(< num 13) (pagelist 1 num current)
(<= current 7) (h/html (pagelist 1 10 current) (dots) (pagelist (- num 1) num current))
(>= current (- num 6)) (h/html (pagelist 1 2 current) (dots) (pagelist (- num 9) num current))
:else (h/html (pagelist 1 2 current) (dots) (pagelist (- current 3) (+ current 3) current) (dots) (pagelist (- num 1) num current)))
(page (inc current) (= current num) "disabled" (h/html "Weiter " [:span.fa.fa-arrow-right]))]]
(page (inc current) (= current num) "disabled" (h/html "Next " [:span.fa.fa-arrow-right]))]]
[:div.clearfix])))
(defn pagination-mobile [num current]
@ -46,12 +46,12 @@
""
(h/html
[:ul.pagination.justify-content-end.d-md-none
(page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Zurück"))
(page (dec current) (= current 1) "disabled" (h/html [:span.fa.fa-arrow-left] " Prev"))
[:form.form-inline
[:select#page-switcher.form-control
(for [p (range 1 (inc num))]
[:option (cond-> {:value p} (= p current) (assoc :selected "selected")) p])]]
(page (inc current) (= current num) "disabled" (h/html "Weiter " [:span.fa.fa-arrow-right]))])))
(page (inc current) (= current num) "disabled" (h/html "Next " [:span.fa.fa-arrow-right]))])))
(defn index-page [current request]
(let [image-count (:images-per-page env)
@ -90,8 +90,8 @@
:comment comment}))
(-> (redirect (str "/show/" image-id))
(assoc :flash (if (not= comment "")
{:message "Danke für deinen Kommentar" :type "success"}
{:message "Der kommentar war leider leer." :type "danger"}))
{:message "Thank you for your comment." :type "success"}
{:message "The comment was empty." :type "danger"}))
(assoc-in [:cookies "author"]
{:value author
:path "/"

View file

@ -63,7 +63,7 @@
<p>This tool is written in <a href="https://clojure.org/">Clojure</a> by <a href="https://aaron-fischer.net/">Aaron Fischer</a>. It is free to use
and is placed under
the <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPL v.3</a>. You
can inspect and download the sourcecode <a href="http://git.datenhalter.de/aaron/yenu">here</a>. The images,
can inspect and download the sourcecode <a href="https://git.okoyono.de/f/yenu">here</a>. The images,
comments and other metadata belongs to you. Make sure, you store the data on
a place you trust and make backups.</p>