xenua
2 years ago
commit
8eb9aef608
24 changed files with 834 additions and 0 deletions
@ -0,0 +1,384 @@ |
|||||||
|
# Custom |
||||||
|
.idea/ |
||||||
|
|
||||||
|
# Config folder |
||||||
|
.secrets/ |
||||||
|
|
||||||
|
### Django ### |
||||||
|
*.log |
||||||
|
*.pot |
||||||
|
*.pyc |
||||||
|
__pycache__/ |
||||||
|
local_settings.py |
||||||
|
db.sqlite3 |
||||||
|
media |
||||||
|
|
||||||
|
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ |
||||||
|
# in your Git repository. Update and uncomment the following line accordingly. |
||||||
|
# <django-project-name>/staticfiles/ |
||||||
|
|
||||||
|
### Linux ### |
||||||
|
*~ |
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file |
||||||
|
.fuse_hidden* |
||||||
|
|
||||||
|
# KDE directory preferences |
||||||
|
.directory |
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk |
||||||
|
.Trash-* |
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed |
||||||
|
.nfs* |
||||||
|
|
||||||
|
### macOS ### |
||||||
|
*.DS_Store |
||||||
|
.AppleDouble |
||||||
|
.LSOverride |
||||||
|
|
||||||
|
# Icon must end with two \r |
||||||
|
Icon |
||||||
|
|
||||||
|
# Thumbnails |
||||||
|
._* |
||||||
|
|
||||||
|
# Files that might appear in the root of a volume |
||||||
|
.DocumentRevisions-V100 |
||||||
|
.fseventsd |
||||||
|
.Spotlight-V100 |
||||||
|
.TemporaryItems |
||||||
|
.Trashes |
||||||
|
.VolumeIcon.icns |
||||||
|
.com.apple.timemachine.donotpresent |
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share |
||||||
|
.AppleDB |
||||||
|
.AppleDesktop |
||||||
|
Network Trash Folder |
||||||
|
Temporary Items |
||||||
|
.apdisk |
||||||
|
|
||||||
|
### PyCharm ### |
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm |
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 |
||||||
|
|
||||||
|
# User-specific stuff: |
||||||
|
.idea/**/workspace.xml |
||||||
|
.idea/**/tasks.xml |
||||||
|
.idea/dictionaries |
||||||
|
|
||||||
|
# Sensitive or high-churn files: |
||||||
|
.idea/**/dataSources/ |
||||||
|
.idea/**/dataSources.ids |
||||||
|
.idea/**/dataSources.xml |
||||||
|
.idea/**/dataSources.local.xml |
||||||
|
.idea/**/sqlDataSources.xml |
||||||
|
.idea/**/dynamic.xml |
||||||
|
.idea/**/uiDesigner.xml |
||||||
|
|
||||||
|
# Gradle: |
||||||
|
.idea/**/gradle.xml |
||||||
|
.idea/**/libraries |
||||||
|
|
||||||
|
# CMake |
||||||
|
cmake-build-debug/ |
||||||
|
|
||||||
|
# Mongo Explorer plugin: |
||||||
|
.idea/**/mongoSettings.xml |
||||||
|
|
||||||
|
## File-based project format: |
||||||
|
*.iws |
||||||
|
|
||||||
|
## Plugin-specific files: |
||||||
|
|
||||||
|
# IntelliJ |
||||||
|
/out/ |
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin |
||||||
|
.idea_modules/ |
||||||
|
|
||||||
|
# JIRA plugin |
||||||
|
atlassian-ide-plugin.xml |
||||||
|
|
||||||
|
# Cursive Clojure plugin |
||||||
|
.idea/replstate.xml |
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ) |
||||||
|
com_crashlytics_export_strings.xml |
||||||
|
crashlytics.properties |
||||||
|
crashlytics-build.properties |
||||||
|
fabric.properties |
||||||
|
|
||||||
|
### PyCharm Patch ### |
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 |
||||||
|
|
||||||
|
# *.iml |
||||||
|
# modules.xml |
||||||
|
# .idea/misc.xml |
||||||
|
# *.ipr |
||||||
|
|
||||||
|
# Sonarlint plugin |
||||||
|
.idea/sonarlint |
||||||
|
|
||||||
|
### Python ### |
||||||
|
# Byte-compiled / optimized / DLL files |
||||||
|
*.py[cod] |
||||||
|
*$py.class |
||||||
|
|
||||||
|
# C extensions |
||||||
|
*.so |
||||||
|
|
||||||
|
# Distribution / packaging |
||||||
|
.Python |
||||||
|
build/ |
||||||
|
develop-eggs/ |
||||||
|
dist/ |
||||||
|
downloads/ |
||||||
|
eggs/ |
||||||
|
.eggs/ |
||||||
|
lib/ |
||||||
|
lib64/ |
||||||
|
parts/ |
||||||
|
sdist/ |
||||||
|
var/ |
||||||
|
wheels/ |
||||||
|
*.egg-info/ |
||||||
|
.installed.cfg |
||||||
|
*.egg |
||||||
|
|
||||||
|
# PyInstaller |
||||||
|
# Usually these files are written by a python script from a template |
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||||
|
*.manifest |
||||||
|
*.spec |
||||||
|
|
||||||
|
# Installer logs |
||||||
|
pip-log.txt |
||||||
|
pip-delete-this-directory.txt |
||||||
|
|
||||||
|
# Unit test / coverage reports |
||||||
|
htmlcov/ |
||||||
|
.tox/ |
||||||
|
.coverage |
||||||
|
.coverage.* |
||||||
|
.cache |
||||||
|
nosetests.xml |
||||||
|
coverage.xml |
||||||
|
*.cover |
||||||
|
.hypothesis/ |
||||||
|
|
||||||
|
# Translations |
||||||
|
*.mo |
||||||
|
|
||||||
|
# Django stuff: |
||||||
|
|
||||||
|
# Flask stuff: |
||||||
|
instance/ |
||||||
|
.webassets-cache |
||||||
|
|
||||||
|
# Scrapy stuff: |
||||||
|
.scrapy |
||||||
|
|
||||||
|
# Sphinx documentation |
||||||
|
docs/_build/ |
||||||
|
|
||||||
|
# PyBuilder |
||||||
|
target/ |
||||||
|
|
||||||
|
# Jupyter Notebook |
||||||
|
.ipynb_checkpoints |
||||||
|
|
||||||
|
# pyenv |
||||||
|
.python-version |
||||||
|
|
||||||
|
# celery beat schedule file |
||||||
|
celerybeat-schedule |
||||||
|
|
||||||
|
# SageMath parsed files |
||||||
|
*.sage.py |
||||||
|
|
||||||
|
# Environments |
||||||
|
.env |
||||||
|
.venv |
||||||
|
env/ |
||||||
|
venv/ |
||||||
|
ENV/ |
||||||
|
env.bak/ |
||||||
|
venv.bak/ |
||||||
|
|
||||||
|
# Spyder project settings |
||||||
|
.spyderproject |
||||||
|
.spyproject |
||||||
|
|
||||||
|
# Rope project settings |
||||||
|
.ropeproject |
||||||
|
|
||||||
|
# mkdocs documentation |
||||||
|
/site |
||||||
|
|
||||||
|
# mypy |
||||||
|
.mypy_cache/ |
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/linux,macos,python,django,pycharm |
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files |
||||||
|
__pycache__/ |
||||||
|
*.py[cod] |
||||||
|
*$py.class |
||||||
|
|
||||||
|
# C extensions |
||||||
|
*.so |
||||||
|
|
||||||
|
# Distribution / packaging |
||||||
|
.Python |
||||||
|
build/ |
||||||
|
develop-eggs/ |
||||||
|
dist/ |
||||||
|
downloads/ |
||||||
|
eggs/ |
||||||
|
.eggs/ |
||||||
|
lib/ |
||||||
|
lib64/ |
||||||
|
parts/ |
||||||
|
sdist/ |
||||||
|
var/ |
||||||
|
wheels/ |
||||||
|
share/python-wheels/ |
||||||
|
*.egg-info/ |
||||||
|
.installed.cfg |
||||||
|
*.egg |
||||||
|
MANIFEST |
||||||
|
|
||||||
|
# PyInstaller |
||||||
|
# Usually these files are written by a python script from a template |
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||||
|
*.manifest |
||||||
|
*.spec |
||||||
|
|
||||||
|
# Installer logs |
||||||
|
pip-log.txt |
||||||
|
pip-delete-this-directory.txt |
||||||
|
|
||||||
|
# Unit test / coverage reports |
||||||
|
htmlcov/ |
||||||
|
.tox/ |
||||||
|
.nox/ |
||||||
|
.coverage |
||||||
|
.coverage.* |
||||||
|
.cache |
||||||
|
nosetests.xml |
||||||
|
coverage.xml |
||||||
|
*.cover |
||||||
|
*.py,cover |
||||||
|
.hypothesis/ |
||||||
|
.pytest_cache/ |
||||||
|
cover/ |
||||||
|
|
||||||
|
# Translations |
||||||
|
*.mo |
||||||
|
*.pot |
||||||
|
|
||||||
|
# Django stuff: |
||||||
|
*.log |
||||||
|
local_settings.py |
||||||
|
db.sqlite3 |
||||||
|
db.sqlite3-journal |
||||||
|
|
||||||
|
# Flask stuff: |
||||||
|
instance/ |
||||||
|
.webassets-cache |
||||||
|
|
||||||
|
# Scrapy stuff: |
||||||
|
.scrapy |
||||||
|
|
||||||
|
# Sphinx documentation |
||||||
|
docs/_build/ |
||||||
|
|
||||||
|
# PyBuilder |
||||||
|
.pybuilder/ |
||||||
|
target/ |
||||||
|
|
||||||
|
# Jupyter Notebook |
||||||
|
.ipynb_checkpoints |
||||||
|
|
||||||
|
# IPython |
||||||
|
profile_default/ |
||||||
|
ipython_config.py |
||||||
|
|
||||||
|
# pyenv |
||||||
|
# For a library or package, you might want to ignore these files since the code is |
||||||
|
# intended to run in multiple environments; otherwise, check them in: |
||||||
|
# .python-version |
||||||
|
|
||||||
|
# pipenv |
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||||
|
# install all needed dependencies. |
||||||
|
#Pipfile.lock |
||||||
|
|
||||||
|
# poetry |
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more |
||||||
|
# commonly ignored for libraries. |
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
||||||
|
#poetry.lock |
||||||
|
|
||||||
|
# pdm |
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. |
||||||
|
#pdm.lock |
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it |
||||||
|
# in version control. |
||||||
|
# https://pdm.fming.dev/#use-with-ide |
||||||
|
.pdm.toml |
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm |
||||||
|
__pypackages__/ |
||||||
|
|
||||||
|
# Celery stuff |
||||||
|
celerybeat-schedule |
||||||
|
celerybeat.pid |
||||||
|
|
||||||
|
# SageMath parsed files |
||||||
|
*.sage.py |
||||||
|
|
||||||
|
# Environments |
||||||
|
.env |
||||||
|
.venv |
||||||
|
env/ |
||||||
|
venv/ |
||||||
|
ENV/ |
||||||
|
env.bak/ |
||||||
|
venv.bak/ |
||||||
|
|
||||||
|
# Spyder project settings |
||||||
|
.spyderproject |
||||||
|
.spyproject |
||||||
|
|
||||||
|
# Rope project settings |
||||||
|
.ropeproject |
||||||
|
|
||||||
|
# mkdocs documentation |
||||||
|
/site |
||||||
|
|
||||||
|
# mypy |
||||||
|
.mypy_cache/ |
||||||
|
.dmypy.json |
||||||
|
dmypy.json |
||||||
|
|
||||||
|
# Pyre type checker |
||||||
|
.pyre/ |
||||||
|
|
||||||
|
# pytype static type analyzer |
||||||
|
.pytype/ |
||||||
|
|
||||||
|
# Cython debug symbols |
||||||
|
cython_debug/ |
||||||
|
|
||||||
|
# PyCharm |
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can |
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore |
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear |
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder. |
||||||
|
#.idea/ |
@ -0,0 +1,3 @@ |
|||||||
|
from django.contrib import admin |
||||||
|
|
||||||
|
# Register your models here. |
@ -0,0 +1,6 @@ |
|||||||
|
from django.apps import AppConfig |
||||||
|
|
||||||
|
|
||||||
|
class LeftistsConfig(AppConfig): |
||||||
|
default_auto_field = 'django.db.models.BigAutoField' |
||||||
|
name = 'leftists' |
@ -0,0 +1,10 @@ |
|||||||
|
from django import forms |
||||||
|
|
||||||
|
from leftists.models import ShortLink |
||||||
|
|
||||||
|
|
||||||
|
class LinkForm(forms.ModelForm): |
||||||
|
class Meta: |
||||||
|
model = ShortLink |
||||||
|
fields = ["domain", "location", "to"] |
||||||
|
|
@ -0,0 +1,29 @@ |
|||||||
|
# Generated by Django 4.0.5 on 2022-06-18 23:16 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
initial = True |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('scopedsites', '0001_initial'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.CreateModel( |
||||||
|
name='ShortLink', |
||||||
|
fields=[ |
||||||
|
('slug', models.CharField(max_length=6, primary_key=True, serialize=False, unique=True)), |
||||||
|
('location', models.CharField(max_length=100, verbose_name='short link')), |
||||||
|
('to', models.URLField(max_length=2500, verbose_name='redirect to')), |
||||||
|
('click_count', models.IntegerField(default=0)), |
||||||
|
('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='links', to='scopedsites.domain')), |
||||||
|
], |
||||||
|
options={ |
||||||
|
'unique_together': {('domain', 'location')}, |
||||||
|
}, |
||||||
|
), |
||||||
|
] |
@ -0,0 +1,24 @@ |
|||||||
|
from django.db import models |
||||||
|
from django.utils.translation import gettext_lazy as _ |
||||||
|
from django_scopes import ScopedManager |
||||||
|
from scopedsites.models import Domain |
||||||
|
from xenua.django.models import RandomSlugPKMixin |
||||||
|
|
||||||
|
|
||||||
|
class ShortLink(RandomSlugPKMixin, models.Model): |
||||||
|
class Meta: |
||||||
|
unique_together = ('domain', 'location') |
||||||
|
|
||||||
|
domain = models.ForeignKey(Domain, related_name='links', on_delete=models.CASCADE) |
||||||
|
location = models.CharField(_("short link"), max_length=100) |
||||||
|
to = models.URLField(_("redirect to"), max_length=2500) |
||||||
|
click_count = models.IntegerField(default=0) |
||||||
|
|
||||||
|
objects = ScopedManager(domain='domain') |
||||||
|
|
||||||
|
def click(self): # todo: replace with cache + regular cleanup impl |
||||||
|
self.click_count += 1 |
||||||
|
self.save() |
||||||
|
|
||||||
|
def link(self): |
||||||
|
return f"{self.domain.fqdn}/{self.location}" |
@ -0,0 +1,32 @@ |
|||||||
|
{% load static %} |
||||||
|
|
||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||||
|
<title>{% block title %}lonk{% endblock %}</title> |
||||||
|
{# <link rel="stylesheet" href="{% static 'css/normalize.css' %}">#} |
||||||
|
{# <link rel="stylesheet" href="{% static 'forkawesome/css/fork-awesome.css' %}">#} |
||||||
|
{# <link rel="stylesheet" href="{% static 'css/terminal.css' %}">#} |
||||||
|
{# <link rel="stylesheet" href="{% static 'entropybase/base.css' %}">#} |
||||||
|
|
||||||
|
{% block meta %}{% endblock %} |
||||||
|
{% block css %}{% endblock %} |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<nav> |
||||||
|
<ul> |
||||||
|
{# <li><a href="{% url 'interface.domain.create' %}">+ domain</a></li>#} |
||||||
|
<li><a href="{% url 'interface.link.create' %}">+ link</a></li> |
||||||
|
{# <li><a href="{% url '' %}"></a></li>#} |
||||||
|
</ul> |
||||||
|
</nav> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
{% block main %}{% endblock %} |
||||||
|
</main> |
||||||
|
{% block js %}{% endblock %} |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,10 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<title>lonk</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
{% block body %}{% endblock %} |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,9 @@ |
|||||||
|
{% extends "base.html" %} |
||||||
|
|
||||||
|
{% block main %} |
||||||
|
<form method="post"> |
||||||
|
{% csrf_token %} |
||||||
|
{{ form.as_p }} |
||||||
|
<input type="submit" value="Submit" /> |
||||||
|
</form> |
||||||
|
{% endblock %} |
@ -0,0 +1,10 @@ |
|||||||
|
{% extends "base.html" %} |
||||||
|
|
||||||
|
{% block main %} |
||||||
|
<form method="post"> |
||||||
|
{% csrf_token %} |
||||||
|
<label for="delete">delete "{{ object.link }}"? </label> |
||||||
|
<input type="submit" value="Delete" name="delete"> |
||||||
|
</form> |
||||||
|
|
||||||
|
{% endblock %} |
@ -0,0 +1,25 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block main %} |
||||||
|
<div> |
||||||
|
managing these domains: |
||||||
|
<ul> |
||||||
|
{% for domain in domains %} |
||||||
|
<li>{{ domain.fqdn }}</li> |
||||||
|
{% endfor %} |
||||||
|
|
||||||
|
<table> |
||||||
|
<tr> |
||||||
|
<th>link</th> |
||||||
|
<th>to</th> |
||||||
|
</tr> |
||||||
|
{% for link in links %} |
||||||
|
<tr> |
||||||
|
<td>{{ link.link }}</td> |
||||||
|
<td>{{ link.to }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</table> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
{% endblock %} |
@ -0,0 +1,9 @@ |
|||||||
|
{% extends "base_plain.html" %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<form method="post"> |
||||||
|
{% csrf_token %} |
||||||
|
{{ form.as_p }} |
||||||
|
<input type="submit" value="Login" /> |
||||||
|
</form> |
||||||
|
{% endblock %} |
@ -0,0 +1,3 @@ |
|||||||
|
from django.test import TestCase |
||||||
|
|
||||||
|
# Create your tests here. |
@ -0,0 +1,13 @@ |
|||||||
|
from django.urls import path |
||||||
|
|
||||||
|
from leftists.views import ShortLinkRedirectView, CoolerLoginView, OverView, LinkCreateView, LinkUpdateView, \ |
||||||
|
LinkDeleteView |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
path('', CoolerLoginView.as_view(), name='login'), |
||||||
|
path('iface/overview', OverView.as_view(), name='interface.overview'), |
||||||
|
path('iface/link/create', LinkCreateView.as_view(), name='interface.link.create'), |
||||||
|
path('iface/link/update/<str:slug>', LinkUpdateView.as_view(), name='interface.link.update'), |
||||||
|
path('iface/link/delete/<str:slug>', LinkDeleteView.as_view(), name='interface.link.delete'), |
||||||
|
path('<str:link>', ShortLinkRedirectView.as_view(), name='link-redirect'), |
||||||
|
] |
@ -0,0 +1,57 @@ |
|||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin |
||||||
|
from django.contrib.auth.views import LoginView |
||||||
|
from django.shortcuts import get_object_or_404 |
||||||
|
from django.urls import reverse_lazy |
||||||
|
from django.views.generic import RedirectView, TemplateView, CreateView, UpdateView, DeleteView |
||||||
|
from scopedsites.models import Domain |
||||||
|
|
||||||
|
from leftists.forms import LinkForm |
||||||
|
from leftists.models import ShortLink |
||||||
|
|
||||||
|
|
||||||
|
class ShortLinkRedirectView(RedirectView): |
||||||
|
def get_redirect_url(self, *args, **kwargs): |
||||||
|
sl = get_object_or_404(ShortLink, location=kwargs.get('link')) |
||||||
|
sl.click() |
||||||
|
return sl.to |
||||||
|
|
||||||
|
|
||||||
|
class CoolerLoginView(LoginView): |
||||||
|
redirect_authenticated_user = True |
||||||
|
next_page = reverse_lazy('interface.overview') |
||||||
|
|
||||||
|
|
||||||
|
class OverView(LoginRequiredMixin, TemplateView): |
||||||
|
template_name = 'interface/overview.html' |
||||||
|
|
||||||
|
def get_context_data(self, **kwargs): |
||||||
|
ctx = super().get_context_data(**kwargs) |
||||||
|
ds = Domain.objects.all() |
||||||
|
ctx.setdefault('domains', ds) |
||||||
|
links = [] |
||||||
|
for d in ds: |
||||||
|
[links.append(l) for l in d.links.all()] |
||||||
|
ctx.setdefault('links', links) |
||||||
|
return ctx |
||||||
|
|
||||||
|
|
||||||
|
class LinkCreateView(LoginRequiredMixin, CreateView): |
||||||
|
template_name = 'interface/basic_form.html' |
||||||
|
model = ShortLink |
||||||
|
form_class = LinkForm |
||||||
|
success_url = reverse_lazy('interface.overview') |
||||||
|
|
||||||
|
|
||||||
|
class LinkUpdateView(LoginRequiredMixin, UpdateView): |
||||||
|
template_name = 'interface/basic_form.html' |
||||||
|
model = ShortLink |
||||||
|
form_class = LinkForm |
||||||
|
success_url = reverse_lazy('interface.overview') |
||||||
|
|
||||||
|
|
||||||
|
class LinkDeleteView(LoginRequiredMixin, DeleteView): |
||||||
|
template_name = 'interface/delete_link.html' |
||||||
|
model = ShortLink |
||||||
|
success_url = reverse_lazy('interface.overview') |
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@ |
|||||||
|
""" |
||||||
|
ASGI config for lonk project. |
||||||
|
|
||||||
|
It exposes the ASGI callable as a module-level variable named ``application``. |
||||||
|
|
||||||
|
For more information on this file, see |
||||||
|
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ |
||||||
|
""" |
||||||
|
|
||||||
|
import os |
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application |
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lonk.settings') |
||||||
|
|
||||||
|
application = get_asgi_application() |
@ -0,0 +1,132 @@ |
|||||||
|
""" |
||||||
|
Django settings for lonk project. |
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 4.0.5. |
||||||
|
|
||||||
|
For more information on this file, see |
||||||
|
https://docs.djangoproject.com/en/4.0/topics/settings/ |
||||||
|
|
||||||
|
For the full list of settings and their values, see |
||||||
|
https://docs.djangoproject.com/en/4.0/ref/settings/ |
||||||
|
""" |
||||||
|
|
||||||
|
from pathlib import Path |
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'. |
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent |
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production |
||||||
|
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ |
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret! |
||||||
|
SECRET_KEY = 'django-insecure-&$_=kq+s^d^nos!hw9cktmapz@2(!aex_ub1vq)@^j(**3dxqe' |
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production! |
||||||
|
DEBUG = True |
||||||
|
|
||||||
|
ALLOWED_HOSTS = ['*'] |
||||||
|
|
||||||
|
|
||||||
|
# Application definition |
||||||
|
|
||||||
|
INSTALLED_APPS = [ |
||||||
|
'django.contrib.auth', |
||||||
|
'django.contrib.contenttypes', |
||||||
|
'django.contrib.sessions', |
||||||
|
'django.contrib.messages', |
||||||
|
'django.contrib.staticfiles', |
||||||
|
'scopedsites', |
||||||
|
'leftists', |
||||||
|
] |
||||||
|
|
||||||
|
MIDDLEWARE = [ |
||||||
|
'django.middleware.security.SecurityMiddleware', |
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware', |
||||||
|
'django.middleware.common.CommonMiddleware', |
||||||
|
'django.middleware.csrf.CsrfViewMiddleware', |
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware', |
||||||
|
'django.contrib.messages.middleware.MessageMiddleware', |
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware', |
||||||
|
'scopedsites.middleware.DomainAutoCreateMiddleware', |
||||||
|
'scopedsites.middleware.DomainScopeMiddleware', |
||||||
|
] |
||||||
|
|
||||||
|
ROOT_URLCONF = 'lonk.urls' |
||||||
|
|
||||||
|
TEMPLATES = [ |
||||||
|
{ |
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates', |
||||||
|
'DIRS': [BASE_DIR / 'templates'] |
||||||
|
, |
||||||
|
'APP_DIRS': True, |
||||||
|
'OPTIONS': { |
||||||
|
'context_processors': [ |
||||||
|
'django.template.context_processors.debug', |
||||||
|
'django.template.context_processors.request', |
||||||
|
'django.contrib.auth.context_processors.auth', |
||||||
|
'django.contrib.messages.context_processors.messages', |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
WSGI_APPLICATION = 'lonk.wsgi.application' |
||||||
|
|
||||||
|
|
||||||
|
# Database |
||||||
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases |
||||||
|
|
||||||
|
DATABASES = { |
||||||
|
'default': { |
||||||
|
'ENGINE': 'django.db.backends.sqlite3', |
||||||
|
'NAME': BASE_DIR / 'db.sqlite3', |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
# Password validation |
||||||
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators |
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [ |
||||||
|
{ |
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', |
||||||
|
}, |
||||||
|
{ |
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', |
||||||
|
}, |
||||||
|
{ |
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', |
||||||
|
}, |
||||||
|
{ |
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
# Internationalization |
||||||
|
# https://docs.djangoproject.com/en/4.0/topics/i18n/ |
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us' |
||||||
|
|
||||||
|
TIME_ZONE = 'UTC' |
||||||
|
|
||||||
|
USE_I18N = True |
||||||
|
|
||||||
|
USE_TZ = True |
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images) |
||||||
|
# https://docs.djangoproject.com/en/4.0/howto/static-files/ |
||||||
|
|
||||||
|
STATIC_URL = 'static/' |
||||||
|
|
||||||
|
# Default primary key field type |
||||||
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field |
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' |
||||||
|
|
||||||
|
|
||||||
|
APPEND_SLASH = False |
||||||
|
|
||||||
|
LOGIN_URL = '/' |
@ -0,0 +1,20 @@ |
|||||||
|
"""lonk URL Configuration |
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see: |
||||||
|
https://docs.djangoproject.com/en/4.0/topics/http/urls/ |
||||||
|
Examples: |
||||||
|
Function views |
||||||
|
1. Add an import: from my_app import views |
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home') |
||||||
|
Class-based views |
||||||
|
1. Add an import: from other_app.views import Home |
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
||||||
|
Including another URLconf |
||||||
|
1. Import the include() function: from django.urls import include, path |
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
||||||
|
""" |
||||||
|
from django.urls import path, include |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
path('', include('leftists.urls')), |
||||||
|
] |
@ -0,0 +1,16 @@ |
|||||||
|
""" |
||||||
|
WSGI config for lonk project. |
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``. |
||||||
|
|
||||||
|
For more information on this file, see |
||||||
|
https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ |
||||||
|
""" |
||||||
|
|
||||||
|
import os |
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application |
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lonk.settings') |
||||||
|
|
||||||
|
application = get_wsgi_application() |
@ -0,0 +1,22 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
"""Django's command-line utility for administrative tasks.""" |
||||||
|
import os |
||||||
|
import sys |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
"""Run administrative tasks.""" |
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lonk.settings') |
||||||
|
try: |
||||||
|
from django.core.management import execute_from_command_line |
||||||
|
except ImportError as exc: |
||||||
|
raise ImportError( |
||||||
|
"Couldn't import Django. Are you sure it's installed and " |
||||||
|
"available on your PYTHONPATH environment variable? Did you " |
||||||
|
"forget to activate a virtual environment?" |
||||||
|
) from exc |
||||||
|
execute_from_command_line(sys.argv) |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
main() |
Loading…
Reference in new issue