Compare commits
149
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d728c8e68 | ||
|
|
ef3aed4ba2 | ||
|
|
8f30fdb88c | ||
|
|
d4b67906cd | ||
|
|
075fa32ea2 | ||
|
|
f71f678662 | ||
|
|
457857df32 | ||
|
|
49adc84f5c | ||
|
|
a2a9a8c3a0 | ||
|
|
a62db898aa | ||
|
|
a2a6e5c5fe | ||
|
|
b9307efba2 | ||
|
|
52ccff4086 | ||
|
|
7f59856da3 | ||
|
|
10dc913080 | ||
|
|
1d2f190459 | ||
|
|
859ab9cfaf | ||
|
|
924d3dabb9 | ||
|
|
b227337ced | ||
|
|
717ffb4b8a | ||
|
|
08121fc701 | ||
|
|
460f18d85a | ||
|
|
6c34d510e5 | ||
|
|
789fc8bcbc | ||
|
|
31e72f28b0 | ||
|
|
3d0b87998d | ||
|
|
6c7b9a4ad8 | ||
|
|
f4379b07ca | ||
|
|
55364da10b | ||
|
|
e28b34b49b | ||
|
|
7ce3167d57 | ||
|
|
b0b9ae068a | ||
|
|
54349b4e8a | ||
|
|
2483e71d98 | ||
|
|
6b46873009 | ||
|
|
685a76bdd1 | ||
|
|
933a8bf3c8 | ||
|
|
e228d20d0b | ||
|
|
19ec49778e | ||
|
|
17dbe04c4b | ||
|
|
e5404fa1b9 | ||
|
|
f6506aeeca | ||
|
|
795720dcd2 | ||
|
|
85962b11a6 | ||
|
|
c1229b348e | ||
|
|
06358c4c07 | ||
|
|
fffde38fed | ||
|
|
13bfc40c6a | ||
|
|
9024a1eab6 | ||
|
|
aa851a7779 | ||
|
|
ac3d20d072 | ||
|
|
02f16516f1 | ||
|
|
c8301113e5 | ||
|
|
73fd35ad40 | ||
|
|
996ed3d776 | ||
|
|
05feced28f | ||
|
|
fe844437fb | ||
|
|
3de05c08bc | ||
|
|
e6509e0932 | ||
|
|
ce95ed4854 | ||
|
|
3bf2d553c8 | ||
|
|
b3fb490c16 | ||
|
|
5e8c2c73fd | ||
|
|
a75aabbec6 | ||
|
|
583522a422 | ||
|
|
a9b4a95e0c | ||
|
|
8b68d52be0 | ||
|
|
8f52aca2b4 | ||
|
|
744f920854 | ||
|
|
fe43d274cb | ||
|
|
53f4c17a08 | ||
|
|
f728cdafb4 | ||
|
|
21b4b9b7fb | ||
|
|
87a5e40e3e | ||
|
|
bf7f831c42 | ||
|
|
f74a1a7076 | ||
|
|
6c9c0ffad2 | ||
|
|
4b1d75b1ba | ||
|
|
6f06f7d657 | ||
|
|
91c4928ec7 | ||
|
|
9ce785014d | ||
|
|
e139dcea35 | ||
|
|
adb18644ee | ||
|
|
bccd344aa7 | ||
|
|
3315fbdb4f | ||
|
|
5bbe4c5c61 | ||
|
|
2366d0c2a8 | ||
|
|
a4d9f63568 | ||
|
|
496f2b3bfb | ||
|
|
cb7a010fb6 | ||
|
|
5b5093708d | ||
|
|
975252656f | ||
|
|
0b7da7a5c9 | ||
|
|
4e70e2d28d | ||
|
|
705db14521 | ||
|
|
5b5d62e4fa | ||
|
|
9afe770202 | ||
|
|
6a52ed2f66 | ||
|
|
279d59e376 | ||
|
|
a6d9f29f1a | ||
|
|
bb36edfca5 | ||
|
|
f451b8ff3b | ||
|
|
b837e1a952 | ||
|
|
aa1501214d | ||
|
|
246eff86a6 | ||
|
|
e2ea76c6c9 | ||
|
|
ad4fe6df26 | ||
|
|
43a000a9c1 | ||
|
|
32a0e65a68 | ||
|
|
b80be01a52 | ||
|
|
daa935bbef | ||
|
|
cb49bfba58 | ||
|
|
60af5e87ce | ||
|
|
aad687f630 | ||
|
|
6b30f381df | ||
|
|
5b03dc35b4 | ||
|
|
f9732160f0 | ||
|
|
8a84a8d42f | ||
|
|
39e6a69a08 | ||
|
|
c9d6d77931 | ||
|
|
2f30234edd | ||
|
|
cdd1dd0245 | ||
|
|
df9d6c93cc | ||
|
|
80a75a445e | ||
|
|
385d42d0be | ||
|
|
2514603962 | ||
|
|
d071b135e7 | ||
|
|
433185df3e | ||
|
|
ccad16f38c | ||
|
|
c7e5afc750 | ||
|
|
80877663a9 | ||
|
|
ceaf0f0ef6 | ||
|
|
d6135402c2 | ||
|
|
fa365f956e | ||
|
|
82ed5d12e1 | ||
|
|
a9b6c92864 | ||
|
|
cc2d9e1b14 | ||
|
|
3dd8fdb7ca | ||
|
|
db20b291e3 | ||
|
|
096a71a7fc | ||
|
|
83d346b632 | ||
|
|
202797aed5 | ||
|
|
0cb583de09 | ||
|
|
bf19250116 | ||
|
|
e59e7b439d | ||
|
|
83e2ba5be2 | ||
|
|
7cc8891533 | ||
|
|
8a0cd24d69 | ||
|
|
1cb49c3127 |
@@ -0,0 +1,16 @@
|
|||||||
|
FROM gitea.tryton.geeraert.eu/pi-ux-ce/python:3
|
||||||
|
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
WORKDIR /code/
|
||||||
|
|
||||||
|
# Copy only the requirements file first (Changes infrequently)
|
||||||
|
COPY requirements.txt ./
|
||||||
|
|
||||||
|
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade pip
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/pip pip list --outdated
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade wheel
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade setuptools
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
django
|
||||||
|
psycopg2
|
||||||
|
requests
|
||||||
|
proxmoxer
|
||||||
|
docker
|
||||||
|
kubernetes
|
||||||
|
ruamel.yaml
|
||||||
|
pyyaml
|
||||||
|
django-bootstrap-v5
|
||||||
|
jinja2
|
||||||
|
watchdog
|
||||||
|
celery
|
||||||
|
redis
|
||||||
|
lxml
|
||||||
|
requests
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
name: Gitea Actions Demo
|
||||||
|
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
#paths-ignore:
|
||||||
|
# - 'requirements.txt'
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Job to check for file changes and set an output
|
||||||
|
changes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
requirements_changed: ${{ steps.filter.outputs.requirements }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dorny/paths-filter@v3
|
||||||
|
id: filter
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
requirements:
|
||||||
|
- 'requirements.txt'
|
||||||
|
|
||||||
|
Build-dockerfile:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.requirements_changed == 'true' }}
|
||||||
|
steps:
|
||||||
|
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
|
||||||
|
- name: Compute next version
|
||||||
|
id: versioning
|
||||||
|
run: |
|
||||||
|
latest="${{ vars.PYTHON_VERSION }}"
|
||||||
|
next_version=$(echo "$latest" | awk -F. -v OFS=. '{$NF += 1 ; print}')
|
||||||
|
echo "next_version=$next_version" >> $GITHUB_ENV
|
||||||
|
echo "Variables used :"
|
||||||
|
echo "------------------------------------------------"
|
||||||
|
echo "Next version: $next_version"
|
||||||
|
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /root/.cache/pip
|
||||||
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pip-
|
||||||
|
|
||||||
|
|
||||||
|
- name: inject cache into docker
|
||||||
|
uses: reproducible-containers/buildkit-cache-dance@v3.1.0
|
||||||
|
with:
|
||||||
|
cache-source: /root/.cache/pip
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to gitea
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: gitea.tryton.geeraert.eu
|
||||||
|
username: ${{ secrets.USERNAME_GITEA }}
|
||||||
|
password: ${{ secrets.PASSWORD_GITEA }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: "{{defaultContext}}:.gitea/python_build"
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:latest
|
||||||
|
gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:${{ env.next_version }}
|
||||||
|
cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:buildcache
|
||||||
|
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:buildcache,mode=max
|
||||||
|
|
||||||
|
- name: update version in the variable
|
||||||
|
run: |
|
||||||
|
curl -X PUT -H "Content-Type: application/json" \
|
||||||
|
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
|
||||||
|
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/PYTHON_VERSION \
|
||||||
|
-d "{\"Value\":\"$next_version\"}"
|
||||||
|
Explore-Gitea-Actions:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
|
||||||
|
- name: Compute next version
|
||||||
|
id: versioning
|
||||||
|
run: |
|
||||||
|
latest="${{ vars.VERSION }}"
|
||||||
|
next_version=$(echo "$latest" | awk -F. -v OFS=. '{$NF += 1 ; print}')
|
||||||
|
echo "next_version=$next_version" >> $GITHUB_ENV
|
||||||
|
echo "Variables used :"
|
||||||
|
echo "------------------------------------------------"
|
||||||
|
echo "Next version: $next_version"
|
||||||
|
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /root/.cache/pip
|
||||||
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pip-
|
||||||
|
|
||||||
|
|
||||||
|
- name: inject cache into docker
|
||||||
|
uses: reproducible-containers/buildkit-cache-dance@v3.1.0
|
||||||
|
with:
|
||||||
|
cache-source: /root/.cache/pip
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to gitea
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: gitea.tryton.geeraert.eu
|
||||||
|
username: ${{ secrets.USERNAME_GITEA }}
|
||||||
|
password: ${{ secrets.PASSWORD_GITEA }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest
|
||||||
|
gitea.tryton.geeraert.eu/pi-ux-ce/django-python:${{ env.next_version }}
|
||||||
|
cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-python:buildcache
|
||||||
|
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-python:buildcache,mode=max
|
||||||
|
|
||||||
|
- name: Rollout Django to force pulling the new image
|
||||||
|
uses: actions-hub/kubectl@master
|
||||||
|
env:
|
||||||
|
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
|
||||||
|
with:
|
||||||
|
args: rollout restart deployment django -n django
|
||||||
|
|
||||||
|
- name: Rollout Celery worker to force pulling the new image
|
||||||
|
uses: actions-hub/kubectl@master
|
||||||
|
env:
|
||||||
|
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
|
||||||
|
with:
|
||||||
|
args: rollout restart deployment celery-worker -n django
|
||||||
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
|
|
||||||
|
- name: update version in the variable
|
||||||
|
run: |
|
||||||
|
curl -X PUT -H "Content-Type: application/json" \
|
||||||
|
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
|
||||||
|
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION \
|
||||||
|
-d "{\"Value\":\"$next_version\"}"
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
name: Gitea Actions Demo
|
name: Gitea Actions Demo
|
||||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||||
on: [push]
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*"
|
||||||
|
paths:
|
||||||
|
- '*.yaml'
|
||||||
|
tags-ignore:
|
||||||
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Explore-Gitea-Actions:
|
Explore-Gitea-Actions:
|
||||||
@@ -13,22 +20,6 @@ jobs:
|
|||||||
- name: List files in the repository
|
- name: List files in the repository
|
||||||
run: |
|
run: |
|
||||||
ls ${{ gitea.workspace }}
|
ls ${{ gitea.workspace }}
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Login to gitea
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: gitea.tryton.geeraert.eu
|
|
||||||
username: ${{ secrets.USERNAME_GITEA }}
|
|
||||||
password: ${{ secrets.PASSWORD_GITEA }}
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
push: true
|
|
||||||
tags: gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest
|
|
||||||
|
|
||||||
|
|
||||||
- name: Perform kubectl tasks
|
- name: Perform kubectl tasks
|
||||||
uses: actions-hub/kubectl@master
|
uses: actions-hub/kubectl@master
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
*/__pycache__/*
|
||||||
|
*/.idea
|
||||||
|
venv/*
|
||||||
|
*__pycache__*
|
||||||
|
Webcal-python/*
|
||||||
|
.idea/*
|
||||||
@@ -20,18 +20,20 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: django-python
|
- name: django-python
|
||||||
# image: localhost:31795/django-python
|
image: gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest
|
||||||
image: gitea.tryton.geeraert.eu/pi-ux-ce/django-python:1.0.0
|
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
name: webserver-port
|
name: webserver-port
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: django-python-code
|
## - name: django-python-code
|
||||||
mountPath: /code
|
# mountPath: /code
|
||||||
- name: servarr-data
|
- name: servarr-data
|
||||||
mountPath: /data
|
mountPath: /data
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- name: secret-kubeconfig
|
||||||
|
mountPath: /kubeconfig
|
||||||
|
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@@ -44,6 +46,10 @@ spec:
|
|||||||
- name: servarr-data
|
- name: servarr-data
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /data
|
path: /data
|
||||||
|
- name: secret-kubeconfig
|
||||||
|
secret:
|
||||||
|
defaultMode: 420
|
||||||
|
secretName: kubeconfig
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
=======
|
=======
|
||||||
# Django_kube
|
# Django_kube
|
||||||
|
test
|
||||||
|
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}{% endblock %}</title>
|
||||||
|
{% load bootstrap5 %}
|
||||||
|
{% bootstrap_css %}
|
||||||
|
{% bootstrap_javascript %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1 class="display-1">Welcome to my website!</h1>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="list-group">
|
||||||
|
{% if thislist %}
|
||||||
|
<ul>
|
||||||
|
{% for question in thislist %}
|
||||||
|
<a href="#" class="list-group-item">{{ question }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No polls are available.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>My Website</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to my website!</h1>
|
||||||
|
{% if thislist %}
|
||||||
|
<ul>
|
||||||
|
{% for question in thislist %}
|
||||||
|
<h1>{{ question }}</h1>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No polls are available.</p>
|
||||||
|
{% endif %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>Scaled down</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Varela Round', sans-serif;
|
||||||
|
}
|
||||||
|
.modal-confirm {
|
||||||
|
color: #636363;
|
||||||
|
width: 325px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-content {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-header {
|
||||||
|
border-bottom: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.modal-confirm h4 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26px;
|
||||||
|
margin: 30px 0 -15px;
|
||||||
|
}
|
||||||
|
.modal-confirm .form-control, .modal-confirm .btn {
|
||||||
|
min-height: 40px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.modal-confirm .close {
|
||||||
|
position: absolute;
|
||||||
|
top: -5px;
|
||||||
|
right: -5px;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-footer {
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box {
|
||||||
|
color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0 auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: -70px;
|
||||||
|
width: 105px;
|
||||||
|
height: 105px;
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: 9;
|
||||||
|
/*background: #82ce34;*/
|
||||||
|
background: #a80505;
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box i {
|
||||||
|
font-size: 58px;
|
||||||
|
position: relative;
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box:hover,.modal-confirm .icon-box:focus {
|
||||||
|
background: #6fb32b;
|
||||||
|
/*background: #a80505;*/
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.modal-confirm.modal-dialog {
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
.modal-confirm .btn {
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
/*background: #82ce34;*/
|
||||||
|
background: #a80505;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.4s;
|
||||||
|
line-height: normal;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.modal-confirm .btn:hover, .modal-confirm .btn:focus {
|
||||||
|
background: #800404;
|
||||||
|
/*background: #a80505;*/
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.trigger-btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 100px auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="text-center">
|
||||||
|
<!-- Button HTML (to Trigger Modal) -->
|
||||||
|
<!--<a href="#myModal" class="trigger-btn" data-toggle="modal">Click to Open Confirm Modal</a> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal HTML -->
|
||||||
|
<!--<div id="myModal" class="modal fade">-->
|
||||||
|
<div class="modal-dialog modal-confirm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="icon-box" onclick="window.location='/kubernetes_connection/scale_up/{{namespace}}/{{deployment}}';">
|
||||||
|
<!--<i class="material-icons"></i>-->
|
||||||
|
<i class="material-icons">×</i>
|
||||||
|
</div>
|
||||||
|
<h4 class="modal-title w-100">Too bad!</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p class="text-center">{{ deployment }} deployment from namespace {{ namespace }} is now scaled down.</p>
|
||||||
|
<p class="text-center">Current URL {{ url }}.</p>
|
||||||
|
<p class="text-center">base URL {{ baseurl }}.</p>
|
||||||
|
</div>
|
||||||
|
<div href={{ url }} class="modal-footer">
|
||||||
|
<!--<button href={{ url }} class="btn btn-success btn-block" data-dismiss="modal">Redirect</button>-->
|
||||||
|
<a href="https://google.fr" class="btn btn-success btn-block" data-dismiss="modal">Redirect</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>Scaled up</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Varela Round', sans-serif;
|
||||||
|
}
|
||||||
|
.modal-confirm {
|
||||||
|
color: #636363;
|
||||||
|
width: 325px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-content {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-header {
|
||||||
|
border-bottom: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.modal-confirm h4 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26px;
|
||||||
|
margin: 30px 0 -15px;
|
||||||
|
}
|
||||||
|
.modal-confirm .form-control, .modal-confirm .btn {
|
||||||
|
min-height: 40px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.modal-confirm .close {
|
||||||
|
position: absolute;
|
||||||
|
top: -5px;
|
||||||
|
right: -5px;
|
||||||
|
}
|
||||||
|
.modal-confirm .modal-footer {
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box {
|
||||||
|
color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0 auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: -70px;
|
||||||
|
width: 95px;
|
||||||
|
height: 95px;
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: 9;
|
||||||
|
background: #82ce34;
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box i {
|
||||||
|
font-size: 58px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
.modal-confirm .icon-box:hover,.modal-confirm .icon-box:focus {
|
||||||
|
/*background: #6fb32b;*/
|
||||||
|
background: #a80505;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.modal-confirm.modal-dialog {
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
.modal-confirm .btn {
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #82ce34;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.4s;
|
||||||
|
line-height: normal;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.modal-confirm .btn:hover, .modal-confirm .btn:focus {
|
||||||
|
background: #6fb32b;
|
||||||
|
/*background: #a80505;*/
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.trigger-btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 100px auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="text-center">
|
||||||
|
<!-- Button HTML (to Trigger Modal) -->
|
||||||
|
<!--<a href="#myModal" class="trigger-btn" data-toggle="modal">Click to Open Confirm Modal</a> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal HTML -->
|
||||||
|
<!--<div id="myModal" class="modal fade">-->
|
||||||
|
<div class="modal-dialog modal-confirm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="icon-box" onclick="window.location='/kubernetes_connection/scale_down/{{namespace}}/{{deployment}}';">
|
||||||
|
<!--<i class="material-icons"></i>-->
|
||||||
|
<i class="material-icons"></i>
|
||||||
|
</div>
|
||||||
|
<h4 class="modal-title w-100">Awesome!</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p class="text-center">{{ deployment }} deployment from namespace {{ namespace }} is now scaled up.</p>
|
||||||
|
<p class="text-center">Current URL {{ url }}.</p>
|
||||||
|
<p class="text-center">base URL {{ baseurl }}.</p>
|
||||||
|
</div>
|
||||||
|
<div href={{ url }} class="modal-footer">
|
||||||
|
<!--<button href={{ url }} class="btn btn-success btn-block" data-dismiss="modal">Redirect</button>-->
|
||||||
|
|
||||||
|
<a href="https://google.fr" class="btn btn-success btn-block" data-dismiss="modal">Redirect</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
||||||
|
def home(request):
|
||||||
|
thislist = ["apple", "banana", "cherry"]
|
||||||
|
return render(request, 'home.html',{'thislist': thislist})
|
||||||
|
|
||||||
|
def about(request):
|
||||||
|
thislist = ["apple", "banana", "cherry"]
|
||||||
|
return render(request, 'about.html',{'thislist': thislist})
|
||||||
|
|
||||||
|
def success(request):
|
||||||
|
return render(request, 'start.html',{'deployment': 'django','url':'https://google.com'})
|
||||||
|
|
||||||
|
def scale_up(request,namespace_name,deploy_name):
|
||||||
|
baseurl = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
|
||||||
|
return render(request, 'start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com','baseurl': baseurl})
|
||||||
|
|
||||||
|
def scale_down(request,namespace_name,deploy_name):
|
||||||
|
baseurl = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
|
||||||
|
return render(request, 'shutdown.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com','baseurl': baseurl})
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from .celery_settings import app as celery_app
|
||||||
|
|
||||||
|
__all__ = ("celery_app",)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
import os
|
||||||
|
from celery import Celery
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_code.settings')
|
||||||
|
|
||||||
|
app = Celery("django_code")
|
||||||
|
app.config_from_object("django.conf:settings", namespace="CELERY")
|
||||||
|
app.autodiscover_tasks()
|
||||||
@@ -25,7 +25,7 @@ SECRET_KEY = 'django-insecure-71%)_#e#o9-dl2o^6mfud-*rw+4+8vy-nd*bzeier&(34ap-p9
|
|||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['reverse.tryton.geeraert.eu','192.168.4.100','django.tryton.geeraert.eu']
|
ALLOWED_HOSTS = ['reverse.tryton.geeraert.eu','192.168.4.100','django.tryton.geeraert.eu','localhost']
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
@@ -37,6 +37,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'bootstrap5',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -54,7 +55,8 @@ ROOT_URLCONF = 'django_code.urls'
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': [],
|
#'DIRS': ["/code/django_code/templates","/code/django_code/dashboard/templates/"],
|
||||||
|
'DIRS': [BASE_DIR / "templates","django_code/dashboard/templates/","django_code/stash_management/templates"],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
@@ -121,3 +123,12 @@ STATIC_URL = 'static/'
|
|||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
#
|
||||||
|
# Celery settings
|
||||||
|
CELERY_BROKER_URL = "redis://django-redis-svc:6379"
|
||||||
|
CELERY_RESULT_BACKEND = "redis://django-redis-svc:6379"
|
||||||
|
|
||||||
|
CELERY_IMPORTS = [
|
||||||
|
'stash_management.apps', # This line imports the tasks.py file
|
||||||
|
# Add other app tasks here if needed
|
||||||
|
]
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ from django.urls import path
|
|||||||
from random_simpsons import apps as random_simpsons
|
from random_simpsons import apps as random_simpsons
|
||||||
from paperless_django import apps as paperless_django
|
from paperless_django import apps as paperless_django
|
||||||
from onenote import apps as onenote
|
from onenote import apps as onenote
|
||||||
from dashboard import apps as dashboard
|
from dashboard import apps as dashboardapp
|
||||||
|
from dashboard import views as dashboardview
|
||||||
|
from kubernetes_connection import apps as kubernetes_connection
|
||||||
|
from stash_management import apps as stashapp
|
||||||
|
from stash_management import views as stashview
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# path('admin/', admin.site.urls),
|
# path('admin/', admin.site.urls),
|
||||||
@@ -38,7 +42,32 @@ urlpatterns = [
|
|||||||
path('onenote/hello/', onenote.hello),
|
path('onenote/hello/', onenote.hello),
|
||||||
|
|
||||||
################### onenote ###################
|
################### onenote ###################
|
||||||
path('dashboard/hello/', dashboard.hello),
|
path('dashboard/hello/', dashboardapp.hello),
|
||||||
|
path('dashboard/view/about', dashboardview.about),
|
||||||
|
path('dashboard/view/home', dashboardview.home),
|
||||||
|
path('dashboard/view/success', dashboardview.success),
|
||||||
|
path('dashboard/scale_up/<str:namespace_name>/<str:deploy_name>', dashboardview.scale_up),
|
||||||
|
path('dashboard/scale_down/<str:namespace_name>/<str:deploy_name>', dashboardview.scale_down),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################## kubernetes_connection#####
|
||||||
|
path('kubernetes_connection/hello/', kubernetes_connection.hello),
|
||||||
|
path('kubernetes_connection/nodes/', kubernetes_connection.nodes),
|
||||||
|
path('kubernetes_connection/backup_job/', kubernetes_connection.backup_job),
|
||||||
|
path('kubernetes_connection/backup_job_yaml/', kubernetes_connection.backup_job_yaml),
|
||||||
|
path('kubernetes_connection/scale_up/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_up),
|
||||||
|
path('kubernetes_connection/scale_down/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_down),
|
||||||
|
|
||||||
|
################## kubernetes_connection#####
|
||||||
|
path('stash/', stashview.home),
|
||||||
|
path('stash/hello/', stashapp.hello),
|
||||||
|
path('stash/form/', stashapp.form),
|
||||||
|
path('stash/incremental/', stashapp.incremental),
|
||||||
|
path('stash/album/', stashapp.album),
|
||||||
|
path('stash/album-form/', stashapp.album_form, name='submit_form'),
|
||||||
|
path('stash/submit-form/', stashapp.handle_survey_form, name='submit_form'),
|
||||||
|
path('stash/incremental-form/', stashapp.incremental_form, name='submit_form'),
|
||||||
|
|
||||||
|
|
||||||
# path('bookstack/', docker_connection.apps.hello),
|
# path('bookstack/', docker_connection.apps.hello),
|
||||||
|
|||||||
@@ -14,3 +14,10 @@ from django.core.wsgi import get_wsgi_application
|
|||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_code.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_code.settings')
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
https_proxy = "gluetun-svc.gluetun.svc:8888"
|
||||||
|
|
||||||
|
proxyDict = {
|
||||||
|
"https" : https_proxy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#os.environ["PROXIES"] = proxyDict
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
|
||||||
|
from django.core.files import File
|
||||||
|
from kubernetes import client, config
|
||||||
|
|
||||||
|
#from django.template.loader import render_to_string
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import mimetypes
|
||||||
|
import ruamel.yaml
|
||||||
|
import yaml
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
def hello(request):
|
||||||
|
return HttpResponse('<h1>Hello k8s!</h1>')
|
||||||
|
|
||||||
|
def scale_up(request,namespace_name,deploy_name):
|
||||||
|
config.load_kube_config(config_file='/kubeconfig/config')
|
||||||
|
api = client.AppsV1Api()
|
||||||
|
deployment = api.read_namespaced_deployment(name=deploy_name, namespace=namespace_name)
|
||||||
|
deployment.spec.replicas = 1
|
||||||
|
resp = api.patch_namespaced_deployment(
|
||||||
|
name=deploy_name, namespace=namespace_name, body=deployment);
|
||||||
|
#return HttpResponse('<h1>Scaled up !</h1>')
|
||||||
|
return render(request, 'start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com'})
|
||||||
|
|
||||||
|
|
||||||
|
def scale_down(request,namespace_name,deploy_name):
|
||||||
|
config.load_kube_config(config_file='/kubeconfig/config')
|
||||||
|
api = client.AppsV1Api()
|
||||||
|
deployment = api.read_namespaced_deployment(name=deploy_name, namespace=namespace_name)
|
||||||
|
deployment.spec.replicas = 0
|
||||||
|
resp = api.patch_namespaced_deployment(
|
||||||
|
name=deploy_name, namespace=namespace_name, body=deployment);
|
||||||
|
#return HttpResponse('<h1>Scaled down !</h1>')
|
||||||
|
return render(request, 'shutdown.html',
|
||||||
|
{'namespace': namespace_name, 'deployment': deploy_name, 'url': 'https://namespace.com'})
|
||||||
|
|
||||||
|
def nodes(request):
|
||||||
|
config.load_kube_config(config_file='/code/kubeconfig')
|
||||||
|
v1 = client.CoreV1Api()
|
||||||
|
# v1.list_node()
|
||||||
|
pod_manifest = {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'Pod',
|
||||||
|
'metadata': {
|
||||||
|
'labels': {
|
||||||
|
'bot': 'current-bot'
|
||||||
|
},
|
||||||
|
'name': 'podname',
|
||||||
|
'namespace': 'echo-server'
|
||||||
|
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
|
||||||
|
'containers': [{
|
||||||
|
'image': 'gitea.tryton.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||||
|
# 'pod-running-timeout': '5m0s',
|
||||||
|
'name': 'testpython',
|
||||||
|
'env': [
|
||||||
|
{'name': 'env_variable', 'value': 'env_value'},
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
'restartPolicy': 'Always',
|
||||||
|
# 'serviceAccountName': 'bots-service-account'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# print(f'POD MANIFEST:\n{pod_manifest}')
|
||||||
|
api_response = v1.create_namespaced_pod(body=pod_manifest,namespace='echo-server')
|
||||||
|
return HttpResponse(api_response)
|
||||||
|
|
||||||
|
def backup_job(request):
|
||||||
|
config.load_kube_config(config_file='/code/kubeconfig')
|
||||||
|
v1 = client.CoreV1Api()
|
||||||
|
#v1 = client.BatchV1Api()
|
||||||
|
# v1.list_node()
|
||||||
|
pod_manifest_job = {
|
||||||
|
'apiVersion': 'batch/v1',
|
||||||
|
'kind': 'Job',
|
||||||
|
'metadata': {
|
||||||
|
'name': 'bitwarden-backup-django',
|
||||||
|
'namespace': 'bwbackup'
|
||||||
|
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'template': {
|
||||||
|
'spec': {
|
||||||
|
|
||||||
|
'containers': [{
|
||||||
|
'image': 'gitea.tryton.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||||
|
'name': 'testpython',
|
||||||
|
'command': ['/bin/sh -c /config/export_bitwarden.sh'],
|
||||||
|
'env': [
|
||||||
|
{'name': 'env_variable', 'value': 'env_value'},
|
||||||
|
],
|
||||||
|
'volumeMounts': [
|
||||||
|
{'name': 'scripts', 'configMap': [{'name':'bitwarden-export-scripts'},]},
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
'restartPolicy': 'Always',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
api_response = v1.create_namespaced_job(body=pod_manifest_job)
|
||||||
|
return HttpResponse(api_response)
|
||||||
|
|
||||||
|
|
||||||
|
#help with yaml import
|
||||||
|
#https://github.com/kubernetes-client/python/issues/589
|
||||||
|
|
||||||
|
def backup_job_yaml(request,sync_target):
|
||||||
|
config.load_kube_config(config_file='/code/kubeconfig')
|
||||||
|
v1 = client.BatchV1Api()
|
||||||
|
|
||||||
|
yaml_location = {
|
||||||
|
"synology" : "https://gitea.tryton.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/synology_pod.yaml",
|
||||||
|
"openmediavault":"https://gitea.tryton.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/openmediavault_pod.yaml"
|
||||||
|
}
|
||||||
|
print(yaml_location[sync_target])
|
||||||
|
url_to_select=yaml_location[sync_target]
|
||||||
|
api_response = v1.create_namespaced_job(body=pod_manifest_job)
|
||||||
|
|
||||||
|
return HttpResponse(api_response)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<h1>Hello template!</h1>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
def hello(request):
|
||||||
|
return HttpResponse('<h1>Hello Django!</h1>')
|
||||||
Binary file not shown.
@@ -2,9 +2,26 @@ from django.apps import AppConfig
|
|||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
import time
|
#from django.template.loader import render_to_string
|
||||||
import random
|
from django.template import loader
|
||||||
|
#import time
|
||||||
|
#import random
|
||||||
|
|
||||||
def hello(request):
|
def hello(request):
|
||||||
return HttpResponse('<h1>Hello onenote! <h1>')
|
# htmlContent = '
|
||||||
|
#<!DOCTYPE html>
|
||||||
|
#<html lang="en">
|
||||||
|
#<body>
|
||||||
|
#<strong>Hello World from const</strong>
|
||||||
|
#</body>
|
||||||
|
#</html>
|
||||||
|
#'
|
||||||
|
# response = "coucou"
|
||||||
|
# context = {'response': HttpResponse(response)}
|
||||||
|
# return HttpResponse(htmlContent)
|
||||||
|
# return HttpResponse('<h1>Hello onenote! <h1>')
|
||||||
|
# return render(request, 'hello.html', context)
|
||||||
|
|
||||||
|
template = loader.get_template('onenote/hello.html')
|
||||||
|
# template = loader.get_template('onenote/Roser.mht')
|
||||||
|
return HttpResponse(template.render())
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
<strong>Hello World</strong>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,13 +3,38 @@ from django.http import HttpResponse
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
|
|
||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
|
|
||||||
#from django.template.loader import render_to_string
|
#from django.template.loader import render_to_string
|
||||||
import time
|
import time
|
||||||
|
import psycopg2
|
||||||
import random
|
import random
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
|
||||||
|
def DB_generation(host_in,port_in,user_in,password_in,db_in):
|
||||||
|
#db = pymysql.connect(host=host_in, port=port_in, user=user_in, passwd=password_in,db=db_in)
|
||||||
|
db = psycopg2.connect(host=host_in, port=port_in, user=user_in, password=password_in,database=db_in)
|
||||||
|
return db
|
||||||
|
|
||||||
|
def Launch_sql_query(sql,db):
|
||||||
|
#sql query with 1 object returned
|
||||||
|
cursor = db.cursor()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Execute the SQL command
|
||||||
|
cursor.execute(sql)
|
||||||
|
# Fetch all the rows in a list of lists.
|
||||||
|
results = cursor.fetchall()
|
||||||
|
for row in results:
|
||||||
|
return row[0]
|
||||||
|
|
||||||
|
except:
|
||||||
|
print ("Error: unable to fetch data from the query:")
|
||||||
|
print (sql)
|
||||||
|
print("---")
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
|
||||||
def hello(request):
|
def hello(request):
|
||||||
return HttpResponse('<h1>Hello Simpsons!</h1>')
|
return HttpResponse('<h1>Hello Simpsons!</h1>')
|
||||||
#<h1>href="{{ STATIC_URL }}/files/somefile</h1>)
|
#<h1>href="{{ STATIC_URL }}/files/somefile</h1>)
|
||||||
@@ -25,8 +50,8 @@ def download_file(request):
|
|||||||
|
|
||||||
# response = HttpResponse(fl, content_type=mime_type)
|
# response = HttpResponse(fl, content_type=mime_type)
|
||||||
# response['Content-Disposition'] = "attachment; filename=%s" % filename
|
# response['Content-Disposition'] = "attachment; filename=%s" % filename
|
||||||
some_file = open('/data/kubernetes/Backup/nextcloud/notes/2024-07-28/Course.md', "r")
|
some_file = open('/data/kubernetes/Backup/nextcloud/notes/2024-07-28/Course.md', "r")
|
||||||
django_file = File(some_file)
|
django_file = File(some_file)
|
||||||
return HttpResponse("<h1>Hello download!</h1><h1><a href='{{ MEDIA_URL }}{{ django_file.relative_path }}'>{{ django_file.name }}</a></h1><h1>bye download!</h1>")
|
return HttpResponse("<h1>Hello download!</h1><h1><a href='{{ MEDIA_URL }}{{ django_file.relative_path }}'>{{ django_file.name }}</a></h1><h1>bye download!</h1>")
|
||||||
# return response
|
# return response
|
||||||
|
|
||||||
@@ -42,27 +67,46 @@ def download_mo(request,file):
|
|||||||
#return HttpResponse('<h1>Hello !</h1>')
|
#return HttpResponse('<h1>Hello !</h1>')
|
||||||
|
|
||||||
def simpsons(request):
|
def simpsons(request):
|
||||||
# simpsons_url = "https://www1.kisscartoon.online/episode/the-simpsons-season-";
|
#dev settings
|
||||||
simpsons_url = "https://kisscartoon.top/episode/the-simpsons-season-";
|
#generated_db = DB_generation("192.168.88.50",32345, "django_username", "Suffrage-Moneybags-Illusion7","django")
|
||||||
number_of_seasons = 35
|
#production settings
|
||||||
seasons_maximum_number = [13,22,24,22,22,25,25,25,25,23,22,21,22,22,22,21,22,22,20,21,23,22,22,22,22,22,22,22,21,23,22,22,22,22,18]
|
generated_db = DB_generation("django-db-svc",5432, "django_username", "Suffrage-Moneybags-Illusion7","django")
|
||||||
|
|
||||||
#print(simpsons_url)
|
cursor = generated_db.cursor()
|
||||||
|
|
||||||
random_seasons = random.randint(1, number_of_seasons)
|
#get max number of season
|
||||||
print("random seasons: "+ str(random_seasons))
|
maximum_number_of_seasons = Launch_sql_query("SELECT COUNT(DISTINCT season) as result FROM episodes;",generated_db)
|
||||||
|
|
||||||
#random_seasons-1 because list start at index 0
|
boolean_restart = True;
|
||||||
print("maximum of episode for this season: "+str(seasons_maximum_number[random_seasons-1]))
|
while (boolean_restart):
|
||||||
|
|
||||||
random_episode = random.randint(1, seasons_maximum_number[random_seasons-1])
|
random_seasons = random.randint(1, maximum_number_of_seasons)
|
||||||
|
print("random season: " + str(random_seasons))
|
||||||
print("random episode: "+ str(random_episode))
|
|
||||||
|
|
||||||
|
|
||||||
final_url = simpsons_url+str(random_seasons)+ "-episode-"+str(random_episode)#
|
#get max number of epiosde for this season
|
||||||
print(final_url)
|
maximum_number_of_episodes_query = "SELECT COUNT(url) as result FROM episodes WHERE season = " + str(random_seasons) + ";"
|
||||||
|
|
||||||
# return HttpResponse(str(final_url))
|
maximum_number_of_episodes = Launch_sql_query(maximum_number_of_episodes_query,generated_db)
|
||||||
# time.sleep(10)
|
|
||||||
return redirect(str(final_url))
|
random_episode = random.randint(1, maximum_number_of_episodes)
|
||||||
|
print("random episode: " + str(random_episode))
|
||||||
|
|
||||||
|
#check if the episode was already seen
|
||||||
|
check_if_already_seen_query = "select seen from episodes where season="+ str(random_seasons) +" and episode = "+ str(random_episode) +";"
|
||||||
|
if not Launch_sql_query(check_if_already_seen_query, generated_db):
|
||||||
|
boolean_restart = False
|
||||||
|
else:
|
||||||
|
print("episode "+str(random_episode)+" from season "+str(random_seasons)+" already seen")
|
||||||
|
|
||||||
|
url_from_episode_season_query = "select url from episodes where season="+ str(random_seasons) +" and episode = "+ str(random_episode) +";"
|
||||||
|
generated_url = Launch_sql_query(url_from_episode_season_query,generated_db)
|
||||||
|
|
||||||
|
#mark as seen
|
||||||
|
url_from_episode_season_query = "update episodes set seen = True where season=" + str(random_seasons) + " and episode = " + str(random_episode) + ";"
|
||||||
|
Launch_sql_query(url_from_episode_season_query, generated_db)
|
||||||
|
|
||||||
|
generated_db.commit()
|
||||||
|
generated_db.close()
|
||||||
|
#return HttpResponse(str(generated_url))
|
||||||
|
return redirect(str(generated_url))
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
#from jinja2 import Environment, FileSystemLoader
|
||||||
|
from django.core.files import File
|
||||||
|
from kubernetes import client, config
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
|
from lxml import html
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import mimetypes
|
||||||
|
import ruamel.yaml
|
||||||
|
import yaml
|
||||||
|
from urllib import request as urlrequest
|
||||||
|
from urllib import parse as urlparse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
proxy_url = 'http://gluetun-svc.gluetun.svc:8888'
|
||||||
|
proxy = urlrequest.ProxyHandler({
|
||||||
|
'http': proxy_url,
|
||||||
|
'https': proxy_url # Add the handler for HTTPS
|
||||||
|
})
|
||||||
|
|
||||||
|
proxies = {
|
||||||
|
"http" : proxy_url,
|
||||||
|
"https" : proxy_url
|
||||||
|
}
|
||||||
|
|
||||||
|
destination_folder = "/tmp/stash/"
|
||||||
|
|
||||||
|
def hello(request):
|
||||||
|
return HttpResponse('<h1>Hello stash!</h1>')
|
||||||
|
def form(request):
|
||||||
|
return render(request, 'stash_form.html',{})
|
||||||
|
def album(request):
|
||||||
|
return render(request, 'album_form.html',{})
|
||||||
|
|
||||||
|
def check_and_create_destination_folder(name):
|
||||||
|
#check if the output directory exist and create if not
|
||||||
|
if not os.path.isdir(destination_folder):
|
||||||
|
os.makedirs(destination_folder)
|
||||||
|
|
||||||
|
#check if the named directory exist and create if not
|
||||||
|
destination_named_folder = os.path.join(destination_folder,name)
|
||||||
|
if not os.path.isdir(destination_named_folder):
|
||||||
|
os.makedirs(destination_named_folder)
|
||||||
|
|
||||||
|
return destination_named_folder
|
||||||
|
|
||||||
|
def album_form(request):
|
||||||
|
name = request.GET.get('name')
|
||||||
|
url = request.GET.get('url')
|
||||||
|
external_galleries = request.GET.get('external_galleries')
|
||||||
|
|
||||||
|
album_downloader.delay(name=name,url=url,external_galleries=external_galleries)
|
||||||
|
|
||||||
|
text_generated = "successfully sent to the album downloader"
|
||||||
|
return HttpResponse(text_generated, content_type="text/plain")
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def album_downloader(name,url,external_galleries):
|
||||||
|
print(name+" "+url+" "+external_galleries)
|
||||||
|
|
||||||
|
opener = urlrequest.build_opener(proxy)
|
||||||
|
urlrequest.install_opener(opener)
|
||||||
|
|
||||||
|
req = urlrequest.Request(url)
|
||||||
|
urlcurl = urlrequest.urlopen(req).read()
|
||||||
|
|
||||||
|
page = requests.get(url,proxies=proxies)
|
||||||
|
webpage = html.fromstring(page.content)
|
||||||
|
|
||||||
|
#create the prerequisites folder
|
||||||
|
destination_named_folder = check_and_create_destination_folder(name=name)
|
||||||
|
|
||||||
|
|
||||||
|
#get all URLs from the code source (searching for href tag on the code)
|
||||||
|
#https://stackoverflow.com/questions/21455349/xpath-query-get-attribute-href-from-a-tag
|
||||||
|
|
||||||
|
webpage_all_url = webpage.xpath('//a/@href')
|
||||||
|
|
||||||
|
#search for the href that contains the galleries
|
||||||
|
webpage_all_album_url = webpage.xpath("//a[contains(@href,'pornpics.com/galleries/')]/@href")
|
||||||
|
#print(webpage_all_album_url[3])
|
||||||
|
#print(webpage_all_album_url)
|
||||||
|
|
||||||
|
|
||||||
|
for album in webpage_all_album_url:
|
||||||
|
print("Album "+album)
|
||||||
|
print("")
|
||||||
|
page = requests.get(album,proxies=proxies)
|
||||||
|
webpage = html.fromstring(page.content)
|
||||||
|
|
||||||
|
images_list = webpage.xpath("//a[contains(@href,'cdni.pornpics.com/1280/')]/@href")
|
||||||
|
images_downloader.delay(name=name,images_url_list=images_list,destination_named_folder=destination_named_folder)
|
||||||
|
print(images_list)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def images_downloader(name,images_url_list,destination_named_folder):
|
||||||
|
for image_url in images_url_list:
|
||||||
|
split = urlparse.urlsplit(image_url)
|
||||||
|
#filename = destination_folder + split.path.split("/")[-1]
|
||||||
|
filename = os.path.join(destination_named_folder,split.path.split("/")[-1])
|
||||||
|
|
||||||
|
|
||||||
|
print("downloading: "+filename+" -- "+image_url)
|
||||||
|
|
||||||
|
opener = urlrequest.build_opener(proxy)
|
||||||
|
|
||||||
|
urlrequest.install_opener(opener)
|
||||||
|
urlrequest.urlretrieve(image_url, filename )
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def incremental(request):
|
||||||
|
return render(request, 'incremental_form.html',{})
|
||||||
|
|
||||||
|
def incremental_form(request):
|
||||||
|
name = request.GET.get('name')
|
||||||
|
url = request.GET.get('url')
|
||||||
|
url_suffix = request.GET.get('url_suffix')
|
||||||
|
maximum_increment = int(request.GET.get('maximum_increment'))
|
||||||
|
minimum_increment = request.GET.get('minimum_increment')
|
||||||
|
|
||||||
|
increment_and_download.delay(minimum_increment=minimum_increment,maximum_increment=maximum_increment,url=url,url_suffix=url_suffix,name=name)
|
||||||
|
|
||||||
|
text_generated = "successfully sent to celery"
|
||||||
|
return HttpResponse(text_generated, content_type="text/plain")
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def increment_and_download(minimum_increment,maximum_increment,url,url_suffix,name):
|
||||||
|
if minimum_increment == None:
|
||||||
|
minimum_increment = 1
|
||||||
|
|
||||||
|
text_generated = ""
|
||||||
|
minimum_increment = int(minimum_increment)
|
||||||
|
maximum_increment = int(maximum_increment)
|
||||||
|
|
||||||
|
#check if the output directory exist and create if not
|
||||||
|
if not os.path.isdir(destination_folder):
|
||||||
|
os.makedirs(destination_folder)
|
||||||
|
|
||||||
|
#check if the named directory exist and create if not
|
||||||
|
destination_named_folder = os.path.join(destination_folder,name)
|
||||||
|
if not os.path.isdir(destination_named_folder):
|
||||||
|
os.makedirs(destination_named_folder)
|
||||||
|
|
||||||
|
print("\n downloading for "+name+" "+url+"XXX"+url_suffix)
|
||||||
|
|
||||||
|
for increment in range(minimum_increment,maximum_increment):
|
||||||
|
print("increment : "+str(increment)+"/"+str(maximum_increment))
|
||||||
|
if len(str(increment)) == 3:
|
||||||
|
increment_generated ='0' + str(increment)
|
||||||
|
elif len(str(increment)) == 2:
|
||||||
|
increment_generated ='00' + str(increment)
|
||||||
|
elif len(str(increment)) == 1:
|
||||||
|
increment_generated ='000' + str(increment)
|
||||||
|
|
||||||
|
url_generated = url+increment_generated+url_suffix
|
||||||
|
destination_filename = increment_generated+url_suffix
|
||||||
|
destination_file = os.path.join(destination_named_folder,destination_filename)
|
||||||
|
|
||||||
|
opener = urlrequest.build_opener(proxy)
|
||||||
|
urlrequest.install_opener(opener)
|
||||||
|
urlrequest.urlretrieve(url_generated, destination_file )
|
||||||
|
|
||||||
|
text_generated = "\n downloading for "+name+" "+url+increment_generated+url_suffix
|
||||||
|
print("download completed for "+name+" of "+str(maximum_increment)+" images")
|
||||||
|
return text_generated
|
||||||
|
def handle_survey_form(request):
|
||||||
|
config.load_kube_config(config_file='/kubeconfig/config')
|
||||||
|
v1 = client.BatchV1Api()
|
||||||
|
name = request.GET.get('name')
|
||||||
|
url = request.GET.get('url')
|
||||||
|
external_galleries = str(request.GET.get('external_galleries'))
|
||||||
|
|
||||||
|
stash_folder = "/stash"
|
||||||
|
|
||||||
|
if external_galleries:
|
||||||
|
print("external_galleries is not null")
|
||||||
|
performer_external_galleries = stash_folder+"/"+name+"_external_galleries.txt"
|
||||||
|
with open(performer_external_galleries, "a") as f:
|
||||||
|
f.write(external_galleries)
|
||||||
|
skip_searching_gallery = True
|
||||||
|
else:
|
||||||
|
print("external_galleries is null")
|
||||||
|
skip_searching_gallery = False
|
||||||
|
|
||||||
|
with open('django_code/stash_management/templates/template.stash-pornpics-dowloader.job.yml', 'r') as file:
|
||||||
|
#get the manifest in a variable template_manifest from the manifest file
|
||||||
|
template_manifest = yaml.safe_load(file)
|
||||||
|
|
||||||
|
#edit the container name
|
||||||
|
template_manifest['metadata']['name'] ="stash-pornpics-dowloader-"+name
|
||||||
|
template_manifest['spec']['template']['spec']['containers'][0]['name'] ="stash-pornpics-dowloader-"+name
|
||||||
|
|
||||||
|
#edit the command based on the input
|
||||||
|
command=['bash', '/config/download.sh', '--http_proxy', 'http://gluetun-svc.gluetun.svc:8888', '--BASE_URL', url, '--pornstars', name]
|
||||||
|
template_manifest['spec']['template']['spec']['containers'][0]['command']=command
|
||||||
|
|
||||||
|
|
||||||
|
#execute based on the value
|
||||||
|
api_response = v1.create_namespaced_job(body=template_manifest,namespace='stash')
|
||||||
|
return HttpResponse(api_response)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>Stash form</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@charset "UTF-8";
|
||||||
|
.m-b-xs {
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-b-md {
|
||||||
|
margin-bottom: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-xs {
|
||||||
|
margin-top: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-sm {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 2% 0;
|
||||||
|
background-color: #37404a;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#survey-form label,
|
||||||
|
#survey-form .labels {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
#survey-form input::-webkit-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input::-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-ms-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input,
|
||||||
|
#survey-form select {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid #333;
|
||||||
|
}
|
||||||
|
#survey-form input {
|
||||||
|
margin-top: 1.5%;
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 2px solid #fff;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form input:focus {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
margin: 0px 10px 0 0;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px 0 0 !important;
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-o-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
height: 23px;
|
||||||
|
width: 23px;
|
||||||
|
transition: all 0.15s ease-out 0s;
|
||||||
|
background: #37404a;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
z-index: 1000;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:hover,
|
||||||
|
#survey-form [type=radio]:hover {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:checked:before,
|
||||||
|
#survey-form [type=radio]:checked:before {
|
||||||
|
display: inline-block;
|
||||||
|
height: 21px;
|
||||||
|
width: 21px;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
content: "";
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Glyphicons Halflings";
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:focus,
|
||||||
|
#survey-form [type=radio]:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio]:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=number] {
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
#survey-form [type=number]::-webkit-inner-spin-button, #survey-form [type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#survey-form select {
|
||||||
|
height: 40px;
|
||||||
|
padding-left: 5px;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form select option {
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#survey-form select option:hover {
|
||||||
|
background-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form textarea {
|
||||||
|
resize: none;
|
||||||
|
margin-top: 2%;
|
||||||
|
padding: 10px 10px 0px 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
color: #85ffc7;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form .btn {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin: 3% 0 0 0;
|
||||||
|
height: 45px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 3px solid #85ffc7;
|
||||||
|
border-radius: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-align: center;
|
||||||
|
background: none;
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
#survey-form .btn:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #85ffc7;
|
||||||
|
transform-origin: left;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover {
|
||||||
|
color: #37404a;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover:after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#survey-form fieldset {
|
||||||
|
margin: 5% 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.copyright i {
|
||||||
|
color: #ef5350;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 8% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<main id="main" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-lg-offset-3 col-lg-6">
|
||||||
|
<div class="m-b-md text-center">
|
||||||
|
<h1 id="title">Stash Form</h1>
|
||||||
|
<p id="description" class="description" class="text-center">Download form</p>
|
||||||
|
</div>
|
||||||
|
<form method="GET" action="/stash/album-form/" id="survey-form" name="survey-form">
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="name" id="name-label">
|
||||||
|
Name *
|
||||||
|
<input class="" type="text" id="name" name="name" placeholder="Enter your name (required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="url" id="url-label">
|
||||||
|
URL *
|
||||||
|
<input class="" type="url" id="url" name="url" placeholder="Enter the URL (required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="external_galleries">
|
||||||
|
Any external galleries ?
|
||||||
|
<textarea id="external_galleries" name="external_galleries" ></textarea>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button id="submit" type="submit" class="btn">Submit the form</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>Stash form</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@charset "UTF-8";
|
||||||
|
.m-b-xs {
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-b-md {
|
||||||
|
margin-bottom: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-xs {
|
||||||
|
margin-top: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-sm {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 2% 0;
|
||||||
|
background-color: #37404a;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#survey-form label,
|
||||||
|
#survey-form .labels {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
#survey-form input::-webkit-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input::-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-ms-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input,
|
||||||
|
#survey-form select {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid #333;
|
||||||
|
}
|
||||||
|
#survey-form input {
|
||||||
|
margin-top: 1.5%;
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 2px solid #fff;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form input:focus {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
margin: 0px 10px 0 0;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px 0 0 !important;
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-o-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
height: 23px;
|
||||||
|
width: 23px;
|
||||||
|
transition: all 0.15s ease-out 0s;
|
||||||
|
background: #37404a;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
z-index: 1000;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:hover,
|
||||||
|
#survey-form [type=radio]:hover {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:checked:before,
|
||||||
|
#survey-form [type=radio]:checked:before {
|
||||||
|
display: inline-block;
|
||||||
|
height: 21px;
|
||||||
|
width: 21px;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
content: "";
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Glyphicons Halflings";
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:focus,
|
||||||
|
#survey-form [type=radio]:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio]:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=number] {
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
#survey-form [type=number]::-webkit-inner-spin-button, #survey-form [type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#survey-form select {
|
||||||
|
height: 40px;
|
||||||
|
padding-left: 5px;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form select option {
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#survey-form select option:hover {
|
||||||
|
background-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form textarea {
|
||||||
|
resize: none;
|
||||||
|
margin-top: 2%;
|
||||||
|
padding: 10px 10px 0px 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
color: #85ffc7;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form .btn {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin: 3% 0 0 0;
|
||||||
|
height: 45px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 3px solid #85ffc7;
|
||||||
|
border-radius: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-align: center;
|
||||||
|
background: none;
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
#survey-form .btn:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #85ffc7;
|
||||||
|
transform-origin: left;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover {
|
||||||
|
color: #37404a;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover:after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#survey-form fieldset {
|
||||||
|
margin: 5% 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.copyright i {
|
||||||
|
color: #ef5350;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 8% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<main id="main" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-lg-offset-3 col-lg-6">
|
||||||
|
<div class="m-b-md text-center">
|
||||||
|
<h1 id="title">Incremental Form</h1>
|
||||||
|
<p id="description" class="description" class="text-center">Download form</p>
|
||||||
|
</div>
|
||||||
|
<form method="GET" action="/stash/incremental-form/" id="survey-form" name="survey-form">
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="name" id="name-label">
|
||||||
|
Name *
|
||||||
|
<input class="" type="text" id="name" name="name" placeholder="Enter your name (required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="url" id="url-label">
|
||||||
|
URL of one image before the increment *
|
||||||
|
<input class="" type="url" id="url" name="url" placeholder="Enter the URL before the increment(required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="url_suffix" id="url_suffix-label">
|
||||||
|
suffix URL of one image after the increment *
|
||||||
|
<input class="" type="string" id="url_suffix" name="url_suffix" placeholder="Enter the URL suffix (Example .png)(required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="maximum_increment" id="maximum_increment_label">
|
||||||
|
Maximum increment value *
|
||||||
|
<input class="" type="text" id="maximum_increment" name="maximum_increment" placeholder="Enter the maximum increment(required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="Minimum_increment" id="Minimum_increment_label">
|
||||||
|
Minimum increment value
|
||||||
|
<input class="" type="text" id="Minimum_increment" name="Minimum_increment" placeholder="Enter the minimum increment (default 1)" />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button id="submit" type="submit" class="btn">Submit the form</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</html>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
<h1>Hello template!</h1>
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>Stash form</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@charset "UTF-8";
|
||||||
|
.m-b-xs {
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-b-md {
|
||||||
|
margin-bottom: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-xs {
|
||||||
|
margin-top: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-sm {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
outline: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 2% 0;
|
||||||
|
background-color: #37404a;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#survey-form label,
|
||||||
|
#survey-form .labels {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
#survey-form input::-webkit-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input::-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-ms-input-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input:-moz-placeholder {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
#survey-form input,
|
||||||
|
#survey-form select {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid #333;
|
||||||
|
}
|
||||||
|
#survey-form input {
|
||||||
|
margin-top: 1.5%;
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 2px solid #fff;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form input:focus {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
margin: 0px 10px 0 0;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox],
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px 0 0 !important;
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-o-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
height: 23px;
|
||||||
|
width: 23px;
|
||||||
|
transition: all 0.15s ease-out 0s;
|
||||||
|
background: #37404a;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
z-index: 1000;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:hover,
|
||||||
|
#survey-form [type=radio]:hover {
|
||||||
|
border-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:checked:before,
|
||||||
|
#survey-form [type=radio]:checked:before {
|
||||||
|
display: inline-block;
|
||||||
|
height: 21px;
|
||||||
|
width: 21px;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
content: "";
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Glyphicons Halflings";
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form [type=checkbox]:focus,
|
||||||
|
#survey-form [type=radio]:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio] {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=radio]:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#survey-form [type=number] {
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
#survey-form [type=number]::-webkit-inner-spin-button, #survey-form [type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#survey-form select {
|
||||||
|
height: 40px;
|
||||||
|
padding-left: 5px;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form select option {
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#survey-form select option:hover {
|
||||||
|
background-color: #85ffc7;
|
||||||
|
}
|
||||||
|
#survey-form textarea {
|
||||||
|
resize: none;
|
||||||
|
margin-top: 2%;
|
||||||
|
padding: 10px 10px 0px 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
color: #85ffc7;
|
||||||
|
background-color: #37404a;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
}
|
||||||
|
#survey-form .btn {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin: 3% 0 0 0;
|
||||||
|
height: 45px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 3px solid #85ffc7;
|
||||||
|
border-radius: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #85ffc7;
|
||||||
|
text-align: center;
|
||||||
|
background: none;
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
#survey-form .btn:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #85ffc7;
|
||||||
|
transform-origin: left;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover {
|
||||||
|
color: #37404a;
|
||||||
|
}
|
||||||
|
#survey-form .btn:hover:after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#survey-form fieldset {
|
||||||
|
margin: 5% 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.copyright i {
|
||||||
|
color: #ef5350;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 8% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<main id="main" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-lg-offset-3 col-lg-6">
|
||||||
|
<div class="m-b-md text-center">
|
||||||
|
<h1 id="title">Stash Form</h1>
|
||||||
|
<p id="description" class="description" class="text-center">Download form</p>
|
||||||
|
</div>
|
||||||
|
<form method="GET" action="/stash/submit-form/" id="survey-form" name="survey-form">
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="name" id="name-label">
|
||||||
|
Name *
|
||||||
|
<input class="" type="text" id="name" name="name" placeholder="Enter your name (required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="url" id="url-label">
|
||||||
|
URL *
|
||||||
|
<input class="" type="url" id="url" name="url" placeholder="Enter the URL (required)" required />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label for="external_galleries">
|
||||||
|
Any external galleries ?
|
||||||
|
<textarea id="external_galleries" name="external_galleries" ></textarea>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button id="submit" type="submit" class="btn">Submit the form</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: stash-pornpics-dowloader-{{ name }}
|
||||||
|
namespace: stash
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: stash-pornpics-dowloader-{{ name }}
|
||||||
|
image: bash
|
||||||
|
imagePullPolicy: Always
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /config
|
||||||
|
name: scripts
|
||||||
|
- mountPath: /data
|
||||||
|
mountPropagation: None
|
||||||
|
name: data-pvc
|
||||||
|
command:
|
||||||
|
- bash
|
||||||
|
- /config/download.sh
|
||||||
|
- --http_proxy
|
||||||
|
- "http://gluetun-svc.gluetun.svc:8888"
|
||||||
|
- --BASE_URL
|
||||||
|
- "{{ url }}"
|
||||||
|
- --pornstars
|
||||||
|
- "{{ name }}"
|
||||||
|
restartPolicy: Never
|
||||||
|
volumes:
|
||||||
|
- configMap:
|
||||||
|
defaultMode: 0744
|
||||||
|
name: pornpic-dowloader
|
||||||
|
name: scripts
|
||||||
|
- name: data-pvc
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: data-pvc
|
||||||
|
backoffLimit: 4
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
def hello(request):
|
||||||
|
return HttpResponse('<h1>Hello stash!</h1>')
|
||||||
|
|
||||||
|
|
||||||
|
def home(request):
|
||||||
|
return render(request, 'listing.html')
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
<strong>Hello World template</strong>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: django:local
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
target: /code
|
||||||
|
source: ./django_code
|
||||||
|
command: python manage.py runserver 0.0.0.0:7000
|
||||||
|
ports:
|
||||||
|
- 7000:7000
|
||||||
+7
-6
@@ -1,11 +1,12 @@
|
|||||||
FROM python:3
|
FROM gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:latest
|
||||||
|
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
WORKDIR /code/
|
WORKDIR /code/
|
||||||
|
|
||||||
COPY requirements.txt ./
|
# Copy the rest of your application code (Changes frequently, invalidates subsequent cache)
|
||||||
COPY django_code ./
|
COPY . ./
|
||||||
|
RUN python django_code/manage.py migrate
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
|
# CMD is the command run when the container starts
|
||||||
CMD [ "python","django_code/manage.py","runserver","0.0.0.0:8000" ]
|
CMD [ "python","django_code/manage.py","runserver","0.0.0.0:8000" ]
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#install required packages
|
||||||
|
apk add curl wget
|
||||||
|
|
||||||
|
#named argument generation
|
||||||
|
skip_searching_gallery="${skip_searching_gallery:-false}"
|
||||||
|
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
if [[ $1 == "--"* ]]; then
|
||||||
|
v="${1/--/}"
|
||||||
|
declare "$v"="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
#check if we will use a HTTP proxy or not
|
||||||
|
|
||||||
|
if [[ -z $http_proxy ]]; then
|
||||||
|
echo "not using proxy"
|
||||||
|
curl_command="curl"
|
||||||
|
else
|
||||||
|
echo "using proxy"
|
||||||
|
curl_command="curl -x $http_proxy"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#dowload from https://www.pornpics.com/pornstars/eiby-shine/
|
||||||
|
DESTINATION_FOLDER="/data"
|
||||||
|
PROXY_HTTP="http://gluetun-svc.gluetun.svc:8888"
|
||||||
|
|
||||||
|
#BASE_URL="https://www.pornpics.com/pornstars/eiby-shine/"
|
||||||
|
#pornstars="eiby-shine"
|
||||||
|
|
||||||
|
#BASE_URL="https://www.pornpics.com/?q=shy+imp"
|
||||||
|
#pornstars="shy-imp"
|
||||||
|
|
||||||
|
#BASE_URL="https://www.pornpics.com/pornstars/gloria-sol/"
|
||||||
|
#pornstars="gloria-sol"
|
||||||
|
|
||||||
|
|
||||||
|
#BASE_URL="https://www.pornpics.com/pornstars/becky-summer"
|
||||||
|
#pornstars="becky-summer"
|
||||||
|
|
||||||
|
|
||||||
|
#clear files beforehand
|
||||||
|
|
||||||
|
echo "Pornstar: "$pornstars
|
||||||
|
echo "URL: "$BASE_URL
|
||||||
|
|
||||||
|
mkdir -p $DESTINATION_FOLDER/$pornstars
|
||||||
|
|
||||||
|
if [[ $skip_searching_gallery == true ]]; then
|
||||||
|
echo "not looping through galleries"
|
||||||
|
echo "using existing file instead"
|
||||||
|
#because we need to keep the file $DESTINATION_FOLDER/$pornstars-urls_of_galleries.txt with the existing URL , in this condition,
|
||||||
|
#no deletion of this file
|
||||||
|
echo $external_gallery > $DESTINATION_FOLDER/$pornstars-urls_of_galleries.txt
|
||||||
|
else
|
||||||
|
echo "looping through galleries"
|
||||||
|
#because we will re-generate this file, can be emptied
|
||||||
|
echo "" > $DESTINATION_FOLDER/$pornstars-urls_of_galleries.txt
|
||||||
|
$curl_command -s $BASE_URL | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*" | grep "https://www.pornpics.com/galleries/" |sort -u >> $DESTINATION_FOLDER/$pornstars-urls_of_galleries.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" > $DESTINATION_FOLDER/$pornstars-image_to_download.txt
|
||||||
|
|
||||||
|
|
||||||
|
for f in $(cat $DESTINATION_FOLDER/$pornstars-urls_of_galleries.txt ); do
|
||||||
|
$curl_command $f | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*" | grep "https://cdni.pornpics.com/1280" >> $DESTINATION_FOLDER/$pornstars-image_to_download.txt
|
||||||
|
echo $f
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
for g in $(cat $DESTINATION_FOLDER/$pornstars-image_to_download.txt ); do
|
||||||
|
$curl_command -O --output-dir $DESTINATION_FOLDER/$pornstars $g
|
||||||
|
# wget -e use_proxy=yes -e http_proxy=$PROXY_HTTP $g -P $DESTINATION_FOLDER/$pornstars
|
||||||
|
echo $g
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,15 @@
|
|||||||
django
|
django
|
||||||
|
psycopg2
|
||||||
requests
|
requests
|
||||||
proxmoxer
|
proxmoxer
|
||||||
docker
|
docker
|
||||||
kubernetes
|
kubernetes
|
||||||
ruamel.yaml
|
ruamel.yaml
|
||||||
pyyaml
|
pyyaml
|
||||||
|
django-bootstrap-v5
|
||||||
|
jinja2
|
||||||
|
watchdog
|
||||||
|
celery
|
||||||
|
redis
|
||||||
|
lxml
|
||||||
|
requests
|
||||||
|
|||||||
Reference in New Issue
Block a user