Compare commits

...

4 commits

Author SHA1 Message Date
954d24bbb2 Update doc 2024-09-18 10:46:46 +02:00
844eee663d Update theme 2024-09-18 10:46:46 +02:00
ed90b31019 Update Docker file 2024-09-18 10:46:46 +02:00
70f4ea616e Update Docker version 2024-09-18 10:46:46 +02:00
11 changed files with 272 additions and 131 deletions

View file

@ -1,4 +1,4 @@
docker run -v soshot_datas:/var/www/datas -v soshot_cache_img:/var/www/cache/img -e TZ=UTC -p 8080:80 --name soshot soshot:0.2.0
docker run -v soshot_datas:/var/www/datas -v soshot_cache_img:/var/www/cache/img -e TZ=UTC -p 8080:80 --name soshot soshot:0.3.0
or

View file

@ -2,7 +2,7 @@ FROM ubuntu/apache2
MAINTAINER Knah Tsaeb <knah-tsaeb_soshot@knah-tsaeb.org>
LABEL version="0.2.0"
LABEL version="0.3.0"
LABEL description="Apache 2 / PHP / SoShot"
ENV DEBIAN_FRONTEND=noninteractive
@ -17,14 +17,13 @@ WORKDIR /var/www/
RUN git clone https://forge.leslibres.org/Knah-Tsaeb/Soshot.git --branch dev --single-branch --depth 1 .
RUN composer install --no-dev && chown -R www-data:www-data /var/www/
COPY .docker/start.sh /usr/bin/start.sh
RUN cp .docker/start.sh /usr/bin/start.sh
RUN chmod +x /usr/bin/start.sh
WORKDIR /
COPY .docker/apache2/soshot.conf /etc/apache2/sites-available/soshot.conf
RUN cp .docker/apache2/soshot.conf /etc/apache2/sites-available/soshot.conf
RUN a2dissite 000-default.conf && a2ensite soshot.conf && a2enmod rewrite
WORKDIR /
RUN echo '*/4 * * * * www-data php /var/www/bin/thumbShoter.php' > /etc/cron.d/soshot && chmod 0644 /etc/cron.d/soshot && crontab /etc/cron.d/soshot
EXPOSE 80
@ -35,6 +34,6 @@ WORKDIR /var/www/
ENTRYPOINT "start.sh"
# Build image
# docker build -t soshot:0.2.0 .
# docker build -t soshot:0.3.0 .
# Run container
# docker run -v soshot_datas:/var/www/datas -v soshot_cache_img:/var/www/cache/img -e TZ=UTC -p 8080:80 --name soshot soshot:0.2.0
# docker run -v soshot_datas:/var/www/datas -v soshot_cache_img:/var/www/cache/img -e TZ=UTC -p 8080:80 --name soshot soshot:0.3.0

152
README.md
View file

@ -2,7 +2,7 @@
## Use at your own risk
Soshot make webshot of internet page with headless machine.
Soshot make webshot of internet page with headless machine (Google Chrome).
## Ideas
@ -16,15 +16,40 @@ SoShot always make complete webshot (1920x page lenght) + first demande size.
Size use 16/9 ratio :
- fav = define by config (default 48px)
- og = define by the website himself (no resize or crop)
- thumb = 160x90
- nhd = 640x360
- hd = 1280x720
- full = 1920x1080
- complete = 1920xpage height
## Requirements
## Installation
### Docker (recommended)
For the moment I don't provide any image in any hub.
#### Build image
```shell
wget https://forge.leslibres.org/Knah-Tsaeb/Soshot/raw/branch/main/Dockerfile
docker buildx build --no-cache -t soshot:0.3.0 .
```
#### Start container
You can use native docker volume.
docker run -v soshot_datas:/var/www/datas -v soshot_cache:/var/www/cache -e TZ=UTC -p 8187:80 --name soshot soshot:0.3.0
Or use absolute path
docker run -v /opt/soshot/datas:/var/www/datas -v /opt/soshot/cache:/var/www/public/cache -e TZ=UTC -p 8187:80 --name soshot soshot:0.3.0
### Classic way
#### Requirements
- PHP 8.*
- Sqlite3
@ -35,39 +60,35 @@ Size use 16/9 ratio :
- CRON
- Chrome / Chromium
## Installation
Make directory on your web server and go in
`
```shell
mkdir /var/www/soshot && cd /var/www/soshot
`
```
Clone git repo
`
```shell
git clone https://forge.leslibres.org/Knah-Tsaeb/Soshot.git .
`
```
Install dependencies
`
```shell
composer install --no-dev
`
```
Add cron task
`
```shell
sudo crontab -u www-data -e
`
```
`
```shell
php /var/www/soshot/bin/thumbShoter.php
`
```
Configure your web server to serve in "public" directory
Configure your web server to serve in "public" directory.
Go to web page
https://shoshot.your-domain.tld
@ -78,73 +99,36 @@ You can use a web interface (if option "use web gui" is set to true), https://sh
Or you can modify config file /datas/config.json.
#### Accept only request from 127.0.0.1
```json
{
"onlyLocalServer": true,
"webPage": false,
"log": true,
"alwaysMakePdf": false,
"icoSize": 48,
"expireCache": 12,
"maxGenPerBatch": 5,
"permitType": [],
"password": null,
"key": null,
"chromePath": null,
"fileFormat": "jpeg"
}
```
Default : true
ShoShot only work for local machine, return 404 if use with remote machine.
#### Use web gui
Default : false
Soshot only work with endpoint /api. Return 404 if endpoint is not /api
#### Use log
Default : true
Not implemented yet.
#### Always make PDF
Default : false
If true, SoShot make a complete webshot and PDF of page.
#### Favicon size
Default : 48
Define size of favicon.
#### Permit type of webshot
Default : none
Select authorized size or type of webshot.
#### Cache expiration (for web GUI) in hour
Default : 12
Not implemented yet.
#### Maximum work per batch
Default : 5
Foreach cron task as launch, SoShot make 5 webshot.
#### Api key
Default : random string, lenght 12
!!! DANGER !!!
If you change key, all previous generation will be invalid. Soshot re make all previous generation.
#### Password
Default : null
Password for admin interface. No min or max character.
#### Chrome path
Default : empty
If path of Chrome/Chromium is not in PATH, you can define here.
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| onlyLocalServer | bool | true | ShoShot only work for local machine, return 404 if use with remote machine |
| webPage | bool | false | Soshot only work with endpoint /api. Return 404 if not |
| log | bool | true | Not implemented yet |
| alwaysMakePdf | bool | false | If true, SoShot make a complete webshot and PDF of page |
| icoSize | int | 48 | Define size of favicon |
| expireCache | int | 12 | Not implemented yet |
| permitType | array | null | Select authorized size or type of webshot |
| maxGenPerBatch | int | 5 | Foreach cron task as launch, SoShot make 5 webshot |
| key | string | 12 | !!! DANGER !!! If you change key, all previous generation will be invalid. Soshot re make all previous generationt |
| password | string | null | Password for admin interface. No min or max character |
| chromePath | string | null | If path of Chrome/Chromium is not in PATH, you can define here |
## Usage

View file

@ -5,13 +5,13 @@ namespace App\Utils;
class ConvertStatus {
static function convertToIcon($status) {
if ($status === 1) {
echo '<i class="fa fa-check w3-text-green" aria-hidden="true"></i>';
echo '<i class="fa fa-check gen" aria-hidden="true"></i>';
} elseif ($status === 2) {
echo '<i class="fa fa-check w3-text-red" aria-hidden="true"></i>';
echo '<i class="fa fa-check notGen" aria-hidden="true"></i>';
} elseif ($status === 3) {
echo '<i class="fa fa-clock-o w3-text-orange" aria-hidden="true"></i>';
echo '<i class="fa fa-clock-o pending" aria-hidden="true"></i>';
} else {
echo '<i class="fa fa-ban w3-text-red" aria-hidden="true"></i>';
echo '<i class="fa fa-ban notGen" aria-hidden="true"></i>';
}
}
}

View file

@ -1,8 +1,89 @@
:root {
color-scheme: dark light;
--primary: #cc2027;
--primary-darken: #8E161B;
--primary-lighten: #D64C52;
--primary-text-contrast: #FFF;
--secondary: #20ccc5;
--secondary-darken: #168E89;
--secondary-lighten: #4CD6D0;
--secondary-text-contrast: #FFF;
--error: #c43933;
--error-darken: #892723;
--error-lighten: #CF605B;
--error-text-contrast: #FFF;
--info: #206ccc;
--info-darken: #164B8E;
--info-lighten: #4C89D6;
--info-text-contrast: #FFF;
--success: #7dcc20;
--success-darken: #578E16;
--success-lighten: #97D64C;
--success-text-contrast: #000;
--warning: #cc5e20;
--warning-darken: #8E4116;
--warning-lighten: #D67E4C;
--warning-text-contrast: #FFF;
--background-color: light-dark(#fffbfb, #171414);
--background-color-darken: light-dark(#B2AFAF, #100E0E);
--background-color-lighten: light-dark(#FFFBFB, #454343);
--header-background-color: light-dark(#171414, #fffbfb);
--header-background-color-darken: light-dark(#100E0E, #B2AFAF);
--header-background-color-lighten: light-dark(#454343, #FFFBFB);
--header-text-color: light-dark(#fffbfb, #171414);
--header-text-color-secondary: #ffffffb3;
--header-text-color-disable: light-dark(#ffffff80, #454343);
--text-color: light-dark(#171414, #fffbfb);
--text-color-secondary: #ffffffb3;
--text-color-disable: light-dark(#454343, #ffffff80);
--text-color-inverse: light-dark(#fffbfb, #171414);
--text-color-secondary-inverse: #ffffffb3;
--text-color-disable-inverse: light-dark(#ffffff80, #454343);
--h1-color: var(--primary);
--h2-color: #c33d35;
--h3-color: #b94f44;
--h4-color: #ae5e52;
--h5-color: #a16a61;
--h6-color: #927671;
}
[data-theme="light"] {
--background-color: #fffbfb;
--text-color: #171414;
--text-color-inverse: #fffbfb;
.title:hover {
color: var(--text-color);
}
}
[data-theme="dark"] {
table {
color: var(--text-color);
}
.title:hover {
color: var(--text-color-inverse);
}
}
html {
font-family: arial, sans-serif;
font-weight: bold;
line-height: 2em;
background-color: #ffffffcb;
background-color: var(--background-color);
overflow: auto;
color: var(--text-color);
}
html,
@ -16,25 +97,32 @@ h6 {
font-family: "Roboto", sans-serif;
}
h1 {
color: var(--primary);
}
.fa {
/*color: var(--primary);*/
}
.w3-sidebar {
z-index: 3;
width: 250px;
top: 43px;
height: inherit;
}
a {
text-decoration: none;
color: #8AC007;
color: var(--primary);
}
a:hover,
.title:hover {
a:hover {
text-decoration: none;
color: var(--primary-darken)
}
a:visited {
color: #8AC007;
color: var(--primary);
}
.centerBlock {
@ -46,16 +134,17 @@ a:visited {
}
.w3-bar {
background-color: #333333 !important;
background-color: var(--background-color) !important;
}
#mySidebar {
top: inherit;
background-color: initial !important;
top: 84px;
background-color: var(--header-background-color);
}
#mySidebar a:hover {
#mySidebar>:hover {
text-decoration: none;
color: var(--primary-darken);
}
.w3-bar-block .w3-bar-item {
@ -63,7 +152,12 @@ a:visited {
}
.w3-bar {
background-color: #fff !important;
background-color: var(--header-background-color) !important;
}
.w3-bar-item-selected {
background-color: var(--secondary);
color: var(--secondary-text-contrast);
}
#myFooter {
@ -82,10 +176,6 @@ a:visited {
padding-bottom: 16px;
}
.fa {
color: #009688;
}
form label {
width: 48% !important;
display: inline-block;
@ -99,14 +189,58 @@ form label {
width: 48%;
}
.w3-input {
background-color: var(--primary-lighten);
color: var(--text-color);
}
button,
.w3-button {
background-color: var(--primary) !important;
color: var(--text-color) !important;
}
button:hover,
.w3-button:hover {
background-color: var(--primary-darken) !important;
color: var(--text-color-inverse) !important;
}
.zoom {
cursor: zoom-in;
}
.delete,
.notGen {
color: var(--error);
}
.gen {
color: var(--success);
}
.pending {
color: var(--warning);
}
#myFooter {
background-color: var(--header-background-color);
color: var(--header-text-color);
}
#myFooter a:hover {
color: var(--primary-darken);
}
.title {
color: var(--text-color-inverse);
padding: .5em;
}
@media (max-width:768px) {
#mySidebar {
background-color: #ffffffcb !important;
background-color: var(--header-background-color) !important;
width: 100%;
height: 50%;
}

View file

@ -1,6 +1,24 @@
</div>
<script>
function switchTheme(e) {
let actualTheme = document.documentElement.getAttribute('data-theme');
if (actualTheme === null || actualTheme === 'light') {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
return false;
}
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
}
</script>
<footer id="myFooter" class="w3-bottom">
<div class="w3-container w3-theme-l1">
<p>Powered by <a href="https://www.w3schools.com/w3css/default.asp" target="_blank">w3.css</a></p>
<div class="w3-container">
<p>Powered by <a href="https://forge.leslibres.org/Knah-Tsaeb/Soshot" target="_blank"> Soshot </a>| Theme by <a href="https://www.w3schools.com/w3css/default.asp" target="_blank">w3.css</a></p>
</div>
</footer>

View file

@ -1,7 +1,9 @@
<div class="w3-row-padding centerBlock homeForm">
<h1 class="w3-center">SoShot</h1>
<p>Per<b>so</b>nal web<b>shot</b>er</p>
<div>
<p>
<h3>Per<b>so</b>nal web<b>shot</b>er</h3>
</p>
<div class="w3-center">
<img src="assets/img/wikipedia_logiciel_libre.png" alt="Thumbshot of french wikipedia home page" width="720px">
</div>
<p class="w3-center">

View file

@ -6,7 +6,7 @@ use App\Utils\Domains;
?>
<div class="w3-row soshot-main w3-margin-bottom">
<div class="w3-container">
<h1 class="w3-text-teal">Infos</h1>
<h1 class="w3-text">Infos</h1>
<ul>
<li>Total : <?= $total; ?></li>
@ -15,11 +15,11 @@ use App\Utils\Domains;
</ul>
<form>
<input type="text" name="search" value="<?= $search; ?>">
<input type="submit" value="Rechercher">
<input class="w3-input" type="text" name="search" value="<?= $search; ?>" placeholder="Search">
<input class="w3-button" type="submit" value="Rechercher">
</form>
<table class="w3-table-all w3-hoverable">
<table class="w3-table-all w3-hoverable" data-theme="light">
<thead>
<tr>
<td>Domain</td>
@ -42,7 +42,7 @@ use App\Utils\Domains;
<a href="#" class="linkDetail" data-hmac="<?= $value->id; ?>" data-href="<?= $value->url; ?>"><?= Domains::getDomain($value->url); ?></a>
</span>
<span class="w3-right" style="width:40px">
<a href="?page=infos&deleteGen=<?= $value->id; ?>"><i class="fa fa-trash-o w3-text-red" aria-hidden="true"></i></a>
<a href="?page=infos&deleteGen=<?= $value->id; ?>"><i class="fa fa-trash-o delete" aria-hidden="true"></i></a>
</span>
</td>
<td><?= $value->created; ?></td>
@ -62,10 +62,10 @@ use App\Utils\Domains;
<div class="w3-center w3-margin-top">
<div class="w3-bar">
<?php if ($start > 0) : ?>
<a href="?page=infos&start=<?= $previous; ?>" class="w3-teal w3-button">&laquo; Previous</a>
<a href="?page=infos&start=<?= $previous; ?>" class="w3 w3-button">&laquo; Previous</a>
<?php endif; ?>
<?php if ($next != $start) :; ?>
<a href="?page=infos&start=<?= $next; ?>" class="w3-teal w3-button">Next &raquo; </a>
<a href="?page=infos&start=<?= $next; ?>" class="w3 w3-button">Next &raquo; </a>
<?php endif; ?>
</div>
</div>

View file

@ -5,7 +5,7 @@
<div class="w3-section">
<input class="w3-input w3-border" type="password" placeholder="Password" name="loginPassword" required>
<input type="hidden" name="token" value="<?= $token; ?>" />
<button class="w3-button w3-block w3-teal w3-section w3-padding" style="width:30%; margin:0 auto" type="submit">Login</button>
<button class="w3-button w3-block w3-section w3-padding" style="width:30%; margin:0 auto" type="submit">Login</button>
</div>
</form>
</div>

View file

@ -5,7 +5,7 @@ use App\Utils\Page;
<div class="w3-top w3-round">
<div class="w3-bar w3-theme w3-top w3-left-align w3-large">
<a class="w3-bar-item w3-button w3-right w3-hide-large w3-hover-white w3-large w3-theme-l1" href="javascript:void(0)" onclick="w3_open()"><i class="fa fa-bars"></i></a>
<a href="#" class="w3-bar-item w3-button w3-theme-l1 title"><i class="fa fa-camera" aria-hidden="true"></i> SoShot</a>
<h1><a href="#" class="title"><i class="fa fa-camera" aria-hidden="true"></i> SoShot</a></h1>
<?php if ($this->runningJob) : ?><i class="fa fa-refresh fa-spin w3-text-red"></i><?php endif; ?>
</div>
</div>
@ -15,9 +15,13 @@ use App\Utils\Page;
<a href="javascript:void(0)" onclick="w3_close()" class="w3-right w3-xlarge w3-padding-large w3-hover-black w3-hide-large" title="Close Menu">
<i class="fa fa-remove"></i>
</a>
<a class="w3-bar-item w3-button <?= Page::active($params->page, 'infos', 'w3-gray') ?>" href="?page=infos">&nbsp;<i class="fa fa-info"></i> Infos</a>
<a class="w3-bar-item w3-button <?= Page::active($params->page, 'settings', 'w3-gray') ?>" href="?page=settings"><i class="fa fa-cog"></i> Settings</a>
<a class="w3-bar-item w3-button w3-margin-top <?= Page::active($params->page, 'logout', 'w3-gray') ?>" href="/logout"><i class="fa fa-sign-out"></i> Logout</a>
<a class="w3-bar-item <?= Page::active($params->page, 'infos', 'w3-bar-item-selected') ?>" href="?page=infos">&nbsp;<i class="fa fa-info"></i> Infos</a>
<a class="w3-bar-item <?= Page::active($params->page, 'settings', 'w3-bar-item-selected') ?>" href="?page=settings"><i class="fa fa-cog"></i> Settings</a>
<a class="w3-bar-item w3-margin-top" onclick="switchTheme();" href="#" ><i class="fa fa-moon" aria-hidden="true"></i> Dark/Light</a>
<a class="w3-bar-item w3-margin-top <?= Page::active($params->page, 'logout', 'w3-bar-item-selected') ?>" href="/logout"><i class="fa fa-sign-out"></i> Logout</a>
</nav>
<!-- Overlay effect when opening sidebar on small screens -->

View file

@ -5,8 +5,8 @@ use App\Utils\Page;
<div class="w3-row soshot-main w3-margin-bottom">
<div class="w3-container">
<h1 class="w3-text-teal"><?= $this->title; ?></h1>
<form class="w3-container" method="post">
<h1 class="w3-text"><?= $this->title; ?></h1>
<form class="w3-container" method="post" data-theme="dark">
<p>
<label>Accept only request from 127.0.0.1</label>
@ -75,7 +75,7 @@ use App\Utils\Page;
<p>
<input type="hidden" name="page" value="settings">
<input type="hidden" name="token" value="<?= $token; ?>">
<button type="submit" class="w3-btn w3-padding w3-teal" style="width:120px">Save</button>
<button type="submit" class="w3-btn w3-padding w3" style="width:120px">Save</button>
</p>
</form>
</div>