Compare commits
28 Commits
a88dec9610
...
master
Author | SHA1 | Date | |
---|---|---|---|
325a234b18 | |||
add60af880 | |||
0b64b4ed25 | |||
660fc54101 | |||
06d4c3ee77 | |||
85217e4e9c | |||
79f6d10d9d | |||
f3ecaedb55 | |||
47bbec8dfe | |||
b690967d5d | |||
2dae592258 | |||
c1371cdd94 | |||
7aecc21528 | |||
ccebb6f4a7 | |||
7922d749ab | |||
a5cfb42818 | |||
91430d30a0 | |||
f0975c6505 | |||
d2909e5ce9 | |||
eb24f56b7c | |||
17f5199fa1 | |||
18b063713e | |||
3632f27583 | |||
e8cd3c33d2 | |||
a004b3eb0e | |||
37bf9a0c82 | |||
01035a2b45 | |||
d414868d93 |
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
venv
|
venv/
|
||||||
.vscode
|
.vscode/
|
||||||
__pycache__
|
__pycache__/
|
||||||
|
db.sqlite3
|
||||||
|
.env
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "public/libcasa/themes/risotto"]
|
||||||
|
path = public/libcasa/themes/risotto
|
||||||
|
url = https://github.com/joeroe/risotto.git
|
@ -0,0 +1,6 @@
|
|||||||
|
# Django Backend for LibertaCasa
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
* Use a virtual environment and `pip install -r requirements.txt`
|
||||||
|
* deps: `psychopg2`, `django`, `djangorestframework`.
|
@ -1,3 +1,5 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
|
|
6
api/control/apps.py
Normal file
6
api/control/apps.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ControlConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'control'
|
34
api/control/models.py
Normal file
34
api/control/models.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class ScheduledTask(models.Model):
|
||||||
|
from control.tasks import REGISTERED_TASKS
|
||||||
|
|
||||||
|
class CatchupMode(models.IntegerChoices):
|
||||||
|
SKIP = 0, ('SKIP TO LATEST')
|
||||||
|
EXEC = 1, ('EXECUTE ALL')
|
||||||
|
|
||||||
|
class Interval(models.IntegerChoices):
|
||||||
|
HOURS = 1, ('HOURS')
|
||||||
|
DAYS = 24, ('DAYS')
|
||||||
|
WEEKS = 168, ('WEEKS')
|
||||||
|
|
||||||
|
active = models.BooleanField(default=False)
|
||||||
|
name = models.CharField(max_length=128)
|
||||||
|
action = models.CharField(max_length=128, choices=zip(
|
||||||
|
REGISTERED_TASKS.keys(), REGISTERED_TASKS.keys()))
|
||||||
|
kwargs = models.JSONField(blank=True, null=True)
|
||||||
|
repeat = models.IntegerField('Repeat Every', default=0)
|
||||||
|
repeat_interval = models.IntegerField(
|
||||||
|
'Interval', choices=Interval.choices, default=1)
|
||||||
|
start_datetime = models.DateTimeField()
|
||||||
|
end_datetime = models.DateTimeField(blank=True, null=True)
|
||||||
|
next_cycle = models.DateTimeField(blank=True, null=True)
|
||||||
|
catchup_mode = models.IntegerField(
|
||||||
|
default=0, choices=CatchupMode.choices)
|
||||||
|
|
||||||
|
class Meta():
|
||||||
|
verbose_name = 'Scheduled Task'
|
||||||
|
verbose_name_plural = 'Scheduled Tasks'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
9
api/control/tasks.py
Normal file
9
api/control/tasks.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from datetime import datetime, timezone, timedelta,
|
||||||
|
|
||||||
|
### TASKS ###
|
||||||
|
|
||||||
|
# def test_task(comms: dict, debug=False):
|
||||||
|
# timestamp = datetime.now(tz=timezone.utc).strftime("%b %d %Y %H:%M")
|
||||||
|
# text = "Test Task fired at " + timestamp
|
||||||
|
# blocks = [make_section(text)]
|
||||||
|
# process_comms(comms, blocks, debug)
|
5
api/posts/admin.py
Normal file
5
api/posts/admin.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from posts.models import *
|
||||||
|
|
||||||
|
admin.site.register(Post)
|
@ -1,6 +1,6 @@
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class BlogConfig(AppConfig):
|
class PostsConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'blog'
|
name = 'posts'
|
29
api/posts/migrations/0001_initial.py
Normal file
29
api/posts/migrations/0001_initial.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 4.0 on 2022-01-08 06:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Post',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('title', models.CharField(blank=True, default='', max_length=100)),
|
||||||
|
('body', models.TextField(blank=True, default='')),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='posts', to='auth.user')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['created'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
0
api/posts/migrations/__init__.py
Normal file
0
api/posts/migrations/__init__.py
Normal file
18
api/posts/models.py
Normal file
18
api/posts/models.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
# move to `const.py`
|
||||||
|
|
||||||
|
STATUS = (
|
||||||
|
(0,"Draft"),
|
||||||
|
(1,"Publish")
|
||||||
|
)
|
||||||
|
# Create your models here.
|
||||||
|
class Post(models.Model):
|
||||||
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
title = models.CharField(max_length=100, blank=True, default='')
|
||||||
|
body = models.TextField(blank=True, default='')
|
||||||
|
owner = models.ForeignKey('auth.User', related_name='posts', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['created']
|
3
api/posts/tests.py
Normal file
3
api/posts/tests.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
11
api/posts/urls.py
Normal file
11
api/posts/urls.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register(r'posts', views.PostsViewSet)
|
||||||
|
# router.register(r'users', views.UserViewSet)
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', include(router.urls)),
|
||||||
|
]
|
30
api/posts/views.py
Normal file
30
api/posts/views.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.shortcuts import render
|
||||||
|
from snippets.serializers import UserSerializer
|
||||||
|
from .models import Post
|
||||||
|
from .serializers import PostSerializer
|
||||||
|
from posts.permissions import IsOwnerOrReadOnly
|
||||||
|
from rest_framework import permissions, renderers
|
||||||
|
from rest_framework.reverse import reverse
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
class PostsViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
docstring
|
||||||
|
"""
|
||||||
|
queryset = Post.objects.all()
|
||||||
|
serializer_class = PostSerializer
|
||||||
|
permission_classes = [permissions.IsAuthenticatedOrReadOnly,
|
||||||
|
IsOwnerOrReadOnly]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
|
||||||
|
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
|
"""
|
||||||
|
This viewset automatically provides `list` and `retrieve` actions.
|
||||||
|
"""
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = UserSerializer
|
0
api/snippets/__init__.py
Normal file
0
api/snippets/__init__.py
Normal file
80
api/snippets/admin.py
Normal file
80
api/snippets/admin.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.admin.models import LogEntry, DELETION
|
||||||
|
|
||||||
|
from django.utils.html import escape
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from snippets.models import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#LogEntry
|
||||||
|
@admin.register(LogEntry)
|
||||||
|
class LogEntryAdmin(admin.ModelAdmin):
|
||||||
|
# to have a date-based drilldown navigation in the admin page
|
||||||
|
date_hierarchy = "action_time"
|
||||||
|
|
||||||
|
# to filter the resultes by users, content types and action flags
|
||||||
|
list_filter = ["user", "content_type", "action_flag"]
|
||||||
|
|
||||||
|
# when searching the user will be able to search in both object_repr and change_message
|
||||||
|
search_fields = ["object_repr", "change_message"]
|
||||||
|
|
||||||
|
list_display = [
|
||||||
|
"action_time",
|
||||||
|
"user",
|
||||||
|
"content_type",
|
||||||
|
"action_flag",
|
||||||
|
"object_link",
|
||||||
|
]
|
||||||
|
|
||||||
|
def has_add_permission(self, request):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_change_permission(self, request, obj=None):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_delete_permission(self, request, obj=None):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_view_permission(self, request, obj=None):
|
||||||
|
return request.user.is_staff
|
||||||
|
|
||||||
|
def object_link(self, obj):
|
||||||
|
if obj.action_flag == DELETION:
|
||||||
|
link = escape(obj.object_repr)
|
||||||
|
else:
|
||||||
|
ct = obj.content_type
|
||||||
|
link = '<a href="%s">%s</a>' % (
|
||||||
|
reverse(
|
||||||
|
"admin:%s_%s_change" % (ct.app_label, ct.model),
|
||||||
|
args=[obj.object_id],
|
||||||
|
),
|
||||||
|
escape(obj.object_repr),
|
||||||
|
)
|
||||||
|
return mark_safe(link)
|
||||||
|
|
||||||
|
object_link.admin_order_field = "object_repr"
|
||||||
|
object_link.short_description = "object"
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Snippet)
|
||||||
|
class SnippetAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
|
date_hierarchy = "created"
|
||||||
|
ordering= ['-created']
|
||||||
|
# add hyperlinked highlighted view and
|
||||||
|
# possibly code preview js magic
|
||||||
|
list_filter = ('owner', 'language', 'style')
|
||||||
|
list_display = ['id',
|
||||||
|
'title',
|
||||||
|
'owner',
|
||||||
|
'created',
|
||||||
|
'language']
|
||||||
|
search_fields = ['owner', 'title', 'language']
|
||||||
|
|
||||||
|
# @admin.register)
|
||||||
|
# class SnippetAdmin(admin.ModelAdmin):
|
||||||
|
# pass
|
6
api/snippets/apps.py
Normal file
6
api/snippets/apps.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class SnippetsConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'snippets'
|
33
api/snippets/migrations/0001_initial.py
Normal file
33
api/snippets/migrations/0001_initial.py
Normal file
File diff suppressed because one or more lines are too long
0
api/snippets/migrations/__init__.py
Normal file
0
api/snippets/migrations/__init__.py
Normal file
39
api/snippets/models.py
Normal file
39
api/snippets/models.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# pygments
|
||||||
|
|
||||||
|
from pygments import highlight
|
||||||
|
from pygments.lexers import get_all_lexers
|
||||||
|
from pygments.styles import get_all_styles
|
||||||
|
from pygments.lexers import get_lexer_by_name
|
||||||
|
from pygments.formatters.html import HtmlFormatter
|
||||||
|
|
||||||
|
LEXERS = [item for item in get_all_lexers() if item[1]]
|
||||||
|
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
|
||||||
|
STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])
|
||||||
|
|
||||||
|
class Snippet(models.Model):
|
||||||
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
# modified?
|
||||||
|
title = models.CharField(max_length=100, blank=True, default='')
|
||||||
|
code = models.TextField()
|
||||||
|
linenos = models.BooleanField(default=False)
|
||||||
|
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
|
||||||
|
style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
|
||||||
|
owner = models.ForeignKey('auth.user', related_name='snippets', on_delete=models.CASCADE)
|
||||||
|
highlighted = models.TextField()
|
||||||
|
class Meta:
|
||||||
|
ordering = ['created']
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Use the `pygments` library to create a highlighted HTML
|
||||||
|
representation of the code snippet.
|
||||||
|
"""
|
||||||
|
lexer = get_lexer_by_name(self.language)
|
||||||
|
linenos = 'table' if self.linenos else False
|
||||||
|
options = {'title': self.title} if self.title else {}
|
||||||
|
formatter = HtmlFormatter(style=self.style, linenos=linenos,
|
||||||
|
full=True, **options)
|
||||||
|
self.highlighted = highlight(self.code, lexer, formatter)
|
||||||
|
super().save(*args, **kwargs)
|
15
api/snippets/permissions.py
Normal file
15
api/snippets/permissions.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from rest_framework import permissions
|
||||||
|
|
||||||
|
class IsOwnerOrReadOnly(permissions.BasePermission):
|
||||||
|
"""
|
||||||
|
Custom permission to only allow owners of an object to edit it.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
# Read permissions are allowed to any request,
|
||||||
|
# so we'll always allow GET, HEAD or OPTIONS requests.
|
||||||
|
if request.method in permissions.SAFE_METHODS:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Write permissions are only allowed to the owner of the snippet.
|
||||||
|
return obj.owner == request.user
|
18
api/snippets/serializers.py
Normal file
18
api/snippets/serializers.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from rest_framework import serializers
|
||||||
|
from .models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
|
||||||
|
|
||||||
|
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
owner = serializers.ReadOnlyField(source='owner.username')
|
||||||
|
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
|
||||||
|
class Meta:
|
||||||
|
model = Snippet
|
||||||
|
fields = ['url', 'id', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style']
|
||||||
|
|
||||||
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ['url', 'id', 'username', 'snippets']
|
3
api/snippets/tests.py
Normal file
3
api/snippets/tests.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
12
api/snippets/urls.py
Normal file
12
api/snippets/urls.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register(r'snippets', views.SnippetViewSet)
|
||||||
|
router.register(r'users', views.UserViewSet)
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', include(router.urls)),
|
||||||
|
]
|
37
api/snippets/views.py
Normal file
37
api/snippets/views.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from .models import Snippet
|
||||||
|
from .serializers import SnippetSerializer, UserSerializer
|
||||||
|
from snippets.permissions import IsOwnerOrReadOnly
|
||||||
|
from rest_framework import permissions, renderers
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.reverse import reverse
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
class SnippetViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
This viewset automatically provides `list`, `create`, `retrieve`,
|
||||||
|
`update` and `destroy` actions.
|
||||||
|
|
||||||
|
Additionally we also provide an extra `highlight` action.
|
||||||
|
"""
|
||||||
|
queryset = Snippet.objects.all()
|
||||||
|
serializer_class = SnippetSerializer
|
||||||
|
permission_classes = [permissions.IsAuthenticatedOrReadOnly,
|
||||||
|
IsOwnerOrReadOnly]
|
||||||
|
|
||||||
|
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
|
||||||
|
def highlight(self, request, *args, **kwargs):
|
||||||
|
snippet = self.get_object()
|
||||||
|
return Response(snippet.highlighted)
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
|
"""
|
||||||
|
This viewset automatically provides `list` and `retrieve` actions.
|
||||||
|
"""
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = UserSerializer
|
0
api/website/__init__.py
Normal file
0
api/website/__init__.py
Normal file
@ -11,10 +11,26 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
## ENVARS ##
|
||||||
|
|
||||||
|
POSTGRES_DB = os.getenv('POSTGRES_DB')
|
||||||
|
POSTGRES_USER = os.getenv('POSTGRES_USER')
|
||||||
|
POSTGRES_PASSWORD = os.getenv('POSTGRES_PASSWORD')
|
||||||
|
POSTGRES_HOST = os.getenv('POSTGRES_HOST')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = False
|
||||||
|
if os.getenv('DEBUG') == 'True':
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
|
||||||
@ -37,6 +53,11 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'rest_framework',
|
||||||
|
'snippets.apps.SnippetsConfig',
|
||||||
|
'posts.apps.PostsConfig',
|
||||||
|
'api.apps.ApiConfig',
|
||||||
|
'control.apps.ControlConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -74,11 +95,23 @@ WSGI_APPLICATION = 'website.wsgi.application'
|
|||||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||||
|
'NAME': POSTGRES_DB,
|
||||||
|
'USER': POSTGRES_USER,
|
||||||
|
'PASSWORD': POSTGRES_PASSWORD,
|
||||||
|
'HOST': POSTGRES_HOST,
|
||||||
|
'PORT': '5432',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.getenv('DEV') == 'true':
|
||||||
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': BASE_DIR / 'db.sqlite3',
|
'NAME': BASE_DIR / 'db.sqlite3',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
@ -121,3 +154,35 @@ STATIC_URL = 'static/'
|
|||||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||||
|
'PAGE_SIZE': 10,
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
|
'rest_framework.authentication.BasicAuthentication',
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# LOGGING = {
|
||||||
|
# 'version': 1,
|
||||||
|
# 'disable_existing_loggers': False,
|
||||||
|
# 'handlers': {
|
||||||
|
# 'file': {
|
||||||
|
# 'level': 'DEBUG',
|
||||||
|
# 'class': 'logging.FileHandler',
|
||||||
|
# 'filename': './debug.log',
|
||||||
|
# },
|
||||||
|
# 'error_file': {
|
||||||
|
# 'level': 'ERROR',
|
||||||
|
# 'class': 'logging.FileHandler',
|
||||||
|
# 'filename': './error.log',
|
||||||
|
# },
|
||||||
|
# },
|
||||||
|
# 'loggers': {
|
||||||
|
# 'django': {
|
||||||
|
# 'handlers': ['file', 'error_file'],
|
||||||
|
# 'propagate': True,
|
||||||
|
# },
|
||||||
|
# },
|
||||||
|
# }
|
@ -14,8 +14,14 @@ Including another URLconf
|
|||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('snippets/', include('snippets.urls')),
|
||||||
|
path('posts/', include('posts.urls'))
|
||||||
|
]
|
||||||
|
|
||||||
|
urlpatterns += [
|
||||||
|
path('api-auth/', include('rest_framework.urls')),
|
||||||
]
|
]
|
0
public/libcasa/.hugo_build.lock
Normal file
0
public/libcasa/.hugo_build.lock
Normal file
6
public/libcasa/archetypes/default.md
Normal file
6
public/libcasa/archetypes/default.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "{{ replace .Name "-" " " | title }}"
|
||||||
|
date: {{ .Date }}
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
53
public/libcasa/config.yml
Normal file
53
public/libcasa/config.yml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
baseURL: https://liberta.casa
|
||||||
|
theme: risotto
|
||||||
|
languageCode: en-us
|
||||||
|
title: Liberta Casa
|
||||||
|
paginate: 3
|
||||||
|
authors: [ Georg Pfuetzenreuter, Pratyush Desai ]
|
||||||
|
|
||||||
|
# Automatically add content sections to main menu
|
||||||
|
sectionPagesMenu: main
|
||||||
|
|
||||||
|
params:
|
||||||
|
theme:
|
||||||
|
palette: monokai-dark
|
||||||
|
mode: dark-mode
|
||||||
|
about:
|
||||||
|
title: Liberta Casa
|
||||||
|
description: 'For those who FLOSS shall be free.'
|
||||||
|
logo: images/logo.png
|
||||||
|
socialLinks:
|
||||||
|
- icon: fab fa-irc
|
||||||
|
title: IRC
|
||||||
|
url: 'https://liberta.casa/gamja'
|
||||||
|
- icon: fas fa-envelope
|
||||||
|
title: Email
|
||||||
|
url: 'mailto:hello@liberta.casa'
|
||||||
|
|
||||||
|
menu:
|
||||||
|
main:
|
||||||
|
- identifier: about
|
||||||
|
name: About
|
||||||
|
url: /about/
|
||||||
|
weight: 10
|
||||||
|
- identifier: rules
|
||||||
|
name: Rules
|
||||||
|
url: /rules/
|
||||||
|
weight: 10
|
||||||
|
- identifier: faqs
|
||||||
|
name: FAQ
|
||||||
|
url: /faqs/
|
||||||
|
weight: 10
|
||||||
|
- identifier: accounts
|
||||||
|
name: Account
|
||||||
|
url: /accounts/
|
||||||
|
weight: 10
|
||||||
|
- identifier: tools
|
||||||
|
name: Tools
|
||||||
|
url: /tools/
|
||||||
|
weight: 10
|
||||||
|
|
||||||
|
taxonomies:
|
||||||
|
category: categories
|
||||||
|
tag: tags
|
||||||
|
series: series
|
3
public/libcasa/content/_index.md
Normal file
3
public/libcasa/content/_index.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
+++
|
||||||
|
author = "LibCasa Authors"
|
||||||
|
+++
|
7
public/libcasa/content/about.md
Normal file
7
public/libcasa/content/about.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
+++
|
||||||
|
title = "About"
|
||||||
|
description = "Liberta Casa, providing services.. for some reason."
|
||||||
|
date = "2021-12-12"
|
||||||
|
aliases = ["about-us", "about-libertacasa", "contact"]
|
||||||
|
author = "LibCasa Authors"
|
||||||
|
+++
|
6
public/libcasa/content/accounts/_index.md
Normal file
6
public/libcasa/content/accounts/_index.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "Accounts"
|
||||||
|
date: 2022-01-08T15:14:39+05:30
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
6
public/libcasa/content/faqs/_index.md
Normal file
6
public/libcasa/content/faqs/_index.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "Faqs"
|
||||||
|
date: 2022-01-08T15:14:13+05:30
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
3
public/libcasa/content/rules.md
Normal file
3
public/libcasa/content/rules.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
+++
|
||||||
|
title = "Rules"
|
||||||
|
+++
|
6
public/libcasa/content/tools/_index.md
Normal file
6
public/libcasa/content/tools/_index.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "Tools"
|
||||||
|
date: 2022-01-08T15:14:47+05:30
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
1
public/libcasa/themes/risotto
Submodule
1
public/libcasa/themes/risotto
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 07f1b3ecfd4202a69847d47c89ece4e4d01278c4
|
@ -2,5 +2,6 @@ asgiref==3.4.1
|
|||||||
Django==4.0
|
Django==4.0
|
||||||
djangorestframework==3.13.1
|
djangorestframework==3.13.1
|
||||||
psycopg2==2.9.2
|
psycopg2==2.9.2
|
||||||
|
Pygments==2.11.2
|
||||||
pytz==2021.3
|
pytz==2021.3
|
||||||
sqlparse==0.4.2
|
sqlparse==0.4.2
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
|
|
||||||
|
|
||||||
# move to `const.py`
|
|
||||||
|
|
||||||
STATUS = (
|
|
||||||
(0,"Draft"),
|
|
||||||
(1,"Publish")
|
|
||||||
)
|
|
||||||
# Create your models here.
|
|
||||||
|
|
||||||
class Post(models.Model):
|
|
||||||
title = models.CharField(max_length=200, unique=True)
|
|
||||||
author = models.ForeignKey('user.auth',on_delete=models.CASCADE)
|
|
||||||
updated_on =models.DateTimeField(auto_now= True)
|
|
||||||
created_on = models.DateTimeField(auto_now_add=True)
|
|
||||||
content = models.TextField()
|
|
||||||
# status = models.IntegerChoices()
|
|
@ -1,7 +0,0 @@
|
|||||||
from django.urls import path, include
|
|
||||||
from . import views
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path('blogs/', include('blog.urls')),
|
|
||||||
path('', views.index, name='index')
|
|
||||||
]
|
|
Reference in New Issue
Block a user