project(fork): fork github sui

This commit is contained in:
周中平 2022-11-03 17:02:36 +08:00
commit 22c9f9e32c
No known key found for this signature in database
GPG Key ID: B1DF9DD42D8E00DC
17 changed files with 1409 additions and 0 deletions

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM busybox
LABEL maintainer="Jeroen Pardon"
WORKDIR /opt/html
COPY . /opt/html
EXPOSE 80
ENTRYPOINT [ "httpd", "-f", "-v", "-u", "1000" ]

10
DockerfilePullFromGit Normal file
View File

@ -0,0 +1,10 @@
FROM ubuntu:latest
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install nginx git cron nano
COPY install.sh /tmp/
EXPOSE 80
# execute install, start cron and nginx
CMD chmod +x /tmp/install.sh && /tmp/install.sh && cron && nginx

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>

107
README.md Normal file
View File

@ -0,0 +1,107 @@
## SUI
*a startpage for your server and / or new tab page*
![screenshot](https://i.imgur.com/J4d7Q3D.png)
[More screenshots](https://imgur.com/a/FDVRIyw)
### Deploy with Docker compose
#### Prerequisites:
- Docker: [Linux](https://docs.docker.com/install/linux/docker-ce/debian/), [Mac](https://hub.docker.com/editions/community/docker-ce-desktop-mac), [Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows)
- [Docker-compose](https://docs.docker.com/compose/install/)
#### Install:
- `git clone` this repository
- Build and bring up with `docker-compose up -d`
- The page should be available at `http://localhost:4000`
To run at a different port open edit docker-compose.yml:
ports:
- 4000:80
#### Install pull from git variant:
- refreshs source code every 5 minutes from master branch you provided - convenience feature for lacy devs
- `git clone` this repository
- build image `docker build -f DockerfilePullFromGit -t sui:latest .`
- run image with `docker run -e GITURL='https://x:ghp_x@github.com/jeroenpardon/sui.git' -p 8081:80 sui:latest`
- can be run also with a private repository by setting username:api-key@ in the url (see above example). Otherwise remove this part of the url.
### Customization
#### Changing color themes
- Click the options button on the left bottom
#### Apps
Add your apps by editing apps.json:
{
"apps" : [
{"name":"Name of app 1","url":"sub1.example.com","icon":"icon-name"},
{"name":"Name of app 2","url":"sub2.example.com","icon":"icon-name","target":"optionals"}
]
}
Please note:
- No `http://` in the URL
- No `,` at the end of the last app's line
- Find the names of icons to use at [Material Design Icons](https://materialdesignicons.com/)
#### Bookmarks
Add your bookmarks by editing links.json:
```
{
"bookmarks":[
{
"category":"Category1",
"links":[
{
"name":"Link1",
"url":"http://example.com"
},
{
"name":"Link2",
"url":"http://example.com",
"target":"optionals"
}
]
},
{
"category":"Category2",
"links":[
{
"name":"Link1",
"url":"http://example.com"
},
{
"name":"Link2",
"url":"http://example.com"
}
]
}
]
}
```
Add names for the categories you wish to define and add the bookmarks for each category.
Please note:
- No `http://` in the URL
- No `,` at the end of the last bookmark in a category and at the end of the last category
#### Color themes
These can be added or customized in the themer.js file. When changing the name of a theme or adding one, make sure to edit this section in index.html accordingly:
```
<section class="themes">
```
I might add a simpler way to edit themes at some point, but adding the current ones should be pretty straight forward.

24
apps.json Normal file
View File

@ -0,0 +1,24 @@
{
"apps" : [
{"name":"Bazarr","url":"subs.example.com","icon":"message-video", "target": "_blank"},
{"name":"CloudCMD","url":"files.example.com","icon":"folder-multiple-outline"},
{"name":"Cockpit","url":"cp.example.com","icon":"airplane"},
{"name":"Feedbin","url":"rss.example.com","icon":"rss"},
{"name":"Filestash","url":"cloud.example.com","icon":"package"},
{"name":"Jackett","url":"jackett.example.com","icon":"tshirt-crew-outline"},
{"name":"Lidarr","url":"music.example.com","icon":"music"},
{"name":"Minio","url":"minio.example.com","icon":"server"},
{"name":"Mylar","url":"comics.example.com","icon":"book-open-variant"},
{"name":"Nextcloud","url":"cloud.example.com","icon":"weather-cloudy"},
{"name":"Ombi","url":"request.example.com","icon":"file-find-outline"},
{"name":"Pi-hole","url":"pihole.example.com","icon":"do-not-disturb"},
{"name":"Plex","url":"play.example.com","icon":"plex"},
{"name":"Portainer","url":"port1.example.com","icon":"docker"},
{"name":"Radarr","url":"movies.example.com","icon":"filmstrip"},
{"name":"Sonarr","url":"tv.example.com","icon":"television-box"},
{"name":"Stackedit","url":"md.example.com","icon":"markdown"},
{"name":"Transmission","url":"dl.example.com","icon":"progress-download"},
{"name":"Ubooquity","url":"opds.example.com","icon":"library-shelves"},
{"name":"Youtube-DL","url":"yt.example.com","icon":"youtube"}
]
}

558
assets/css/styles.css Normal file
View File

@ -0,0 +1,558 @@
html{
box-sizing: border-box;
moz-box-sizing: border-box;
webkit-box-sizing: border-box;
webkit-text-size-adjust: none;
}
html,
body{
background-color: var(--color-background);
color: var(--color-text-pri);
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif;
font-size: 14px;
font-weight: 400;
height: auto;
letter-spacing: -.012em;
margin: 0;
padding: 0;
webkit-font-smoothing: antialiased;
width: 100vw;
}
*,
*:before,
*:after{
box-sizing: inherit;
moz-box-sizing: inherit;
webkit-box-sizing: inherit;
}
:root{
module-spacing: 3vh;
}
/* TEXT STYLES */
h1, h2{
font-weight: 300;
margin: 0;
padding: 0;
text-align: left;
}
h2, h3, h4{
text-transform: uppercase;
}
h1{
font-size: 4em;
font-weight: 700;
margin-bottom: 0.5em;
}
h2{
font-size: 16px;
height: 30px;
}
h3{
font-size: 20px;
font-weight: 900;
height: 10px;
}
h4{
font-size: 1.1em;
font-weight: 400;
height: 10px;
}
a{
color: var(--color-text-pri);
text-decoration: none;
}
a:hover{
text-decoration: underline;
webkit-text-decoration-color: var(--color-text-acc);
webkit-text-decoration-skip: true;
}
.icon{
font-size: 2.5em;
}
/* FORMS */
input{
background-color: transparent;
border: 0;
border-bottom: thin solid var(--color-text-acc);
color: var(--color-text-pri);
font-size: 0.8em;
height: 3.5em;
transition: all 0.4s ease;
width: 100%;
}
input:focus{
color-border: var(--color-text-pri);
outline: none;
}
input:focus{
opacity: 1;
}
/* TABLES */
table{
border: thin solid #e4e4e4;
border-collapse: collapse;
border-spacing: 0;
font-size: 1em;
text-align: left;
width: 100%;
}
table td:nth-of-type(2){
padding-right: 5em;
}
table td{
border: thin solid #e4e4e4;
color: #333333;
font-size: 1em;
overflow: hidden;
padding: 10px 5px;
word-break: normal;
}
table th{
border: thin solid #e4e4e4;
color: #333333;
font-weight: bold;
padding: 10px 5px;
}
table a{
color: #333333;
}
/* ANIMATION */
.fade{
opacity: 0;
}
@keyframes fadeseq{
100% {
opacity: 1;
}
}
.fade{
opacity: 0;
}
.fade{
animation: fadeseq .3s forwards;
}
.fade:nth-child(2){
animation-delay: .4s;
}
/* LAYOUT */
#container{
align-items: stretch;
display: grid;
grid-column-gap: 20px;
grid-row-gap: 3vh;
grid-template-columns: 1fr;
grid-template-rows: 8vh auto;
justify-items: stretch;
margin-left: auto;
margin-right: auto;
margin-top: 5vh;
width: 60%;
}
/* SECTIONS */
#header{
border-bottom: 0px solid var(--color-text-acc);
z-index: 1;
}
#apps_loop{
border-bottom: 0px solid var(--color-text-acc);
display: grid;
grid-column-gap: 0px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 64px;
padding-bottom: var(--module-spacing);
}
.apps_icon{
height: 64px;
margin-right: 1em;
padding-top: 15px;
}
.apps_icon span{
font-size: 2.5em;
line-height: 3rem;
}
.apps_item{
display: flex;
flex-direction: row;
flex-wrap: wrap;
height: 64px;
margin: 0;
}
.apps_text{
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
overflow: hidden;
}
.apps_text a{
font-size: 1em;
font-weight: 500;
text-transform: uppercase;
}
.apps_text span{
color: var(--color-text-acc);
font-size: 0.8em;
text-transform: uppercase;
}
#links_loop{
display: grid;
flex-wrap: nowrap;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto;
}
#links_item{
line-height: 1.5rem;
margin-bottom: 2em;
webkit-font-smoothing: antialiased;
}
#links_item h4{
color: var(--color-text-acc);
}
#links_item a{
display: block;
line-height: 2;
}
/* MODAL */
#modal{
overflow-y: auto;
bottom: 0;
left: 0;
opacity: 0;
pointer-events: none;
position: fixed;
right: 0;
top: 0;
transition: all 0.3s;
z-index: 20;
}
#modal:target{
opacity: 1;
pointer-events: auto;
}
#modal>div{
background-color: #ffffff;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.30), 0 15px 12px rgba(0, 0, 0, 0.25);
margin-left: auto;
margin-right: auto;
padding: 2em;
margin-top: 5vh;
width: 50%;
display: flex;
flex-direction: column;
}
#modal h1{
color: #333333;
font-size: 2em;
}
#modal h2{
margin-top:1.5em;
}
#modal-header{
display:flex;
justify-content: space-between;
}
#modal-footer{
display:flex;
font-size:2em;
justify-content: flex-start;
}
#modal-footer a{
margin-right:0.25em;
}
.modal-close{
color: #000000;
font-size: 1.5em;
text-align: center;
text-decoration: none;
}
.modal-close:hover{
color: #000;
}
#modal_init a{
bottom: 1vh;
color: var(--color-text-acc);
left: 1vw;
position: fixed;
}
#modal_init a:hover{
color: var(--color-text-pri);
}
#modal-theme{
border-bottom: 0px solid var(--color-text-acc);
display: flex;
flex-wrap: wrap;
margin-bottom: 2em;
}
#providers{
margin-bottom: 2em;
}
/* THEMING */
.theme-button{
font-size: 0.8em;
margin: 2px;
width:128px;
line-height: 3em;
text-align: center;
text-transform: uppercase;
}
.theme-blackboard{
background-color: #000000;
border: 4px solid #5c5c5c;
color: #FFFDEA;
}
.theme-gazette{
background-color: #F2F7FF;
border: 4px solid #5c5c5c;
color: #000000;
}
.theme-espresso{
background-color: #21211F;
border: 4px solid #4E4E4E;
color: #D1B59A;
}
.theme-cab{
background-color: #FEED01;
border: 4px solid #424242;
color: #1F1F1F;
}
.theme-cloud{
background-color: #f1f2f0;
border: 4px solid #35342f;
color: #37bbe4;
}
.theme-lime{
background-color: #263238;
border: 4px solid #AABBC3;
color: #aeea00;
}
.theme-passion{
background-color: #f5f5f5;
border: 4px solid #8e24aa;
color: #12005e;
}
.theme-blues{
background-color: #2B2C56;
border: 4px solid #6677EB;
color: #EFF1FC;
}
.theme-chalk{
background-color: #263238;
border: 4px solid #FF869A;
color: #AABBC3;
}
.theme-tron{
background-color: #242B33;
border: 4px solid #6EE2FF;
color: #EFFBFF;
}
.theme-paper{
background-color: #F8F6F1;
border: 4px solid #F5E1A4;
color: #4C432E;
}
/* MEDIA QUERIES */
@media screen and (max-width: 1260px)
{
#container
{
align-items: stretch;
display: grid;
grid-column-gap: 10px;
grid-row-gap: 0px;
grid-template-columns: 1fr;
grid-template-rows: 80px auto;
justify-items: stretch;
margin-bottom: 1vh;
margin-left: auto;
margin-right: auto;
width: 90%;
}
#apps_loop{
grid-template-columns: 1fr 1fr 1fr;
width: 100vw;
}
#links_loop {
grid-template-columns: 1fr 1fr 1fr;
}
#modal>div{
margin-left: auto;
margin-right: auto;
margin-top: 5vh;
width: 90%;
}
}
@media screen and (max-width: 667px)
{
html{
font-size: calc(16px + 6 * ((100vw - 320px) / 680));
}
#container{
align-items: stretch;
display: grid;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr;
grid-template-rows: 80px auto;
justify-items: stretch;
margin-bottom: 1vh;
width: 90%;
}
h1{
font-size: 4em;
height: auto;
margin-bottom: 0em;
}
h2{
font-size: 1em;
height: auto;
margin-bottom: 0em;
}
h3{
font-size: 1em;
}
#apps_loop{
grid-column-gap: 0px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr;
width: 100vw;
}
.apps_icon{
height: 64px;
margin-right: 0.8em;
padding-top: 14px;
}
.apps_icon span{
font-size: 2em;
line-height: 2.5rem;
}
#links_loop{
display: grid;
flex-wrap: nowrap;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
}
}
/* Small Screens */
@media only screen and (max-width: 400px) {
#app-address {
display: none;
}
}

16
assets/js/data.js Normal file
View File

@ -0,0 +1,16 @@
function fetchAndRender (name) {
fetch(name + '.json')
.then(response => response.json())
.then(data => {
const mysource = document.getElementById(name + '-template').innerHTML;
const mytemplate = Handlebars.compile(mysource);
const myresult = mytemplate(data);
document.getElementById(name).innerHTML = myresult;
});
}
document.addEventListener('DOMContentLoaded', () => {
fetchAndRender('apps');
fetchAndRender('links');
fetchAndRender('providers');
});

37
assets/js/script.js Normal file
View File

@ -0,0 +1,37 @@
function date() {
let currentDate = new Date();
let dateOptions = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
};
let date = currentDate.toLocaleDateString("en-GB", dateOptions);
document.getElementById("header_date").innerHTML = date;
}
function greet() {
let currentTime = new Date();
let greet = Math.floor(currentTime.getHours() / 6);
switch (greet) {
case 0:
document.getElementById("header_greet").innerHTML = "Good night!";
break;
case 1:
document.getElementById("header_greet").innerHTML = "Good morning!";
break;
case 2:
document.getElementById("header_greet").innerHTML = "Good afternoon!";
break;
case 3:
document.getElementById("header_greet").innerHTML = "Good evening!";
break;
}
}
function loadFunctions() {
date();
greet();
}

146
assets/js/search.js Normal file
View File

@ -0,0 +1,146 @@
var sindex = 0;
var cycle = false;
var sengine = "https://www.google.com/?q="; // Default search engine
function start() {
var query = getParameterByName('q');
if (query) search(query.replaceAll("+", "%2B"));
document.getElementById('keywords').focus();
window.setInterval(function () {
updatetime();
}, 200);
}
function handleKeyPress(e) {
var key = e.keyCode || e.which;
var text = document.getElementById("keywords").value.replaceAll("+", "%2B");
var option = text.substr(1, text.indexOf(' ') - 1) || text.substr(1);
var subtext = text.substr(2 + option.length);
if (key == 13) { // Search functions
search(text);
}
if (key == 9) { // Tab Completion Functions
e.preventDefault();
e.stopPropagation();
if (text[0] === ';') {
switch (option) {
case 't':
var streamers = ['admiralbahroo', 'moonmoon_ow', 'witwix'];
if (!subtext || cycle) {
cycle = true;
if (sindex > streamers.length - 1) sindex = 0;
document.getElementById("keywords").value = ';t ' + streamers[sindex++];
return;
}
for (var streamer of streamers) {
if (subtext === streamer.substr(0, subtext.length)) {
document.getElementById("keywords").value = ';t ' + streamer;
return;
}
}
break;
}
}
}
if(key == 32){ //Space to go to search
document.getElementById("keywords").focus();
}
sindex = 0;
cycle = false;
}
function search(text) {
var option = text.substr(1, text.indexOf(' ') - 1) || text.substr(1);
var subtext = text.substr(2 + option.length);
if (text[0] === '/') {
if (text.indexOf(' ') > -1) {
switch (option) {
case "am":
window.location = "https://www.allmusic.com/search/all/" + subtext;
break;
case "d":
window.location = "https://duckduckgo.com/?q=" + subtext;
break;
case "di":
window.location = "https://www.discogs.com/search/?q=" + subtext;
break;
case "i":
window.location = "https://www.imdb.com/find?q=" + subtext;
break;
case "m":
window.location = "https://www.themoviedb.org/search?query=" + subtext;
break;
case "r":
window.location = "https://www.reddit.com/search?q=" + subtext;
break;
case "q":
window.location = "https://www.qwant.com/?q=" + subtext;
break;
case "so":
window.location = "https://soundcloud.com/search?q=" + subtext;
break;
case "s":
window.location = "https://open.spotify.com/search/results/" + subtext;
break;
case "t":
window.location = "https://trakt.tv/search?query=" + subtext;
break;
case "tv":
window.location = "https://www.thetvdb.com/search?query=" + subtext;
break;
case "y":
window.location = "https://www.youtube.com/results?search_query=" + subtext;
break;
case "g":
window.location = "https://www.google.com/?q=" + subtext;
break;
}
} else {
var option = text.substr(1);
switch (option) {
case "d":
window.location = "https://www.duckduckgo.com";
break;
case "y":
window.location = "https://www.youtube.com";
break;
case "r":
window.location = "https://reddit.com";
break;
case "s":
window.location = "https://open.spotify.com";
break;
}
}
} else if (validURL(text)) {
if (containsProtocol(text))
window.location = text;
else
window.location = "https://" + text;
} else {
window.location = sengine + text;
}
}
// Source: https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url
function validURL(str) {
var pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
return !!pattern.test(str);
}
function containsProtocol(str) {
var pattern = new RegExp('^(https?:\\/\\/){1}.*', 'i');
return !!pattern.test(str);
}
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};

139
assets/js/themer.js Normal file
View File

@ -0,0 +1,139 @@
const setValue = (property, value) => {
if (value) {
document.documentElement.style.setProperty(`--${property}`, value);
const input = document.querySelector(`#${property}`);
if (input) {
value = value.replace('px', '');
input.value = value;
}
}
};
const setValueFromLocalStorage = property => {
let value = localStorage.getItem(property);
setValue(property, value);
};
const setTheme = options => {
for (let option of Object.keys(options)) {
const property = option;
const value = options[option];
setValue(property, value);
localStorage.setItem(property, value);
}
}
document.addEventListener('DOMContentLoaded', () => {
setValueFromLocalStorage('color-background');
setValueFromLocalStorage('color-text-pri');
setValueFromLocalStorage('color-text-acc');
});
const dataThemeButtons = document.querySelectorAll('[data-theme]');
for (let i = 0; i < dataThemeButtons.length; i++) {
dataThemeButtons[i].addEventListener('click', () => {
const theme = dataThemeButtons[i].dataset.theme;
switch (theme) {
case 'blackboard':
setTheme({
'color-background': '#1a1a1a',
'color-text-pri': '#FFFDEA',
'color-text-acc': '#5c5c5c'
});
return;
case 'gazette':
setTheme({
'color-background': '#F2F7FF',
'color-text-pri': '#000000',
'color-text-acc': '#5c5c5c'
});
return;
case 'espresso':
setTheme({
'color-background': '#21211F',
'color-text-pri': '#D1B59A',
'color-text-acc': '#4E4E4E'
});
return;
case 'cab':
setTheme({
'color-background': '#F6D305',
'color-text-pri': '#1F1F1F',
'color-text-acc': '#424242'
});
return;
case 'cloud':
setTheme({
'color-background': '#f1f2f0',
'color-text-pri': '#35342f',
'color-text-acc': '#37bbe4'
});
return;
case 'lime':
setTheme({
'color-background': '#263238',
'color-text-pri': '#AABBC3',
'color-text-acc': '#aeea00'
});
return;
case 'white':
setTheme({
'color-background': '#ffffff',
'color-text-pri': '#222222',
'color-text-acc': '#dddddd'
});
return;
case 'tron':
setTheme({
'color-background': '#242B33',
'color-text-pri': '#EFFBFF',
'color-text-acc': '#6EE2FF'
});
return;
case 'blues':
setTheme({
'color-background': '#2B2C56',
'color-text-pri': '#EFF1FC',
'color-text-acc': '#6677EB'
});
return;
case 'passion':
setTheme({
'color-background': '#f5f5f5',
'color-text-pri': '#12005e',
'color-text-acc': '#8e24aa'
});
return;
case 'chalk':
setTheme({
'color-background': '#263238',
'color-text-pri': '#AABBC3',
'color-text-acc': '#FF869A'
});
return;
case 'paper':
setTheme({
'color-background': '#F8F6F1',
'color-text-pri': '#4C432E',
'color-text-acc': '#AA9A73'
});
return;
}
})
}

24
docker-compose.yml Normal file
View File

@ -0,0 +1,24 @@
version: "3.5"
services:
sui:
container_name: sui
restart: always
build:
context: ./
environment:
- VIRTUAL_HOST=test.laserr.net
networks:
- nginx-proxy
- public
ports:
- 4000:80
volumes:
- ./:/opt/html
networks:
nginx-proxy:
external: true
public:
external:
name: public

2
gitpull.sh Normal file
View File

@ -0,0 +1,2 @@
cd /var/www/html
git pull

127
index.html Normal file
View File

@ -0,0 +1,127 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>SUI</title>
<meta charset="utf-8">
<meta name="description" content="a startpage for your server and / or new tab page">
<meta http-equiv="Default-Style" content="">
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<link type="text/css" rel="stylesheet" href="./assets/css/styles.css" media="screen,projection"/>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
<script src="https://code.iconify.design/1/1.0.7/iconify.min.js"></script>
</head>
<body onload="loadFunctions()">
<section id="modal">
<div>
<header id="modal-header">
<h1>Options</h1>
<a href="#" title="Close" class="modal-close">
<span class="iconify" data-icon="mdi-close"></span>
</a>
</header>
<h2>Color themes</h2>
<div id="modal-theme">
<button data-theme="blackboard" class="theme-button theme-blackboard">Blackboard</button>
<button data-theme="gazette" class="theme-button theme-gazette">Gazette</button>
<button data-theme="espresso" class="theme-button theme-espresso">Espresso</button>
<button data-theme="cab" class="theme-button theme-cab">Cab</button>
<button data-theme="cloud" class="theme-button theme-cloud">Cloud</button>
<button data-theme="lime" class="theme-button theme-lime">Lime</button>
<button data-theme="passion" class="theme-button theme-passion">Passion</button>
<button data-theme="blues" class="theme-button theme-blues">Blues</button>
<button data-theme="chalk" class="theme-button theme-chalk">Chalk</button>
<button data-theme="tron" class="theme-button theme-tron">Tron</button>
<button data-theme="paper" class="theme-button theme-paper">Paper</button>
</div>
<h2>Search options</h2>
<section id="providers">
<script type="text/handlebars-template" id="providers-template">
<table>
<tr>
<th>Website</th>
<th>Prefix</th>
</tr>
{{#providers}}
<tr>
<td><a href="{{url}}">{{name}}</a></td>
<td>{{prefix}}</td>
</tr>
{{/providers}}
</table>
</script>
</section>
<header id="modal-footer">
<a href="https://github.com/jeroenpardon/"><span class="iconify" data-icon="mdi-github-box"></span></a>
<a href="https://materialdesignicons.com/"><span class="iconify" data-icon="mdi-material-design"></span></a>
</header>
</div>
</section>
<main id="container" class="fade">
<section id="search">
<input name="keywords" type="text" id="keywords" size="50" spellcheck="false" autofocus="true" onkeydown="handleKeyPress(event)">
</section>
<section id="header">
<h2 id="header_date"></h2>
<h1 id="header_greet"></h1>
</section>
<section id="apps">
<script type="text/handlebars-template" id="apps-template">
<h3>Applications</h3>
<div id="apps_loop">
{{#apps}}
<div class="apps_item">
<div class="apps_icon">
<span class="iconify icon" data-icon="mdi-{{icon}}"></span>
</div>
<div class="apps_text">
<a href="http://{{url}}" {{#if target}}target="{{target}}"{{/if}} >{{name}}</a>
<span id="app-address">{{url}}</span>
</div>
</div>
{{/apps}}
</div>
</script>
</section>
<section id="links">
<script type="text/handlebars-template" id="links-template">
<h3>Bookmarks</h3>
<div id="links_loop">
{{#bookmarks}}
<div id="links_item">
<h4>{{category}}</h4>
{{#links}}
<a href="{{url}}" target="{{target}}" class="theme_color-border theme_text-select">{{name}}</a>
{{/links}}
</div>
{{/bookmarks}}
</div>
</script>
</section>
</main>
<div id="modal_init">
<a class="btn" href="#modal">
<span class="iconify icon" data-icon="mdi-xbox-controller-menu"></span>
</a>
</div>
<script src="./assets/js/data.js" type="text/javascript"></script>
<script src="./assets/js/script.js" type="text/javascript"></script>
<script src="./assets/js/themer.js" type="text/javascript"></script>
<script src="./assets/js/search.js" type="text/javascript"></script>
</body>
</html>

24
install.sh Normal file
View File

@ -0,0 +1,24 @@
cd /var/www/html
git clone $GITURL sui
shopt -s dotglob
mv sui/* .
rm -rf sui
echo "pulled update"
# Copy hello-cron file to the cron.d directory
cp sui-cron /etc/cron.d/sui-cron
# Give execution rights on the cron job
chmod 0644 /etc/cron.d/sui-cron
# set pull script permissions
chmod +x gitpull.sh
# Apply cron job
crontab /etc/cron.d/sui-cron
# Create the log file to be able to run tail
touch /var/log/cron.log
# configure nginx
echo "daemon off;" >> /etc/nginx/nginx.conf

143
links.json Normal file
View File

@ -0,0 +1,143 @@
{
"bookmarks" : [
{
"category": "Communicate",
"links": [
{
"name": "Discord",
"url": "https://discord.com"
},
{
"name": "Gmail",
"url": "http://gmail.com"
},
{
"name": "Slack",
"url": "https://slack.com/signin",
"target": "_blank"
}
]
},
{
"category": "Cloud",
"links": [
{
"name": "Box",
"url": "https://box.com",
"target": "sui"
},
{
"name": "Dropbox",
"url": "https://dropbox.com",
"target": "sui"
},
{
"name": "Drive",
"url": "https://drive.google.com"
}
]
},
{
"category": "Design",
"links": [
{
"name": "Awwwards",
"url": "https://awwwards.com"
},
{
"name": "Dribbble",
"url": "https://dribbble.com"
},
{
"name": "Muz.li",
"url": "https://medium.muz.li/"
}
]
},
{
"category": "Dev",
"links": [
{
"name": "Codepen",
"url": "https://codepen.io/"
},
{
"name": "Devdocs",
"url": "https://devdocs.io"
},
{
"name": "Devhints",
"url": "https://devhints.io"
}
]
},
{
"category": "Lifestyle",
"links": [
{
"name": "Design Milk",
"url": "https://design-milk.com/category/interior-design/"
},
{
"name": "Dwell",
"url": "https://www.dwell.com/"
},
{
"name": "Freshome",
"url": "https://www.mymove.com/freshome/"
}
]
},
{
"category": "Media",
"links": [
{
"name": "Spotify",
"url": "http://browse.spotify.com"
},
{
"name": "Trakt",
"url": "http://trakt.tv"
},
{
"name": "YouTube",
"url": "https://youtube.com/feed/subscriptions"
}
]
},
{
"category": "Reading",
"links": [
{
"name": "Instapaper",
"url": "https://www.instapaper.com/u"
},
{
"name": "Medium",
"url": "http://medium.com"
},
{
"name": "Reddit",
"url": "http://reddit.com"
}
]
},
{
"category": "Tech",
"links": [
{
"name": "TheNextWeb",
"url": "https://thenextweb.com/"
},
{
"name": "The Verge",
"url": "https://theverge.com/"
},
{
"name": "MIT Technology Review",
"url": "https://www.technologyreview.com/"
}
]
}
]
}

15
providers.json Normal file
View File

@ -0,0 +1,15 @@
{
"providers" : [
{"name":"Allmusic","url":"https://www.allmusic.com/search/all/","prefix":"/a"},
{"name":"Discogs","url":"https://www.discogs.com/search/?q=","prefix":"/di"},
{"name":"Duck Duck Go","url":"https://duckduckgo.com/?q=","prefix":"/d"},
{"name":"iMDB","url":"https://www.imdb.com/find?q=","prefix":"/i"},
{"name":"TheMovieDB","url":"https://www.themoviedb.org/search?query=","prefix":"/m"},
{"name":"Reddit","url":"https://www.reddit.com/search?q=","prefix":"/r"},
{"name":"Qwant","url":"https://www.qwant.com/?q=","prefix":"/q"},
{"name":"Soundcloud","url":"https://soundcloud.com/search?q=","prefix":"/so"},
{"name":"Spotify","url":"https://open.spotify.com/search/results/","prefix":"/s"},
{"name":"TheTVDB","url":"https://www.thetvdb.com/search?query=","prefix":"/tv"},
{"name":"Trakt","url":"https://trakt.tv/search?query=","prefix":"/t"}
]
}

2
sui-cron Normal file
View File

@ -0,0 +1,2 @@
*/1 * * * * /var/www/html/gitpull.sh >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.