Compare commits

..

2 commits

Author SHA1 Message Date
m1k1o
7027ec4ed4 Merge branch 'master' of github.com:m1k1o/blog into wake-lock 2020-09-20 11:17:42 +02:00
m1k1o
fdaa83ffbd add wake lock implementation 2020-09-20 10:58:50 +02:00
22 changed files with 122 additions and 614 deletions

1
.github/FUNDING.yml vendored
View file

@ -1 +0,0 @@
github: [ m1k1o ]

View file

@ -1,58 +0,0 @@
name: "CI for builds"
on:
push:
branches:
- master
tags:
- 'v*'
env:
IMAGE_NAME: m1k1o/blog
jobs:
build:
runs-on: ubuntu-latest
#
# do not run on forks
#
if: github.repository_owner == 'm1k1o'
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
-
name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
-
name: Extract metadata (tags, labels) for Docker
uses: docker/metadata-action@v3
id: meta
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
-
name: Log in to the Container registry
uses: docker/login-action@v1
with:
username: ${{ github.actor }}
password: ${{ secrets.DOCKER_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true

View file

@ -1,7 +1,9 @@
FROM php:7.4-apache
MAINTAINER Miroslav Sedivy
RUN set -eux; apt-get update; \
apt-get install -y --no-install-recommends libpq-dev \
apt-get install -y --no-install-recommends \
#
# install curl
libcurl4-openssl-dev \
@ -18,7 +20,7 @@ RUN set -eux; apt-get update; \
--with-jpeg --with-webp --with-xpm --with-freetype; \
#
# install extensions
docker-php-ext-install curl gd pdo pdo_mysql pdo_pgsql exif; \
docker-php-ext-install curl gd pdo pdo_mysql; \
#
# set up environment
a2enmod rewrite;

107
README.md
View file

@ -53,85 +53,32 @@ docker run -d \
m1k1o/blog:latest
```
Or for docker-compose format, see [docker-compose.yml](docker-compose.yml).
Or in docker-compose format:
```yml
version: "3"
services:
blog:
image: m1k1o/blog:latest
restart: unless-stopped
environment:
TZ: Europe/Vienna
BLOG_TITLE: Blog
BLOG_NAME: Max Musermann
BLOG_NICK: username
BLOG_PASS: password
BLOG_LANG: en
ports:
- 80:80
volumes:
- ./data:/var/www/html/data
```
## Install standalone app using `docker-compose` with external database
## Install standalone app using `docker-compose` with mysql
You need to install [docker-compose](https://docs.docker.com/compose/install/).
### MySQL
```yaml
version: "3"
services:
webserver:
image: m1k1o/blog:latest
container_name: blog_apache
environment:
TZ: Europe/Vienna
BLOG_DB_CONNECTION: mysql
BLOG_MYSQL_HOST: mariadb
BLOG_MYSQL_PORT: 3306
BLOG_MYSQL_USER: blog
BLOG_MYSQL_PASS: blog # use secure password
BLOG_DB_NAME: blog
restart: unless-stopped
ports:
- ${HTTP_PORT-80}:80
volumes:
- ${DATA-./data}:/var/www/html/data
mariadb:
image: mariadb:10.1
container_name: blog_mariadb
environment:
MYSQL_USER: blog
MYSQL_PASSWORD: blog # use secure password
MYSQL_DATABASE: blog
MYSQL_ROOT_PASSWORD: root # use secure password
restart: unless-stopped
volumes:
- mariadb:/var/lib/mysql
- ./app/db/mysql:/docker-entrypoint-initdb.d:ro
volumes:
mariadb:
```
### Postgres
```yaml
version: "3"
services:
webserver:
image: m1k1o/blog:latest
container_name: blog_apache
environment:
TZ: Europe/Vienna
BLOG_DB_CONNECTION: postgres
BLOG_POSTGRES_HOST: postgres
BLOG_POSTGRES_PORT: 5432
BLOG_POSTGRES_USER: blog
BLOG_POSTGRES_PASS: blog # use secure password
BLOG_DB_NAME: blog
restart: unless-stopped
ports:
- ${HTTP_PORT-80}:80
volumes:
- ${DATA-./data}:/var/www/html/data
postgres:
image: postgres:14
container_name: blog_postgres
environment:
POSTGRES_USER: blog
POSTGRES_PASSWORD: blog # use secure password
POSTGRES_DB: blog
restart: unless-stopped
volumes:
- postgres:/var/lib/postgresql/data
- ./app/db/postgres:/docker-entrypoint-initdb.d:ro
volumes:
postgres:
```
### Step 1: Run `docker-compose.yml`.
Select one of configurations above and save it to `docker-compose.yml`. Then run:
### Step 1: Download and run `docker-compose.yml`.
```sh
wget https://raw.githubusercontent.com/m1k1o/blog/master/docker-compose.yml
docker-compose up -d
```
@ -208,10 +155,9 @@ To check if your server is set up correctly, turn on a debug mode (in config add
* Upload images using CTRL + V *(paste it into textarea)*.
* Highlight code in post using `[code]..your code..[/code]`.
* Highlight your goal using `[goal]Text of your goal.[/goal]`.
* Use tags in posts (allowed characters `A-Za-z0-9-_` terminated by space or EOL): `#song`.
* Sort posts in reverse order (oldest first): `http://blog/#sort=reverse`.
* Filter posts by hashtags: `http://blog/#tag=songs`.
* Filter posts by location in url using: `http://blog/#loc=Vienna`.
* Use tags in posts (allowed characters `A-Za-z0-9-_` terminated by space or EOL): `#song`
* Sort posts by hashtags: `http://blog/#tag=songs`
* Sort posts by location in url using: `http://blog/#loc=Vienna`.
* Display posts from chosen date using (format YYYY-MM-DD or YYY-MM): `http://blog/#from=2017-06`.
* Display posts to chosen date using (format YYYY-MM-DD or YYY-MM): `http://blog/#to=2017-06`.
* Combine parameters in url using `&`, e.g. show posts between dates: `http://blog/#from=2017-06&to=2017-08`.
@ -269,6 +215,3 @@ Feel free to create new PR and add a new language. Specify language in config or
* sk - 🇸🇰 Slovak
* fr - 🇫🇷 French (thanks @Phundrak)
* cz - 🇨🇿 Czech (thanks @djfinch)
* bs - 🇧🇦 Bosnian (thanks @hajro92)
* es - 🇪🇸 Spanish (thanks @ManuLinares)
* ru - 🇷🇺 Russian (thanks @ozzyst)

View file

@ -24,27 +24,12 @@ class DB
return Config::get_safe('db_connection', 'sqlite');
}
// CONCAT() does not exist in SQLite, using || instead
// for postgres, ERROR: could not determine data type of parameter $1
public final static function concat(){
$values = func_get_args();
if(DB::connection() === 'sqlite' || DB::connection() === 'postgres') {
return implode(" || ", $values);
} else {
return 'CONCAT('.implode(", ", $values).')';
}
}
// Initialise PDO object
private final function __construct(){
switch(DB::connection()) {
case 'mysql':
$this->mysql_connect();
break;
case 'postgres':
$this->postgres_connect();
break;
case 'sqlite':
$this->sqlite_connect();
break;
@ -96,48 +81,6 @@ class DB
}
}
private final function postgres_connect(){
$host = Config::get_safe('postgres_host', false);
$port = Config::get_safe('postgres_port', false);
$socket = Config::get_safe('postgres_socket', false);
if($socket === false && $host === false){
throw new DBException("Postgres host or socket must be defined.");
}
// Try to connect
try {
$this->_PDO = new \PDO(
// Server
'pgsql:'.
($socket !== false
? 'unix_socket='.$socket
: 'host='.$host.($port !== false ? ';port='.$port : '')
).
// DB
';dbname='.Config::get('db_name').
// Charset
';options=\'--client_encoding=UTF8\'',
// Username
Config::get('postgres_user'),
// Password
Config::get_safe('postgres_pass', ''),
// Set attributes
[
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]
);
$this->_PDO->exec(
// Set timezone
'SET TIME ZONE "'.date('e').'";'
);
} catch (PDOException $e) {
throw new DBException($e->getMessage());
}
}
private final function sqlite_connect(){
$sqlite_db = PROJECT_PATH.Config::get_safe('sqlite_db', "data/sqlite.db");
@ -211,11 +154,6 @@ class DB
$sql = $params[0];
unset($params[0]);
// Replace backticks with " for postgres
if(DB::connection() === 'postgres') {
$sql = str_replace("`", '"', $sql);
}
// Debug mode
if(Config::get_safe('debug', false)){
echo "<!-- ".$sql." + ".json_encode($params)." -->\n";

View file

@ -1,26 +0,0 @@
CREATE TABLE images (
"id" serial PRIMARY KEY,
"name" varchar(255) NOT NULL,
"path" varchar(255) DEFAULT NULL,
"thumb" varchar(255) DEFAULT NULL,
"type" varchar(10) NOT NULL,
"md5" char(32) NOT NULL,
"datetime" timestamp NOT NULL,
"status" int NOT NULL
);
CREATE TYPE privacy_t as enum('private','friends','public');
CREATE TABLE posts (
"id" serial PRIMARY KEY,
"text" text NOT NULL,
"plain_text" text NOT NULL,
"feeling" varchar(255) NOT NULL,
"persons" varchar(255) NOT NULL,
"location" varchar(255) NOT NULL,
"content" varchar(1000) NOT NULL,
"content_type" varchar(255) NOT NULL,
"privacy" privacy_t NOT NULL,
"datetime" timestamp NOT NULL,
"status" int NOT NULL
);

View file

@ -110,16 +110,15 @@ class Image
}
$old_image = $imgcreatefrom($source_path);
if ($old_image === false) return false;
$new_image = imagecreatetruecolor($new_w, $new_h);
imagecopyresampled($new_image, $old_image, 0, 0, 0, 0, $new_w, $new_h, $source_w, $source_h);
$new_image = self::fix_orientation($source_path, $new_image);
$old_image = self::fix_orientation($source_path, $old_image);
return $imgt($new_image, $thumb_path)
&& $imgt($old_image, $source_path);
$imgt($new_image, $thumb_path);
$imgt($old_image, $source_path);
return true;
}
public static function upload(){

View file

@ -15,7 +15,7 @@ class Lang
}
public static function get($key){
if(is_null(self::$_dictionary) || !array_key_exists($key, self::$_dictionary)){
if(!@array_key_exists($key, self::$_dictionary)){
return $key;
}

View file

@ -1,67 +0,0 @@
; index.html
Show More = "Prikaži još"
Login = "Prijava"
Logout = "Odjava"
Nick = "Nadimak"
Password = "Šifra"
Cancel = "Zatvori"
Post = "Objavi"
Edit Post = "Izmijeni Objavu"
Change Date = "Promijeni Datum"
Hide from Timeline = "Sakrij sa Vremenske Linije"
Show on Timeline = "Prikaži na Vremenskoj Liniji"
Delete Post = "Izbriši objavu"
Drag photos here = "Privuci fotografije ovdje"
Drop photos here = "Privuci fotografije ovdje"
What's on your mind? = "Šta vam je na umu?"
Feeling = "Osjećaj"
How are you feeling? = "Kako se osjećate?"
With = "Sa"
Who are you with? = "S kim ste?"
At = "Gdje"
Where are you? = "Gdje se nalazite?"
Save = "Sačuvaj"
January = "Januar"
February = "Februar"
March = "Mart"
April = "April"
May = "Maj"
June = "Juni"
July = "Juli"
August = "Avgust"
September = "Septembar"
October = "Oktobar"
November = "Novembar"
December = "Decembar"
Time: = "Vrijeme:"
Hour: = "Sati:"
Minute: = "Minute:"
This post will be deleted and you'll no longer be able to find it. You can also edit this post if you just want to change something. = "Ova će objava biti izbrisana i nećete je više moći pronaći. Takođe možete izmijeniti ovu objavu ako želite izvršiti izmjene."
with = "sa"
here: = "ovdje:"
Public = "Javno"
Friends = "Prijatelji"
Only me = "Samo ja"
Show hidden content = "Prikaži skriveni sadržaj"
Show all posts = "Prikaži sve objave"
; user.class.php
You are already logged in. = "Već ste prijavljeni."
The nick or password is incorrect. = "Nadimak ili šifra su pogrešni."
You can't log out. There is no account. = "Ne možete se odjaviti. Račun ne postoji."
You are not even logged in. = "Niste čak ni prijavljeni."
; post.class.php
You need to be logged in to perform this action. = "Morate biti priavljeni da biste izvršili ovu radnju."
No data. = "Nema podataka."

View file

@ -1,67 +0,0 @@
; index.html
Show More = "Mostrar más"
Login = "Iniciar sesión"
Logout = "Cerrar sesión"
Nick = "Apodo"
Password = "Contraseña"
Cancel = "Cancelar"
Post = "Publicar"
Edit Post = "Editar publicación"
Change Date = "Cambiar fecha"
Hide from Timeline = "Ocultar de la línea de tiempo"
Show on Timeline = "Mostrar en la línea de tiempo"
Delete Post = "Eliminar publicación"
Drag photos here = "Arrastra aquí las fotos"
Drop photos here = "Suelta aquí las fotos"
What's on your mind? = "¿Qué estas pensando?"
Feeling = "Sintiendo"
How are you feeling? = "¿Como te sientes?"
With = "Con"
Who are you with? = "¿Con quién estás?"
At = "En"
Where are you? = "¿Dónde estás?"
Save = "Guardar"
January = "Enero"
February = "Febrero"
March = "Marzo"
April = "Abril"
May = "Mayo"
June = "Junio"
July = "Julio"
August = "Agosto"
September = "Septiembre"
October = "Octubre"
November = "Noviembre"
December = "Diciembre"
Time: = "Hora:"
Hour: = "Hora:"
Minute: = "Minuto:"
This post will be deleted and you'll no longer be able to find it. You can also edit this post if you just want to change something. = "Esta publicación se eliminará y ya no podrá ser encontrada. También puedes editar esta publicación si solo deseas cambiar algo."
with = "con"
here: = "aqui:"
Public = "Público"
Friends = "Amigos"
Only me = "Solo yo"
Show hidden content = "Mostrar contenido oculto"
Show all posts = "Mostrar todas las publicaciones"
; user.class.php
You are already logged in. = "Ya has iniciado sesión."
The nick or password is incorrect. = "El apodo o la contraseña son incorrectos."
You can't log out. There is no account. = "No puede cerrar sesión. No hay cuenta."
You are not even logged in. = "Ni siquiera estás conectado."
; post.class.php
You need to be logged in to perform this action. = "Debe haber iniciado una sesión para realizar esta acción."
No data. = "Sin datos."

View file

@ -40,9 +40,9 @@ October = "Octobre"
November = "Novembre"
December = "Décembre"
Time: = "Heure :"
Hour: = "Heure :"
Minute: = "Minutes :"
Time: = "Heure:"
Hour: = "Heure:"
Minute: = "Minutes:"
This post will be deleted and you'll no longer be able to find it. You can also edit this post if you just want to change something. = "Cette publication sera supprimée et vous ne pourrez plus la retrouver. Vous pouvez aussi la modifier si vous souhaitez simplement changer quelque chose."
@ -57,11 +57,11 @@ Show hidden content = "Montrer le contenu caché"
Show all posts = "Montrer toutes les publications"
; user.class.php
You are already logged in. = "Vous êtes déjà connecté."
You are already logged in. = "Vous êtes déjà connectés."
The nick or password is incorrect. = "Votre pseudo ou mot de passe est incorrect."
You can't log out. There is no account. = "Vous ne pouvez pas vous déconnecter, les comptes sont désactivés."
You are not even logged in. = "Vous nêtes pas connecté."
You are not even logged in. = "Vous nêtes même pas connectés."
; post.class.php
You need to be logged in to perform this action. = "Vous devez être connecté pour pouvoir faire ça."
You need to be logged in to perform this action. = "Vous devez être connectés pour pouvoir faire ça."
No data. = "Aucune données."

View file

@ -1,67 +0,0 @@
; index.html
Show More = "Verder Lezen"
Login = "Aanmelden"
Logout = "Afmelden"
Nick = "Gebruiker"
Password = "Wachtwoord"
Cancel = "Annuleren"
Post = "Bericht"
Edit Post = "Wijzig Bericht"
Change Date = "Wijzig Datum"
Hide from Timeline = "Verbergen van Tijdlijn"
Show on Timeline = "Laten zien op Tijdlijn"
Delete Post = "Verwijder Bericht"
Drag photos here = "Sleep foto's hier"
Drop photos here = "Gooi foto's hier"
What's on your mind? = "Waar ben je mee bezig?"
Feeling = "Gevoel"
How are you feeling? = "Hoe voel je je?"
With = "Met"
Who are you with? = "Met wie ben je?"
At = "Bij"
Where are you? = "Waar ben je?"
Save = "Opslaan"
January = "Januari"
February = "Februari"
March = "Maart"
April = "April"
May = "Mei"
June = "Juni"
July = "Juli"
August = "Augustus"
September = "September"
October = "Oktober"
November = "November"
December = "December"
Time: = "Tijd:"
Hour: = "Uur:"
Minute: = "Minuten:"
This post will be deleted and you'll no longer be able to find it. You can also edit this post if you just want to change something. = "Dit bericht word verwijderd en kan niet meer worden gevonden. Je kan ook het bericht wijzigen als je dat liever wilt."
with = "met"
here: = "Bij:"
Public = "Openbaar"
Friends = "Vrienden"
Only me = "Alleen ik"
Show hidden content = "Laat verborgen berichten zien"
Show all posts = "Alle berichten zien"
; user.class.php
You are already logged in. = "Je bent al ingelogt."
The nick or password is incorrect. = "De gebruiken of het Wachtwoord is onjuist."
You can't log out. There is no account. = "Je kan niet Afmelden. Er is geen Account."
You are not even logged in. = "Je ben niet eens ingelogt."
; post.class.php
You need to be logged in to perform this action. = "Je moet ingelogged zijn om deze actie uit te voeren."
No data. = "Geen data."

View file

@ -1,67 +0,0 @@
; index.html
Show More = "Показать больше"
Login = "Войти"
Logout = "Выйти"
Nick = "Логин"
Password = "Пароль"
Cancel = "Отмена"
Post = "Пост"
Edit Post = "Редактировать пост"
Change Date = "Изменить дату"
Hide from Timeline = "Скрыть из ленты"
Show on Timeline = "Показать в ленте"
Delete Post = "Удалить пост"
Drag photos here = "Перетащите сюда фото"
Drop photos here = "Оставь фото здесь"
What's on your mind? = "О чем ты думаешь?"
Feeling = "Ощущения"
How are you feeling? = "Как ты себя чувствуешь?"
With = "В компании"
Who are you with? = "С кем ты?"
At = "Локация"
Where are you? = "Где ты?"
Save = "Сохранить"
January = "Январь"
February = "Февраль"
March = "Март"
April = "Апрель"
May = "Май"
June = "Июнь"
July = "Июль"
August = "Август"
September = "Сентябрь"
October = "Октябрь"
November = "Ноябрь"
December = "Декабрь"
Time: = "Время:"
Hour: = аc:"
Minute: = "Минута:"
This post will be deleted and you'll no longer be able to find it. You can also edit this post if you just want to change something. = "Этот пост будет удален, и вы больше не сможете его найти. Вы также можете отредактировать этот пост, если просто хотите что-то изменить"
with = "с"
here: = "здесь:"
Public = "Публичный"
Friends = "Друзья"
Only me = "Только я"
Show hidden content = "Показать скрытый контент"
Show all posts = "Показать все посты"
; user.class.php
You are already logged in. = "Вы уже залогинены."
The nick or password is incorrect. = "Логин или пароль неверный."
You can't log out. There is no account. = "Вы не можете выйти. Вы не залогинены."
You are not even logged in. = "Вы не авторизовались."
; post.class.php
You need to be logged in to perform this action. = "Вы должны быть залогинены, чтобы выполнить это действие."
No data. = "Нет данных."

View file

@ -204,8 +204,6 @@ class Post
if (DB::connection() === 'sqlite') {
$datetime = "strftime('%Y %m %d %H %M', `posts`.`datetime`)";
} else if (DB::connection() === 'postgres') {
$datetime = "to_char(datetime,'YYYY MM DD HH24 MI')";
} else {
$datetime = "DATE_FORMAT(`datetime`,'%Y %c %e %k %i')";
}
@ -427,14 +425,10 @@ class Post
if (DB::connection() === 'sqlite') {
$datetime = "strftime('%d %m %Y %H:%M', `posts`.`datetime`)";
} else if (DB::connection() === 'postgres') {
$datetime = "to_char(posts.datetime,'DD Mon YYYY HH24:MI')";
} else {
$datetime = "DATE_FORMAT(`posts`.`datetime`,'%d %b %Y %H:%i')";
}
$like_match = "LIKE ".DB::concat("'%'", "?", "'%'");
return DB::get_instance()->query("
SELECT
`id`, `text`, `feeling`, `persons`, `location`, `privacy`, `content_type`, `content`,
@ -445,11 +439,11 @@ class Post
($from ? "`posts`.`datetime` > ? AND " : "").
($to ? "`posts`.`datetime` < ? AND " : "").
($id ? "`id` = ? AND " : "").
($tag ? "`plain_text` $like_match AND " : "").
($loc ? "`location` $like_match AND " : "").
($person ? "`persons` $like_match AND " : "").
($tag ? "`plain_text` LIKE CONCAT('%', ?, '%') AND " : "").
($loc ? "`location` LIKE CONCAT('%', ?, '%') AND " : "").
($person ? "`persons` LIKE CONCAT('%', ?, '%') AND " : "").
"`status` <> 5
ORDER BY `posts`.`datetime` ".(@$r["sort"] == 'reverse' ? "ASC" : "DESC")."
ORDER BY `posts`.`datetime` DESC
LIMIT ? OFFSET ?
", $from, $to, $id, $tag, $loc, $person, $r["limit"], $r["offset"]
)->all();

View file

@ -17,10 +17,10 @@ if(Config::get_safe('debug', false)){
error_reporting(E_ALL);
// Check extensions
$required = ['curl', 'PDO', 'pdo_mysql', 'gd', 'exif'];
$required = ['curl', 'PDO', 'pdo_mysql', 'gd'];
$loaded = get_loaded_extensions();
if($missing = array_diff($required, $loaded)){
die("Missing extensions, please install: ".implode(", ", $missing));
die("Missing extensions, please install: ".impode(", ", $missing));
}
}

View file

@ -11,15 +11,6 @@ db_connection = sqlite
;mysql_pass = root
;db_name = blog
;[database]
;db_connection = postgres
;postgres_socket = /tmp/postgres.sock
;postgres_host = localhost
;postgres_port = 5432
;postgres_user = root
;postgres_pass = root
;db_name = blog
[profile]
title = Blog
name = Max Musermann
@ -39,7 +30,6 @@ theme = theme02
;styles[] = static/styles/custom1.css
;styles[] = static/styles/custom2.css
;scripts = static/styles/scripts.css
;footer = "Edit this if you really want to remove my backlink :("
[bbcode]
;bbtags[quote] = "<quote>{param}</quote>"
@ -72,6 +62,7 @@ logs_path = data/logs/
[system]
;timezone = Europe/Vienna
version = 1.42
system_name = blog
version = 1.253
debug = false
logs = false
logs = false

View file

@ -1,17 +1,31 @@
version: "3"
services:
blog:
webserver:
image: m1k1o/blog:latest
restart: unless-stopped
container_name: blog_apache
environment:
TZ: Europe/Vienna
BLOG_TITLE: Blog
BLOG_NAME: Max Musermann
BLOG_NICK: username
BLOG_PASS: password
BLOG_LANG: en
TZ: Europe/Vienna
BLOG_DB_CONNECTION: mysql
BLOG_MYSQL_HOST: mariadb
BLOG_MYSQL_PORT: 3306
BLOG_MYSQL_USER: root
BLOG_MYSQL_PASS: root
BLOG_DB_NAME: blog
restart: unless-stopped
ports:
- 80:80
- ${HTTP_PORT-80}:80
volumes:
- ${DATA-./data}:/var/www/html/data
mariadb:
image: mariadb:10.1
container_name: blog_mariadb
environment:
MYSQL_DATABASE: blog
MYSQL_ROOT_PASSWORD: root
restart: unless-stopped
volumes:
- ./data:/var/www/html/data
- mariadb:/var/lib/mysql
- ./app/db/mysql:/docker-entrypoint-initdb.d:ro
volumes:
mariadb:

View file

@ -10,10 +10,6 @@ if(empty($_SESSION['token'])){
}
}
function escape($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
//$.ajaxSetup({headers:{'Csrf-Token':'token'}});
Log::put("visitors");
@ -44,7 +40,6 @@ if(!empty($styles)){
}
$styles = array_unique($styles);
$styles = array_map('escape', $styles);
$styles_html = '<link href="'.implode('" rel="stylesheet" type="text/css"/>'.PHP_EOL.'<link href="', $styles).'" rel="stylesheet" type="text/css"/>'.PHP_EOL;
}
@ -52,39 +47,32 @@ if(!empty($styles)){
$scripts = Config::get_safe("scripts", []);
$scripts_html = '';
if(!empty($scripts)){
if(!is_array($scripts)){
$scripts = [$scripts];
if(!is_array($styles)){
$styles = [$styles];
}
$scripts = array_unique($scripts);
$scripts = array_map('escape', $scripts);
$scripts_html = '<script src="'.implode('" type="text/javascript"></script>'.PHP_EOL.'<script src="', $scripts).'" type="text/javascript"></script>'.PHP_EOL;
}
// Use version suffix in URLs to prevent cache
$versionSuffix = '';
if (Config::get_safe("version", false)) {
$versionSuffix = '?v='.rawurlencode(Config::get("version"));
}
?><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo escape(Config::get("title")); ?></title>
<title><?php echo Config::get("title"); ?></title>
<meta name="robots" content="noindex, nofollow">
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link href="static/styles/main.css<?php echo $versionSuffix?>" rel="stylesheet" type="text/css" />
<link href="static/styles/<?php echo rawurlencode(Config::get_safe("theme", "theme01")); ?>.css<?php echo $versionSuffix?>" rel="stylesheet" type="text/css" />
<link href="static/styles/main.css?v=<?php echo Config::get("version"); ?>" rel="stylesheet" type="text/css" />
<link href="static/styles/<?php echo Config::get_safe("theme", "theme01"); ?>.css?v=<?php echo Config::get("version"); ?>" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans&amp;subset=all" rel="stylesheet">
<link href="static/styles/lightbox.css" rel="stylesheet" type="text/css" />
<?php echo Config::get_safe("highlight", false) ? '<link href="static/styles/highlight-monokai-sublime.css" rel="stylesheet" type="text/css" />'.PHP_EOL : ''; ?>
<?php echo Config::get("highlight") ? '<link href="static/styles/highlight-monokai-sublime.css" rel="stylesheet" type="text/css" />' : ''; ?>
<?php echo $styles_html; ?>
</head>
@ -115,6 +103,7 @@ if (Config::get_safe("version", false)) {
</div>
<div class="modal-footer">
<div class="buttons">
<!--<div class="left"><a>Register</a> - <a>Forgot Password</a></div>-->
<a class="button gray close"><?php echo __("Cancel"); ?></a>
<button type="button" class="button blue do_login"><?php echo __("Login"); ?></button>
</div>
@ -181,7 +170,7 @@ if (Config::get_safe("version", false)) {
<div class="modal-body drop_space">
<div class="e_drag"><span><?php echo __("Drag photos here"); ?></span></div>
<div class="e_drop"><span><?php echo __("Drop photos here"); ?></span></div>
<img src="<?php echo escape(Config::get("pic_small")); ?>" width="40" height="40" class="e_profile">
<img src="<?php echo Config::get("pic_small"); ?>" width="40" height="40" class="e_profile">
<!--<div class="e_text" contenteditable="true"></div>-->
<div class="t_area">
<textarea class="e_text" placeholder="<?php echo __("What's on your mind?"); ?>"></textarea>
@ -293,10 +282,10 @@ if (Config::get_safe("version", false)) {
<a class="button"><?php echo __("Show hidden content"); ?></a>
</div>
<div class="b_header">
<img src="<?php echo escape(Config::get("pic_small")); ?>" width="40" height="40" class="b_profile">
<img src="<?php echo Config::get("pic_small"); ?>" width="40" height="40" class="b_profile">
<div class="b_desc">
<div class="b_sharer">
<span class="b_name"><?php echo escape(Config::get("name")); ?></span><span class="b_options"> - </span><span class="b_feeling"></span><span class="b_with"> <?php echo __("with"); ?> </span><span class="b_persons"></span><span class="b_here"> <?php echo __("here:"); ?> </span><span class="b_location"></span>
<span class="b_name"><?php echo Config::get("name"); ?></span><span class="b_options"> - </span><span class="b_feeling"></span><span class="b_with"> <?php echo __("with"); ?> </span><span class="b_persons"></span><span class="b_here"> <?php echo __("here:"); ?> </span><span class="b_location"></span>
</div>
<i class="privacy_icon"></i>
<a class="b_date"></a>
@ -316,18 +305,18 @@ if (Config::get_safe("version", false)) {
</div>
<div class="bluebar">
<h1><?php echo escape(Config::get("title")); ?></h1>
<h1><?php echo Config::get("title"); ?></h1>
</div>
<div class="headbar">
<div class="cover">
<?php echo $header; ?>
<div class="overlay"></div>
<?php echo (Config::get_safe("cover", false) ? '<img src="'.escape(Config::get("cover")).'">' : (empty($header) ? '<div style="padding-bottom: 37%;"></div>' : '')); ?>
<?php echo (Config::get_safe("cover", false) ? '<img src="'.Config::get("cover").'">' : (empty($header) ? '<div style="padding-bottom: 37%;"></div>' : '')); ?>
<div class="profile">
<img src="<?php echo escape(Config::get("pic_big")); ?>">
<img src="<?php echo Config::get("pic_big"); ?>">
</div>
<div class="name"><?php echo escape(Config::get("name")); ?></div>
<div class="name"><?php echo Config::get("name"); ?></div>
</div>
<div id="headline"></div>
</div>
@ -341,18 +330,16 @@ if (Config::get_safe("version", false)) {
<div id="eof_feed">
<img src="static/images/zpEYXu5Wdu6.png">
<p><?php echo escape(Config::get("version")); ?> &copy; 2016-2022<br>
<?php echo Config::get_safe("footer", false) ? escape(Config::get_safe("footer")) : '<a href="https://github.com/m1k1o/blog" class="link" title="m1k1o/blog github repository" target="_blank">m1k1o/blog</a>'; ?>
</p>
<p><?php echo Config::get("version"); ?> &copy; 2016-2020 <br>Miroslav Šedivý</p>
</div>
<script src="static/scripts/jquery.min.js"></script>
<script>$["\x61\x6A\x61\x78\x53\x65\x74\x75\x70"]({"\x68\x65\x61\x64\x65\x72\x73":{"\x43\x73\x72\x66-\x54\x6F\x6B\x65\x6E":"<?php echo $_SESSION['token'];?>"}});</script>
<script src="static/scripts/lightbox.js"></script>
<script src="static/scripts/datepick.js<?php echo $versionSuffix?>"></script>
<script src="static/scripts/datepick.js?v=<?php echo Config::get("version"); ?>"></script>
<script src="static/scripts/autosize.js"></script>
<?php echo Config::get_safe("highlight", false) ? '<script src="static/scripts/highlight-10.1.2.min.js"></script><script>hljs.initHighlightingOnLoad();</script>'.PHP_EOL : ''; ?>
<script src="static/scripts/app.js<?php echo $versionSuffix?>"></script>
<?php echo Config::get("highlight") ? '<script src="static/scripts/highlight-10.1.2.min.js"></script><script>hljs.initHighlightingOnLoad();</script>' : ''; ?>
<script src="static/scripts/app.js?v=<?php echo Config::get("version"); ?>"></script>
<?php echo $scripts_html; ?>
</body>

View file

@ -13,7 +13,6 @@ var posts = {
limit: 5, // Limit posts per load
offset: 0, // Current offset
sort: "default", // Default is from newest to oldest posts (use reverse for oldest to newest)
filter: {
from: null, // Show posts from specified date
@ -35,10 +34,6 @@ var posts = {
// Update ID hash
location.hash.replace(/([a-z]+)\=([^\&]+)/g, function(_, key, value){
if (key == "sort") {
posts.sort = decodeURIComponent(value);
return;
}
posts.filter[key] = decodeURIComponent(value);
$(".more_posts").show();
});
@ -77,7 +72,6 @@ var posts = {
action: "load",
limit: posts.limit,
offset: posts.offset,
sort: posts.sort,
filter: posts.filter
},
success: function(posts_data){
@ -688,6 +682,7 @@ $.fn.apply_edit = function(data){
};
// Fill post data
var wakeLock = null;
$.fn.post_fill = function(data){
var post = $(this);
@ -702,10 +697,26 @@ $.fn.post_fill = function(data){
var elementBottom = elementTop + $(overlay).outerHeight();
$(overlay).hide();
if (!wakeLock && 'wakeLock' in navigator) {
navigator.wakeLock.request('screen').then(function(event){
event.addEventListener('release', function(){
console.log('Screen Wake Lock was released.');
});
console.log('Screen Wake Lock is active.');
wakeLock = event;
});
}
var showOverlay = function() {
$(overlay).css("display", ""); // .show() would cause display:block;
$(window).off('scroll', showOnViewport);
$(window).off('blur', showOverlay);
if (wakeLock) {
wakeLock.release();
wakeLock = null;
}
};
var showOnViewport = function() {
var viewportTop = $(window).scrollTop();

View file

@ -51,11 +51,9 @@ var datepick = function(container) {
var thead = $(
'<thead>' +
'<tr>' +
'<th><button type="button" class="button blue prev_y" title="Previous Year">&lt;&lt;</button></th>' +
'<th><button type="button" class="button blue prev" title="Previous Month">&lt;</button></th>' +
'<th class="month-pick" colspan="3" title="Select Month">'+this.months[this.m]+' '+this.y+'</th>' +
'<th class="month-pick" colspan="5" title="Select Month">'+this.months[this.m]+' '+this.y+'</th>' +
'<th><button type="button" class="button blue next" title="Next Month">&gt;</button></th>' +
'<th><button type="button" class="button blue next_y" title="Next Year">&gt;&gt;</button></th>' +
'</tr>' +
'<tr>' +
'<th>Mo</th>' +
@ -70,22 +68,12 @@ var datepick = function(container) {
);
var x = this;
$(thead).find(".prev_y").click(function(){
x.dec_y();
x.load_table();
$(thead).find(".month-pick").text(x.months[x.m]+' '+x.y);
});
$(thead).find(".prev").click(function(){
x.dec_m();
x.load_table();
$(thead).find(".month-pick").text(x.months[x.m]+' '+x.y);
});
$(thead).find(".next_y").click(function(){
x.inc_y();
x.load_table();
$(thead).find(".month-pick").text(x.months[x.m]+' '+x.y);
});
$(thead).find(".next").click(function(){
x.inc_m();
x.load_table();

View file

@ -114,10 +114,6 @@ body {
text-transform: uppercase;
}
#eof_feed .link {
color: #90949c;
}
.show_more {
height: 40px;
line-height: 40px;
@ -130,6 +126,7 @@ body {
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 75%,rgba(255,255,255,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 );
cursor: pointer;
vertical-align: bottom;
}
.b_post {
@ -590,6 +587,11 @@ body {
margin: 8px;
}
.modal-footer .buttons .left {
display: inline-block;
float: left;
}
.modal-footer:before,
.modal-footer:after {
content: " ";
@ -777,8 +779,6 @@ body {
min-height: 88px;
max-width: 100%;
min-width: 100%;
background: transparent;
border: 0;
}
.options {
@ -1055,8 +1055,7 @@ code {
text-align: center;
}
.datepicker table {
width: 100%;
margin: 5px 0;
display: inline-block;
}
.datepicker th,
@ -1064,9 +1063,6 @@ code {
width: 12.5%;
}
.datepicker th {
padding: 5px 0;
}
.datepicker td {
color: #999;
padding: 5px;

View file

@ -181,10 +181,6 @@ body {
text-transform: uppercase;
}
#eof_feed .link {
color: var(--secondary-text);
}
.show_more {
height: 40px;
line-height: 40px;
@ -196,6 +192,7 @@ body {
background: -webkit-linear-gradient(top, transparent 0%,var(--primary-background) 75%,var(--primary-background) 100%);
background: linear-gradient(to bottom, transparent 0%,var(--primary-background) 75%,var(--primary-background) 100%);
cursor: pointer;
vertical-align: bottom;
}
.b_post {
@ -717,6 +714,11 @@ body {
margin-right: 0;
}
.modal-footer .buttons .left {
display: inline-block;
float: left;
}
.modal-footer:before,
.modal-footer:after {
content: " ";
@ -1173,8 +1175,7 @@ code {
text-align: center;
}
.datepicker table {
width: 100%;
margin: 5px 0;
display: inline-block;
}
.datepicker th,
@ -1182,9 +1183,6 @@ code {
width: 12.5%;
}
.datepicker th {
padding: 5px 0;
}
.datepicker td {
color: var(--datepicker-inactive-month);
padding: 5px;