Compare commits
44 Commits
d7acc197cf
...
master
Author | SHA1 | Date | |
---|---|---|---|
c64c4a1ba4 | |||
c941397e7b | |||
0fb617976d | |||
a724716d7e | |||
c3cfef4ae3 | |||
b7c4c1a207 | |||
00f15f1879 | |||
ddae692f0b | |||
20330437ea | |||
83de5f58a2 | |||
e87f45bcd8 | |||
678204ec71 | |||
743d6ec5ca | |||
409ad95c05 | |||
df9066e066 | |||
17f3c5608e | |||
9534763621 | |||
168bf85fe2 | |||
c293ba7bf7 | |||
67b7a5e20d | |||
ec1858fd25 | |||
ac76e69f4f | |||
2cd48b67ab | |||
0f1766ec94 | |||
82f97cce0d | |||
b4961d6213 | |||
502fc62d1e | |||
506b097929 | |||
69a5889f55 | |||
6c567292e5 | |||
f008d0030a | |||
6a2db02c4d | |||
31234c6e94 | |||
419d5dfdc3 | |||
5c5015f418 | |||
8562ea5e80 | |||
9b0d636299 | |||
5341583fb2 | |||
51661aaa71 | |||
014b17e507 | |||
86421a7eb3 | |||
5e3fc17daa | |||
b525bc2cc0 | |||
fbe77098cd |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -61,6 +61,7 @@ cover/
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
migrations/
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
@@ -138,4 +139,4 @@ dmypy.json
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
rakka.conf
|
||||
rakka.conf
|
||||
|
6
books/converters.py
Normal file
6
books/converters.py
Normal file
@@ -0,0 +1,6 @@
|
||||
class RealIntConverter:
|
||||
regex='[0-9]+'
|
||||
def to_python(self,value):
|
||||
return int(value)
|
||||
def to_url(self,value):
|
||||
return str(value)
|
@@ -1,8 +1,10 @@
|
||||
from django.urls import path, re_path, include
|
||||
from . import views
|
||||
from django.urls import path, register_converter
|
||||
from . import views,converters
|
||||
|
||||
register_converter(converters.RealIntConverter,'rint')
|
||||
|
||||
urlpatterns=[
|
||||
path('',views.index,name='bidex'),
|
||||
path('<str:bookurl>',views.book,name='bbook'),
|
||||
path('<str:bookurl>/<str:chapnum>',views.chapter,name='bchap'),
|
||||
path('<str:bookurl>/<rint:chapnum>',views.chapter,name='bchap'),
|
||||
]
|
@@ -1,46 +1,5 @@
|
||||
from django.shortcuts import render
|
||||
from . import models
|
||||
from django.template import loader
|
||||
|
||||
import functools
|
||||
|
||||
def rerender(funky):
|
||||
@functools.wraps(funky)
|
||||
def wrap(req,*args,**kwargs):
|
||||
with open('main/utils/navs') as b:
|
||||
navs=parsecat(b,4)
|
||||
namednavs=[{'id':blah[0], 'link':blah[1], 'text':blah[2], 'align':int(blah[3])} for blah in navs['']]
|
||||
out=funky(*args,**kwargs)
|
||||
temp=loader.get_template('main/nav.html')
|
||||
out['nav']=temp.render({"navs":namednavs},None)
|
||||
return render(req, 'main/temp.html', out)
|
||||
return wrap
|
||||
|
||||
def parsecat(file,n):
|
||||
if not isinstance(file,str):
|
||||
# Assume open handle
|
||||
stuff=file.read()
|
||||
else:
|
||||
with open(f'main/pages/{file}') as b:
|
||||
stuff=b.read()
|
||||
cats=stuff.split('\n\n')
|
||||
out={}
|
||||
head=''
|
||||
out['']=[]
|
||||
for cat in cats:
|
||||
if ':' in cat[:cat.index('\n')]:
|
||||
# We have a category name
|
||||
head,cat=cat.split('\n',1)
|
||||
head=head[:-1]
|
||||
out[head]=[]
|
||||
else: head=''
|
||||
for line in cat.split('\n'):
|
||||
lin=line.split(',',n-1)
|
||||
pad=n-len(lin)
|
||||
lin.extend(['']*pad)
|
||||
out[head].append(lin)
|
||||
if out['']==[]: del(out[''])
|
||||
return out
|
||||
from rakka.utils import rerender
|
||||
|
||||
@rerender
|
||||
def index():
|
||||
@@ -58,6 +17,6 @@ def book(bookurl):
|
||||
@rerender
|
||||
def chapter(bookurl,chapnum):
|
||||
book=models.Book.objects.filter(url=bookurl)[0]
|
||||
chapter=models.Chapter.objects.filter(book=book,number=int(chapnum))[0]
|
||||
chapter=models.Chapter.objects.filter(book=book,number=chapnum)[0]
|
||||
text='<p>'+chapter.contents.replace('<','<').replace('>','>').replace('\n\n','</p><p>').replace('\n','<br/>')+'</p>'
|
||||
return {'title':chapter,'content':'<p>Navigation buttons will come later...</p>\n'+text,'date':chapter.added}
|
0
comment/__init__.py
Normal file
0
comment/__init__.py
Normal file
3
comment/admin.py
Normal file
3
comment/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
6
comment/apps.py
Normal file
6
comment/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CommentConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'comment'
|
0
comment/migrations/__init__.py
Normal file
0
comment/migrations/__init__.py
Normal file
3
comment/models.py
Normal file
3
comment/models.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
3
comment/tests.py
Normal file
3
comment/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
7
comment/urls.py
Normal file
7
comment/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.urls import include, path
|
||||
from . import views
|
||||
|
||||
urlpatterns=[
|
||||
path('',views.look,name='look'),
|
||||
path('new',views.submit,name='new'),
|
||||
]
|
11
comment/views.py
Normal file
11
comment/views.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from django.shortcuts import render
|
||||
from rakka.utils import rerender
|
||||
# Create your views here.
|
||||
|
||||
@rerender
|
||||
def look():
|
||||
pass
|
||||
|
||||
@rerender
|
||||
def submit():
|
||||
pass
|
@@ -2,7 +2,8 @@ from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
||||
from .models import Page,Contact,Update
|
||||
from .models import Page,Contact,Update,Redirect
|
||||
admin.site.register(Page)
|
||||
admin.site.register(Contact)
|
||||
admin.site.register(Update)
|
||||
admin.site.register(Update)
|
||||
admin.site.register(Redirect)
|
23
main/converters.py
Normal file
23
main/converters.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from .models import Page,Redirect
|
||||
|
||||
class AutoPageConverter:
|
||||
regex='.*'
|
||||
def to_python(self,value):
|
||||
try: p=Page.objects.get(url=value)
|
||||
except Page.DoesNotExist: raise ValueError(f'No such page {value}')
|
||||
if not p: raise ValueError(f'No such page {value}')
|
||||
return p
|
||||
def to_url(self,value):
|
||||
if not isinstance(value,Page): raise ValueError('Given value is not a Page')
|
||||
return p.url
|
||||
|
||||
class RedirectConverter:
|
||||
regex='.*'
|
||||
def to_python(self,value):
|
||||
try: r=Redirect.objects.get(match=value)
|
||||
except Redirect.DoesNotExist: raise ValueError(f'No such redirect {value}')
|
||||
if not r: raise ValueError(f'No such redirect {value}')
|
||||
return r
|
||||
def to_url(self,value):
|
||||
if not isinstance(value,Redirect): raise ValueError('Given value is not a Redirect')
|
||||
return p.match
|
@@ -1,5 +1,6 @@
|
||||
from django.db import models
|
||||
from datetime import date
|
||||
from django.utils.timezone import now
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@@ -8,6 +9,7 @@ class Page(models.Model):
|
||||
title=models.CharField(max_length=100)
|
||||
contents=models.TextField()
|
||||
last_edited=models.DateField(auto_now=True)
|
||||
renders=models.BooleanField(default=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
@@ -20,6 +22,9 @@ class Contact(models.Model):
|
||||
groups={0:'Preferred',1:'Suitable',2:'Discouraged',3:'Ignored',4:'Discontinued',5:'NSFW'}
|
||||
group=models.IntegerField(choices=list(groups.items()))
|
||||
priority=models.IntegerField()
|
||||
desktop=models.BooleanField(default=True)
|
||||
mobile=models.BooleanField(default=True)
|
||||
rel=models.BooleanField(default=False)
|
||||
|
||||
def save(self,*args,**kwargs):
|
||||
a,_=Update.objects.get_or_create(page='contact')
|
||||
@@ -32,4 +37,11 @@ class Contact(models.Model):
|
||||
|
||||
class Update(models.Model):
|
||||
page=models.CharField(max_length=100)
|
||||
date=models.DateField()
|
||||
date=models.DateField(default=now)
|
||||
|
||||
class Redirect(models.Model):
|
||||
match=models.CharField(max_length=200)
|
||||
output=models.CharField(max_length=500)
|
||||
|
||||
def __str__(self):
|
||||
return self.match
|
@@ -1,24 +1,34 @@
|
||||
Nettiquette and misc:
|
||||
Nettiquette:
|
||||
http://www.nohello.com
|
||||
https://nohello.net/
|
||||
https://sol.gfxile.net/dontask.html
|
||||
https://dontasktoask.com/
|
||||
http://slash7.com/2006/12/22/vampires/
|
||||
http://xyproblem.info/
|
||||
|
||||
Politicking:
|
||||
https://ncase.me/ballot
|
||||
https://digdeeper.neocities.org/ghost/email.html
|
||||
http://www.kanjidamage.com
|
||||
https://innermantheatre.com/2021/03/29/lightspeed-lab-homosexuality/,The Christian stance on homosexuality in 3 panels
|
||||
|
||||
Economics:
|
||||
https://archive.secondspring.co.uk/articles/borruso.htm
|
||||
|
||||
Computers and languages are hard:
|
||||
http://www.zompist.com/yingzi/yingzi.htm
|
||||
Computers are hard:
|
||||
https://gankra.github.io/blah/text-hates-you/
|
||||
https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
|
||||
https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time
|
||||
https://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time
|
||||
https://eev.ee/blog/2015/09/12/dark-corners-of-unicode/
|
||||
http://michael.orlitzky.com/articles/motherfuckers_need_package_management.xhtml
|
||||
https://idlewords.com/talks/website_obesity.htm
|
||||
https://digdeeper.club/articles/email.xhtml
|
||||
https://spyware.neocities.org/articles/brave.html,Computers are your enemy
|
||||
https://prose.sh/
|
||||
|
||||
Languages are hard:
|
||||
http://www.zompist.com/yingzi/yingzi.htm
|
||||
http://www.kanjidamage.com,The right way to learn kanji
|
||||
https://faculty.georgetown.edu/jod/texts/twain.german.html,Languages are angry
|
||||
|
||||
Otome! And maybe other game design:
|
||||
https://uguucageoflove.wordpress.com/2020/05/17/preferences-of-otome-gamers-a-survey-of-japanese-players/
|
||||
https://uguucageoflove.wordpress.com/2020/05/17/preferences-of-otome-gamers-a-survey-of-japanese-players/
|
||||
|
@@ -1,62 +0,0 @@
|
||||
Preferred:
|
||||
zergling@rakka.tk,Email,mailto:zergling@rakka.tk,TODO
|
||||
zergling_man@disroot.org,Email,mailto:zergling_man@disroot.org,Pending approval
|
||||
Zergling_man@pod.rakka.tk,Diaspora,,No idea what I'm doing with this yet.
|
||||
Zergling_man@rakka.tk,XMPP,xmpp:Zergling_man@rakka.tk,Not federating for some reason
|
||||
<a rel='me' href='https://birds.garden/Zergling_man'>@Zergling_man@birds.garden</a>,Pleroma/fediverse,,Migrated from linuxbox
|
||||
<a rel='me' href='https://mastodon.linuxbox.ninja/@Zergling_man'>@Zergling_man@mastodon.linuxbox.ninja</a>,Mastodon/fediverse
|
||||
|
||||
Suitable:
|
||||
zerglingman@fedora.email,Email,mailto:zerglingman@fedora.email
|
||||
zergling@email.go.brr.rakka.tk,Email,mailto:zergling@email.go.brr.rakka.tk,Backup account. <strong>Save this!</strong>
|
||||
My comment box,Web,/comment,TODO
|
||||
Zergling_man@irc.libera.chat,IRC
|
||||
Zergling_man@irc.rizon.net,IRC
|
||||
zerglingman,Steam,https://steamcommunity.com/id/zerglingman
|
||||
@Zerglingman@freespeechextremist.com,Pleroma/fediverse,https://freespeechextremist.com/Zerglingman
|
||||
@zergling.man:matrix.perthchat.org,Matrix,https://matrix.to/#/@zergling.man:matrix.perthchat.org,I kinda get it
|
||||
<a rel='me' href='https://mastodon.linuxbox.ninja/@Zergling_man'>@Zergling_man@mastodon.linuxbox.ninja</a>,Mastodon/fediverse,,To be repurposed
|
||||
|
||||
Discouraged:
|
||||
Zergling_man#9849,Discord
|
||||
zergling.man42@gmail.com,Email,mailto:zergling.man42@gmail.com
|
||||
Zergling_man@hotmail.com,Email,mailto:Zergling_man@hotmail.com
|
||||
Zergling_man@irc.chat.twitch.tv,IRC,,yes, IRC
|
||||
Wisknort@irc.mibbit.net,IRC
|
||||
Zergling_man@irc.freenode.net,IRC
|
||||
lazy to put,Codingame,,XMPP
|
||||
Zergling_man,Mangadex,https://mangadex.org/user/419664/zergling_man
|
||||
Wisknort,Favorite Words,https://favoritewords.com/public/7909804378
|
||||
Wisknort,Disqus,https://disqus.com/by/wisknort/
|
||||
<a rel='me' href='https://pawoo.net/@Zergling_man'>@Zergling_man@pawoo.net</a>,Mastodon/fediverse,,Mostly porn
|
||||
@zergling_man@peertube.linuxrocks.online,Peertube/fediverse,https://peertube.linuxrocks.online/accounts/zergling_man/
|
||||
zergling-man,Gitlab,https://gitlab.com/zergling-man
|
||||
Curtis Smith,Patreon,https://www.patreon.com/user/creators?u=688598,I don't actually create anything
|
||||
zergling-man,Github,https://github.com/zergling-man
|
||||
zergling_man,Bandcamp,https://bandcamp.com/zergling_man
|
||||
zerglingman,Facebook message,https://facebook.com/zerglingman
|
||||
|
||||
Ignored:
|
||||
Zergling_man,Kickstarter,https://www.kickstarter.com/profile/zerglingman
|
||||
04 7892 6251,Phone,tel:+61478926251
|
||||
04 7320 1329,Phone,tel:+61473201329
|
||||
Zerguch,Exhentai,,Don't search it if you don't know it
|
||||
zerglingman,Facebook,https://facebook.com/zerglingman
|
||||
@Zergling_man,Twitter,https://twitter.com/zergling_man
|
||||
Wisknort@useast.battle.net,Battlenet 1.0,,probably dead
|
||||
Wisknort@irc.gamesurge.net,IRC
|
||||
Zergling_man@irc.quakenet.org,IRC
|
||||
Zergling_man@irc.irchighway.net,IRC
|
||||
zergling.man42@gmail.com,Hangouts
|
||||
<a href='https://en.wikipedia.org/wiki/NakNak'>naknak</a>210,Neopets
|
||||
zergling_man,Gelbooru,https://gelbooru.com/index.php?page=account&s=profile&id=286243,Content warning for site, not for kids
|
||||
Zergling_man,XDA,https://forum.xda-developers.com/member.php?u=5421902,
|
||||
@zergling_man,Ello,https://ello.co/zergling_man
|
||||
zergling_man@hotmail.com,Skype
|
||||
Curtis Smith,Linkedin,https://www.linkedin.com/in/curtis-smith-615538205/
|
||||
|
||||
Discontinued:
|
||||
<a rel='me' href='https://openweb.social/@Zergling_man'>@Zergling_man@openweb.social</a>,Mastodon/fediverse,,Instance died
|
||||
Zerglingman,Xfire,,Rip btw
|
||||
<a rel='me' href='https://social.quodverum.com/@Zergling_man'>@Zergling_man@social.quodverum.com</a>,Mastodon/fediverse,,Banned, no reason given. Quods is weird.
|
||||
e1ff7b086b591c3bdc7cf74ffc46c38a023721c8386e46cf63ed3d7998020c6240d786bfa8a8,Tox
|
@@ -1,10 +1,20 @@
|
||||
<audio controls><source src='https://invidious.ethibox.fr/latest_version?id={0}&itag=140'/>ababababa</audio>
|
||||
<p>Rakka me takkas and riddly me diddlies.</p>
|
||||
<p>Welcome back, Ike. Farewell, Sly.</p><br/>
|
||||
<p>This site is hosted in Tasmania, AU, by zerglingman (a fedora.email user), a Van Canto fan<del>girl</del> boy. Also available on matrix as @zergling.man:matrix.perthchat.org, or on libera.chat as Zergling_man or Mastodon as <a rel='me' href='https://mastodon.linuxbox.ninja/@Zergling_man'>@Zergling_man@mastodon.linuxbox.ninja</a> (<a href='/contact.php'>and many other places</a>). <br/><a href='/me'>But who am I, really?</a></p>
|
||||
<p>Who <del>can't figure out how SSL works. I'm working on it. got SSL working, I guess.</del> is figuring this SSL thing out, properly.</p>
|
||||
<p><a href='/webhost.php'>Haha I'm way too lazy for webhosting</a></p>
|
||||
<p>This site is hosted in Tasmania, AU, by zerglingman (a fedora.email user), a Van Canto fan<del>girl</del> boy. Also available on matrix as <a href="https://matrix.to/#/@zergling.man:perthchat.org">@zergling.man:perthchat.org</a>, or on libera.chat as Zergling_man or fedi (inc. mastodon) as <a rel='me' href='https://birds.garden/@Zergling_man'>@Zergling_man@birds.garden</a> (<a href='/contact'>and many other places</a>). <br/><a href='/me'>But who am I, really?</a></p>
|
||||
<p>Who <del>can't figure out how SSL works. I'm working on it. got SSL working, I guess. is figuring this SSL thing out, properly.</del> is thinking about eliminating CAs.</p>
|
||||
<p><a href='/webhost'>Haha I'm way too lazy for webhosting</a></p>
|
||||
<p>Cool games: <a href='http://www.fantasystrike.com'>Fantasy Strike</a> (<strong>gone free! Go play it now!</strong>), <a href='http://www.soldak.com/Dins-Curse/Overview.html'>Din's Curse</a> (dirt cheap!), <a href='https://mwomercs.com/'>Mechwarrior Online</a> (free!), <a href='https://www.wurmonline.com/'>Wurm Online</a> (free!), <a href='https://www.chiark.greenend.org.uk/~sgtatham/puzzles/'>Portable Puzzle Collection</a> (free and open source! Also on <a href='https://f-droid.org/en/packages/name.boyle.chris.sgtpuzzles/'>android</a>!)</p>
|
||||
<p>Cool bands: <a href='https://vancanto.de/en'>Van Canto</a> [<a href='https://vancanto.bandcamp.com/'>bandcamp</a>] (who this site is a shrine to), <a href='https://theocracymusic.com/'>Theocracy</a> [<a href='https://ulteriumrecords.bandcamp.com/'>label's bandcamp</a>] (Christian prog metal!), <a href='https://teramaze.com.au/'>Teramaze</a> [<a href='https://teramaze.bandcamp.com/'>bandcamp</a>] (Australian Christian prog metal!)
|
||||
<p>Cool bands: <a href='https://vancanto.de/en'>Van Canto</a> [<a href='https://vancanto.bandcamp.com/'>bandcamp</a>] (Who this site is a shrine to!), <a href='https://theocracymusic.com/'>Theocracy</a> [<a href='https://ulteriumrecords.bandcamp.com/'>label's bandcamp</a>] (Christian prog metal!), <a href='https://teramaze.com.au/'>Teramaze</a> [<a href='https://teramaze.bandcamp.com/'>bandcamp</a>] (Australian Christian prog metal! Always releasing!), Takamachi Walk [<a href='https://takamachiwalk.bandcamp.com/'>bandcamp</a>] (Touhou metal! New album out NYE 2021!)
|
||||
<p><del><a href='https://www.bigr.com/whisker-snot-arrow-rest-weatherproofing/208374.html'>Wisknort. Whisker snot.</a></del> They changed their website and now it sucks.</p>
|
||||
<p>By the way, my site's now <a href='https://gitea.rakka.tk/Zergling_man/rakkapy'>open source</a>, so you can see exactly how shit I am at this.</p>
|
||||
<p>By the way, my site's now <a href='https://gitea.rakka.tk/Zergling_man/rakkapy'>open source</a>, so you can see exactly how shit I am at this.</p>
|
||||
|
||||
<h4>Notices:</h4>
|
||||
<ul>
|
||||
<li>2022 Nov 8th: False alarm, I just needed to restart the DB.</li>
|
||||
<li>2022 Nov 7th: Database access is fucked, I don't know why, but large parts of my site will be inaccessible as a result (including, annoyingly, the contact page). I will probably redo the whole thing as a static site instead of trying to fix it.</li>
|
||||
<li>2022 Apr 5th: I think I've figured out what was causing constant dropouts, uptime should be back to >99%.</li>
|
||||
<li>2022 Mar 27th: Oh yeah I found those other things. One is now at <a href="https://rakka.tk/r/support">https://rakka.tk/r/support</a>, the other is <a href="https://bae.st/media/38f1485d-a6bd-4b30-a409-0d9e75f22d19/bf313a3566fc2ada.png">here</a></li>
|
||||
<li>2022 Feb 15th: Here are some links for a certain person I was speaking to. Actually a couple of people. <a href='https://mangadex.org/manga/c6a51a13-74fd-46bd-989e-5cdaa26542f6'>Hero BBS</a>, parodying isekai before isekai was big. I still haven't found the other things I mentioned.</li>
|
||||
<li>2022 Feb 9th: Someone discovered that my ftp server was externally accessible and allowed anonymous writes and edits. Unfortunately I am too incompetent to have had it logging properly so I didn't get their IP, sad! Still, I feel special. Now I know I've made it.</li>
|
||||
</ul>
|
||||
|
@@ -1,20 +0,0 @@
|
||||
adobe: https://www.patreon.com/posts/26834357
|
||||
faplog: https://docs.google.com/spreadsheets/d/1sIh5evj1Janf_fdefbrksGLyHO_uMMDOjHJReA0P0fw/edit
|
||||
fpdam: https://docs.google.com/document/d/1XSKSC9PYxAE1ys2u5ALD3wDBaps6LQgGe-GtyAju3q8/edit?usp=sharing
|
||||
fpdb: https://docs.google.com/spreadsheets/d/1iJd8dBMbAKfwbfcWNnE-tElu4amJdtz4iMxWCxwKNY8/edit
|
||||
fuckmeyourself: https://gelbooru.com/index.php?page=post&s=view&id=4608040
|
||||
hitspark: https://images.squarespace-cdn.com/content/v1/5728734545bf2166bba67b00/1538785588130-I8WVGV947EEW81LII25S/ke17ZwdGBToddI8pDm48kODKEPcE7oOaZ-HX_UAJexAUqsxRUqqbr1mOJYKfIPR7LoDQ9mXPOjoJoqy81S2I8N_N4V1vUb5AoIIIbLZhVYy7Mythp_T-mtop-vrsUOmeInPi9iDjx9w8K4ZfjXt2dhV8WLpqAVTw2_ZfbaHHLLR7LAwPhjFlJ4O4wogcebl8m7cT0R_dexc_UL_zbpz6JQ/frame_advantage_5up.jpg?format=1000w
|
||||
homo: https://innermantheatre.files.wordpress.com/2020/11/lightspeed-lab-ep.261-homosexuality.jpg
|
||||
homo/s: https://innermantheatre.com/2021/03/29/lightspeed-lab-homosexuality/
|
||||
nadeko: https://docs.google.com/spreadsheets/d/12ZpOI3coZHlSFQ7oFuo1HzbkTkgX8RBk06oeMM56HFQ/edit#gid=0
|
||||
nlship: https://docs.google.com/document/d/1oVZSv7v8cePVu22qmbgkCUtm9LnUcSZIaQyH-3b_DhI/edit?usp=sharing
|
||||
nlvn: https://docs.google.com/document/d/1tVVI2NAY_1vFLsMrbRzn18FiXNzZcDgdxnNXKHEFzTs/edit#
|
||||
osscans: https://discord.gg/VStXkfm
|
||||
ossd: https://drive.google.com/drive/folders/14xIZJER551zEB9rP9d655MdpRE0xDBW8
|
||||
perm: http://nadekobot.readthedocs.io/en/latest/Permissions%20System/
|
||||
rinbot: https://discordapp.com/oauth2/authorize?client_id=448458599673364481&scope=bot
|
||||
sauce: https://discord.gg/gsUT8B
|
||||
spook: https://rakka.tk/pics/SPOOKY/SCARY/SKELETONS/SEND/SHIVERS/DOWN/YOUR/SPINE/SHRIEKING/SKULLS/WILL/SHOCK/YOUR/SOUL/SEAL/YOUR/DOOM/TONIGHT/SPOOKY/SCARY/SKELETONS/SPEAK/WITH/SUCH/A/SCREECH/YOU'LL/SHAKE/AND/SHUDDER/IN/SURPRISE/WHEN/YOU/HEAR/THESE/ZOMBIES/SHRIEK/WE'RE/SO/SORRY/SKELETONS/YOU'RE/SO/MISUNDERSTOOD/YOU/ONLY/WANT/TO/SOCIALIZE/BUT/I/DON'T/THINK/WE/SHOULD/CAUSE_SPOOKY_SCARY_SKELETONS_SHOUT_STARTLING_SHRILLY_SCREAMS.gif
|
||||
wou: https://discord.gg/8sc5m6R
|
||||
WushuAT: https://docs.google.com/document/d/1wtJ6JCpmpr-ziAb0UR0OpW1tX7Ms5CiDFUQkjPgFzIE/edit?usp=drive_web&ouid=102857329945830311247
|
||||
years: https://docs.google.com/spreadsheets/d/1p7NIoC2-o8BJvbLD5N1WazaFAtw4vto7bxJMGsarcgE/edit
|
@@ -5,12 +5,25 @@
|
||||
<title>
|
||||
Tas [] & Van Canto - {{ title }}
|
||||
</title>
|
||||
<script type="text/javascript">
|
||||
function b(){
|
||||
a=document.body.innerHTML
|
||||
document.body.innerHTML = '<main><p>Please disable JavaScript to view this site.</p><p><a href="/javashit">Why?</a> <a href="https://www.wikihow.com/Disable-JavaScript">How?</a></p><p id="tock" class="tick">Or wait <n id="tick">3</n> seconds...</p></main>'
|
||||
function t1(){document.getElementById('tick').textContent=2}
|
||||
function t2(){document.getElementById('tick').textContent=1}
|
||||
function c(){console.log("fucking normie"); document.body.innerHTML=a}
|
||||
window.setTimeout(t1,1000)
|
||||
window.setTimeout(t2,2000)
|
||||
window.setTimeout(c,3000)
|
||||
}
|
||||
</script><!--Need to add a timer to remove it first. I'm not *that* mean. Credit: https://soc.punktrash.club/objects/bfe4fc29-96d5-4f90-9f9e-4092e7c273a4-->
|
||||
</head>
|
||||
<body>
|
||||
{{ nav }}
|
||||
<body onload=b()>
|
||||
<!--Move navbar to the bottom and use flex to reorder it to the top, so it isn't as intrusive without CSS.-->
|
||||
<main>
|
||||
{% autoescape off %}{{ content }}{% endautoescape %}
|
||||
</main>
|
||||
<p class="foot">Page last updated {{ date }}</p>
|
||||
{{ nav }}
|
||||
</body>
|
||||
</html>
|
13
main/urls.py
13
main/urls.py
@@ -1,16 +1,19 @@
|
||||
from django.urls import path, re_path, include
|
||||
from . import views
|
||||
from django.urls import path, register_converter
|
||||
from . import views,converters
|
||||
|
||||
register_converter(converters.AutoPageConverter,'autopage')
|
||||
register_converter(converters.RedirectConverter,'redirect')
|
||||
|
||||
urlpatterns=[
|
||||
path('',views.index,name='idex'),
|
||||
path('contact',views.contact,name='contact'),
|
||||
path('comment',views.comment,name='shoutbox'),
|
||||
path('specs',views.specs,name='specs'),
|
||||
path('songs',views.songs,name='songs'),
|
||||
path('nerdshope',views.nerdshope,name='shop'),
|
||||
path('teapot',views.teapot,name='teapot'),
|
||||
path('toask',views.articles,name='articles'),
|
||||
re_path('r/(.*)',views.redirect,name='redirect'),
|
||||
path('r/<redirect:src>',views.redirect,name='redirect'),
|
||||
path('md.rss',views.md,name='md'),
|
||||
path('me.vcf',views.vcard,name='vcard'),
|
||||
re_path('(.*)',views.autopage,name='everything'),
|
||||
path('<autopage:page>',views.autopage,name='everything'),
|
||||
]
|
@@ -4,9 +4,10 @@ syntax,/syntax,Syntaxer,2
|
||||
todo,/todos,Todos,0
|
||||
pics,/pics,Pics,2
|
||||
wargame,https://gitlab.com/zergling-man/Wargamer,Wargamer,0
|
||||
rinbot,/r/rinbot,Rinbot,0
|
||||
rinbot,/r/rinbot,Rinbot,2
|
||||
survey,/emojisurvey.php,Survey,2
|
||||
myroids,/myroids,Myroids,0
|
||||
bot,/bot,Bot chat,2
|
||||
articles,/toask,Articles,0
|
||||
contact,/contact,Contact,1
|
||||
contact,/contact,Contact,1
|
||||
shope,/nerdshope,Nerds' Hope,0
|
@@ -1,50 +1,10 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
import random as ra
|
||||
import asyncio
|
||||
from . import mdl
|
||||
from .models import Page,Contact,Update
|
||||
from .models import Page,Contact,Update,Redirect
|
||||
|
||||
import functools
|
||||
|
||||
def rerender(funky):
|
||||
@functools.wraps(funky)
|
||||
def wrap(req,*args,**kwargs):
|
||||
with open('main/utils/navs') as b:
|
||||
navs=parsecat(b,4)
|
||||
namednavs=[{'id':blah[0], 'link':blah[1], 'text':blah[2], 'align':int(blah[3])} for blah in navs['']]
|
||||
out=funky(*args,**kwargs)
|
||||
temp=loader.get_template('main/nav.html')
|
||||
out['nav']=temp.render({"navs":namednavs},None)
|
||||
return render(req, 'main/temp.html', out)
|
||||
return wrap
|
||||
|
||||
def parsecat(file,n):
|
||||
if not isinstance(file,str):
|
||||
# Assume open handle
|
||||
stuff=file.read()
|
||||
else:
|
||||
with open(f'main/pages/{file}') as b:
|
||||
stuff=b.read()
|
||||
cats=stuff.split('\n\n')
|
||||
out={}
|
||||
head=''
|
||||
out['']=[]
|
||||
for cat in cats:
|
||||
if ':' in cat[:cat.index('\n')]:
|
||||
# We have a category name
|
||||
head,cat=cat.split('\n',1)
|
||||
head=head[:-1]
|
||||
out[head]=[]
|
||||
else: head=''
|
||||
for line in cat.split('\n'):
|
||||
lin=line.split(',',n-1)
|
||||
pad=n-len(lin)
|
||||
lin.extend(['']*pad)
|
||||
out[head].append(lin)
|
||||
if out['']==[]: del(out[''])
|
||||
return out
|
||||
from rakka.utils import rerender,parsecat
|
||||
|
||||
@rerender
|
||||
def index():
|
||||
@@ -54,17 +14,21 @@ def index():
|
||||
raws=b.read()
|
||||
ids=raws.split('\n')
|
||||
stuff=stuff.format(ra.choice(ids))
|
||||
return {'title':'Home','content':stuff,'date':'2021/12/15'}
|
||||
return {'title':'Home','content':stuff,'date':'2022/02/09'}
|
||||
|
||||
def lii(obj):
|
||||
def lii(obj): # This will get moved to a template shortly
|
||||
name=obj.name
|
||||
if obj.url: name=f"<a href='{obj.url}'>{name}</a>"
|
||||
relme="rel='me' " if obj.rel else ''
|
||||
if obj.url: name=f"<a {relme}href='{obj.url}'>{name}</a>"
|
||||
if obj.comment: name=f"{name} ({obj.comment})"
|
||||
if obj.desktop: name=f"{name} 🖥"
|
||||
if obj.mobile: name=f"{name} 📱"
|
||||
return f"<li>{obj.proto}: {name}</li>"
|
||||
|
||||
@rerender
|
||||
def contact():
|
||||
head="Certain people keep asking me about the best ways to contact me. So here they are, in rough order of most to least preferred. More to come as I remember them/feel like it<br/>"
|
||||
head="""Certain people keep asking me about the best ways to contact me. So here they are, in rough order of most to least preferred. More to come as I remember them/feel like it<br/>
|
||||
🖥 = I will receive on my computer, 📱 = I will receive on my phone<br/>"""
|
||||
contacts=sorted(Contact.objects.all(),key=lambda x:(x.group,x.priority))
|
||||
out={}
|
||||
for n in contacts:
|
||||
@@ -76,12 +40,16 @@ def contact():
|
||||
out2+='\n'.join(map(lii,v))
|
||||
out2+="\n</ul></p>"
|
||||
out3+=out2
|
||||
return {'title':'Contact','content':head+out3,'date':Update.objects.get(page='contact').date}
|
||||
return {'title':'Contact','content':head+out3,'date':Update.objects.get_or_create(page='contact')[0].date}
|
||||
|
||||
def specs(req):
|
||||
with open('main/pages/specs') as b:
|
||||
return HttpResponse(b.read(), content_type="text/plain")
|
||||
|
||||
@rerender
|
||||
def comment():
|
||||
return {'title':'Comment box','content':"TODO",'date':'2021/12/24'}
|
||||
|
||||
@rerender
|
||||
def songs():
|
||||
with open('main/utils/song-ids') as b:
|
||||
@@ -90,10 +58,6 @@ def songs():
|
||||
out='This is the full list of songs that can appear on the home page.<br/>'+'<br/>\n'.join([f'<a href="https://invidious.ethibox.fr/watch?v={idd}">https://invidious.ethibox.fr/watch?v={idd}</a>' for idd in ids])
|
||||
return {'title':'Songs','content':out,'date':'2021/05/06'}
|
||||
|
||||
@rerender
|
||||
def nerdshope():
|
||||
return {'title':'Nerds\' Hope','content':"Store stuff. TODO. Will include inventory and budget. <a href='https://facebook.com/nerdshope'>FB</a><br/>Address is 21 Kensington St, Glenorchy<br/>Off dates 2021: 24th Sept, 29th Oct, 26th Nov<br/>Will be late on the 1st of Oct<br/>Not sure about 31st of Dec. Depends what other plans are made. I might host a NYE party that night.",'date':'2021/09/05'}
|
||||
|
||||
def teapot(req):
|
||||
return HttpResponse("You're probably missing the joke.",status=418)
|
||||
|
||||
@@ -103,18 +67,21 @@ def articles():
|
||||
arts=parsecat('articles',2)
|
||||
out=[]
|
||||
for k,v in arts.items():
|
||||
out.append(f'<h4>{k}</h4>'+ '<br/>'.join([f'<a href="{l[0]}">{l[1] or l[0]}</a>' for l in v]))
|
||||
return {'title':'Articles','content':'<p>'+('</p><p>'.join(out))+'</p>','date':'2021/05/06'}
|
||||
out.append(f'<h4>{k}</h4>\n'+ '<br/>\n'.join([f'<a href="{l[0]}">{l[1] or l[0]}</a>' for l in v]))
|
||||
return {'title':'Articles','content':'<p>'+('</p>\n<p>'.join(out))+'</p>','date':'2022/07/25'}
|
||||
|
||||
def redirect(req,src):
|
||||
with open('main/pages/redirects') as b:
|
||||
lonks=b.read()
|
||||
lonks=dict([n.split(': ',1) for n in lonks.split('\n')])
|
||||
return HttpResponse(status=302,headers={'Location':lonks[src]})
|
||||
return HttpResponse(status=302,headers={'Location':src.output})
|
||||
|
||||
@rerender
|
||||
def mdhelp():
|
||||
return {'title':'How2MD RSS','date':'2022/05/27','content':"This is an <a href='https://en.wikipedia.org/wiki/RSS'>RSS</a> service for <a href='https://mangadex.org'>Mangadex</a>, since they had one in v3 that I made liberal use of, and I've heard nothing regarding its return in v5.<br/>If you've never used RSS before, I strongly recommend starting, as it's the second-best update notification system in existence (and it could be built on #1, push notifications, but that's an another topic).<br/>You will need an RSS reader program, but your browser probably has one built in, so you can just use that. (I don't recommend it, because you should be closing the browser more, not less.)<br/>The important part of an RSS feed is a source URL. If properly configured, that should provide everything else. In this case, you've already found the source URL... Kinda. You need to pass a manga ID (or several) to make it work. A manga ID looks like this: ed996855-70de-449f-bba2-e8e24224c14d (yes, that's a UUID4). If you go to a manga's page on Mangadex, you should see something like it in the URL bar at the top. I think Tachiyomi has some way to grab it, but I also think Tachi's update notifs are better than mine, so if you have that you don't need this.<br/>Once you have the ID(s), you should palm them into this page like this: <a href='/md.rss?ids=ed996855-70de-449f-bba2-e8e24224c14d'>https://rakka.tk/md.rss?ids=ed996855-70de-449f-bba2-e8e24224c14d</a>. Take that and give it to your RSS reader as a new feed and it should handle the rest (did your browser ask you a new question when you clicked it?). If you want more IDs, put an & and do it again: <a href='/md.rss?ids=ed996855-70de-449f-bba2-e8e24224c14d&ids=/d032cdeb-1ced-4031-8b9e-45e6064c1781'>https://rakka.tk/md.rss?ids=ed996855-70de-449f-bba2-e8e24224c14d&ids=d032cdeb-1ced-4031-8b9e-45e6064c1781</a>.<br/>It behaves a bit differently with 1 ID vs multiple, but it should work alright both ways. Personally I prefer making one feed for each series."}
|
||||
|
||||
def md(req):
|
||||
ids=req.GET.getlist('ids','')
|
||||
if not ids: return mdhelp(req)
|
||||
loop=asyncio.get_event_loop()
|
||||
feed=loop.run_until_complete(mdl.makefeed(req.GET.getlist('ids','')))
|
||||
feed=loop.run_until_complete(mdl.makefeed(ids))
|
||||
return HttpResponse(feed, content_type='application/rss+xml')
|
||||
|
||||
def vcard(req):
|
||||
@@ -132,5 +99,4 @@ END:VCARD""")
|
||||
|
||||
@rerender
|
||||
def autopage(page):
|
||||
p=Page.objects.get(url=page)
|
||||
return {'title':p.title,'content':p.contents,'date':p.last_edited}
|
||||
return {'title':page.title,'content':page.contents,'date':page.last_edited}
|
0
nerdshope/__init__.py
Normal file
0
nerdshope/__init__.py
Normal file
8
nerdshope/admin.py
Normal file
8
nerdshope/admin.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
||||
from .models import BankAccount,Payment,OffDate
|
||||
admin.site.register(BankAccount)
|
||||
admin.site.register(Payment)
|
||||
admin.site.register(OffDate)
|
6
nerdshope/apps.py
Normal file
6
nerdshope/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class NerdshopeConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'nerdshope'
|
30
nerdshope/models.py
Normal file
30
nerdshope/models.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from django.db import models
|
||||
from django.utils.timezone import now
|
||||
|
||||
# Create your models here.
|
||||
class BankAccount(models.Model):
|
||||
name=models.CharField(max_length=100)
|
||||
physical=models.CharField(max_length=100)
|
||||
currency=models.CharField(max_length=5)
|
||||
@property
|
||||
def balance(self): return sum(map(lambda x:x.amount,Payment.objects.filter(account=self)))
|
||||
|
||||
def __str__(self):
|
||||
return str(self.name)+', '+str(self.balance)
|
||||
|
||||
class Payment(models.Model):
|
||||
timestamp=models.DateTimeField(default=now)
|
||||
other_party=models.CharField(max_length=100)
|
||||
account=models.ForeignKey(BankAccount, on_delete=models.CASCADE)
|
||||
amount=models.IntegerField(default=0)
|
||||
reason=models.CharField(max_length=200)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.timestamp)+', '+str(self.amount)+', '+str(self.reason)
|
||||
|
||||
class OffDate(models.Model):
|
||||
when=models.DateField(default=now)
|
||||
reason=models.CharField(max_length=50,default="Hall unavailable")
|
||||
|
||||
def __str__(self):
|
||||
return str(str.when)+': '+str(self.reason)
|
3
nerdshope/tests.py
Normal file
3
nerdshope/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
6
nerdshope/urls.py
Normal file
6
nerdshope/urls.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.urls import include, path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('',views.nerdshope,name='shop'),
|
||||
]
|
16
nerdshope/views.py
Normal file
16
nerdshope/views.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.shortcuts import render
|
||||
from rakka.utils import rerender
|
||||
from . import models
|
||||
from main.models import Update
|
||||
|
||||
@rerender
|
||||
def nerdshope():
|
||||
accounts=models.BankAccount.objects.all()
|
||||
sums={curr:sum([n.balance for n in filter(lambda x:x.currency==curr,accounts)]) for curr in set(map(lambda x:x.currency,accounts))}
|
||||
moneyblob='</li>\n<li>'.join([f'{k}: {v}' for k,v in sums.items()])
|
||||
moneyblob='Current monetary state: <ul>\n<li>'+moneyblob+'</li>\n</ul>'
|
||||
return {'title':"Nerds' Hope",'content':"Store stuff. TODOing. Will include inventory and budget. <a href='https://facebook.com/nerdshope'>FB</a><br/>\nAddress is 21 Kensington St, Glenorchy<br/>\nThe store isn't open when other events happen on Fridays, usually the last Friday of each month. Additionally, on the first and third weeks of each month the store will move around the back (through the gate) around 18:00 to make room for a youth group. If in doubt, ask the youth group for directions.<br/>\nFull list of dates:\n<ol><li>16th Sept - round the back later</li>\n<li>30th Sept - closed</li>\n<li>21st Oct - round the back later</li>\n<li>28th Oct - closed</li>\n<li>4th Nov - round the back later</li>\n<li>18th Nov - round the back later</li>\n<li>25th Nov - closed</li>\n<li>2nd Dec - round the back later</li>\n<li>16th Dec - round the back later</li>\n<li>30th Dec - maybe party</li></ol>\n"+moneyblob,'date':Update.objects.get_or_create(page='nh_main')[0].date}
|
||||
|
||||
@rerender
|
||||
def budget():
|
||||
pass
|
133
rakka/UncommonMiddleware.py
Normal file
133
rakka/UncommonMiddleware.py
Normal file
@@ -0,0 +1,133 @@
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import HttpResponsePermanentRedirect
|
||||
from django.urls import is_valid_path
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.utils.http import escape_leading_slashes
|
||||
|
||||
class UnCommonMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
Lol, common
|
||||
"""
|
||||
|
||||
response_redirect_class = HttpResponsePermanentRedirect
|
||||
|
||||
def process_request(self, request):
|
||||
"""
|
||||
Check for denied User-Agents and rewrite the URL based on
|
||||
settings.APPEND_SLASH and settings.PREPEND_WWW
|
||||
"""
|
||||
|
||||
# Check for denied User-Agents
|
||||
user_agent = request.META.get('HTTP_USER_AGENT')
|
||||
if user_agent is not None:
|
||||
for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
|
||||
if user_agent_regex.search(user_agent):
|
||||
raise PermissionDenied('Forbidden user agent')
|
||||
|
||||
# Check for a redirect based on settings.PREPEND_WWW
|
||||
host = request.get_host()
|
||||
must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
|
||||
redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''
|
||||
|
||||
# Check if a slash should be appended or removed
|
||||
if self.should_redirect_with_slash(request):
|
||||
path = self.get_full_path_with_slash(request)
|
||||
elif self.should_redirect_without_slash(request):
|
||||
path = self.get_full_path_without_slash(request)
|
||||
else:
|
||||
path = request.get_full_path()
|
||||
|
||||
# Return a redirect if necessary
|
||||
if redirect_url or path != request.get_full_path():
|
||||
redirect_url += path
|
||||
return self.response_redirect_class(redirect_url)
|
||||
|
||||
def should_redirect_with_slash(self, request):
|
||||
"""
|
||||
Return True if settings.APPEND_SLASH is True and appending a slash to
|
||||
the request path turns an invalid path into a valid one.
|
||||
"""
|
||||
if settings.APPEND_SLASH and not request.path_info.endswith('/'):
|
||||
urlconf = getattr(request, 'urlconf', None)
|
||||
if not is_valid_path(request.path_info, urlconf):
|
||||
match = is_valid_path('%s/' % request.path_info, urlconf)
|
||||
if match:
|
||||
view = match.func
|
||||
return getattr(view, 'should_append_slash', True)
|
||||
return False
|
||||
|
||||
def get_full_path_with_slash(self, request):
|
||||
"""
|
||||
Return the full path of the request with a trailing slash appended.
|
||||
|
||||
Raise a RuntimeError if settings.DEBUG is True and request.method is
|
||||
POST, PUT, or PATCH.
|
||||
"""
|
||||
new_path = request.get_full_path(force_append_slash=True)
|
||||
# Prevent construction of scheme relative urls.
|
||||
new_path = escape_leading_slashes(new_path)
|
||||
if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):
|
||||
raise RuntimeError(
|
||||
"You called this URL via %(method)s, but the URL doesn't end "
|
||||
"in a slash and you have APPEND_SLASH set. Django can't "
|
||||
"redirect to the slash URL while maintaining %(method)s data. "
|
||||
"Change your form to point to %(url)s (note the trailing "
|
||||
"slash), or set APPEND_SLASH=False in your Django settings." % {
|
||||
'method': request.method,
|
||||
'url': request.get_host() + new_path,
|
||||
}
|
||||
)
|
||||
return new_path
|
||||
|
||||
def should_redirect_without_slash(self, request):
|
||||
"""
|
||||
Removing slashes, of course
|
||||
"""
|
||||
if settings.REMOVE_SLASH and request.path_info.endswith('/'):
|
||||
urlconf = getattr(request, 'urlconf', None)
|
||||
if not is_valid_path(request.path_info, urlconf):
|
||||
match = is_valid_path('%s' % request.path_info[:-1], urlconf)
|
||||
if match:
|
||||
view = match.func
|
||||
return getattr(view, 'should_remove_slash', True)
|
||||
return False
|
||||
|
||||
def get_full_path_without_slash(self, request):
|
||||
"""
|
||||
z
|
||||
"""
|
||||
new_path = request.get_full_path(force_append_slash=True)[:-1]
|
||||
# Prevent construction of scheme relative urls.
|
||||
new_path = escape_leading_slashes(new_path)
|
||||
if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):
|
||||
raise RuntimeError(
|
||||
"You called this URL via %(method)s, but the URL doesn't end "
|
||||
"in a slash and you have APPEND_SLASH set. Django can't "
|
||||
"redirect to the slash URL while maintaining %(method)s data. "
|
||||
"Change your form to point to %(url)s (note the trailing "
|
||||
"slash), or set APPEND_SLASH=False in your Django settings." % {
|
||||
'method': request.method,
|
||||
'url': request.get_host() + new_path,
|
||||
}
|
||||
)
|
||||
return new_path
|
||||
|
||||
def process_response(self, request, response):
|
||||
"""
|
||||
When the status code of the response is 404, it may redirect to a path
|
||||
with an appended slash if should_redirect_with_slash() returns True.
|
||||
"""
|
||||
# If the given URL is "Not Found", then check if we should redirect to
|
||||
# a path with a slash appended.
|
||||
if response.status_code == 404 and self.should_redirect_with_slash(request):
|
||||
return self.response_redirect_class(self.get_full_path_with_slash(request))
|
||||
if response.status_code == 404 and self.should_redirect_without_slash(request):
|
||||
return self.response_redirect_class(self.get_full_path_without_slash(request))
|
||||
|
||||
# Add the Content-Length header to non-streaming responses if not
|
||||
# already set.
|
||||
if not response.streaming and not response.has_header('Content-Length'):
|
||||
response.headers['Content-Length'] = str(len(response.content))
|
||||
|
||||
return response
|
@@ -35,6 +35,7 @@ ALLOWED_HOSTS = [n.strip() for n in conf['ALLOWED_HOSTS'].split(',')]
|
||||
INSTALLED_APPS = [
|
||||
'main.apps.MainConfig',
|
||||
'books.apps.BooksConfig',
|
||||
'nerdshope.apps.NerdshopeConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
@@ -46,7 +47,7 @@ INSTALLED_APPS = [
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'rakka.UncommonMiddleware.UnCommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
@@ -104,6 +105,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
},
|
||||
]
|
||||
|
||||
REMOVE_SLASH=True
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
||||
|
@@ -20,5 +20,7 @@ from . import views
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('books/',include('books.urls')),
|
||||
path('comment/',include('comment.urls')),
|
||||
path('nerdshope/',include('nerdshope.urls')),
|
||||
path('', include('main.urls')),
|
||||
]
|
||||
|
41
rakka/utils.py
Normal file
41
rakka/utils.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from django.shortcuts import render
|
||||
from django.template import loader
|
||||
import functools
|
||||
|
||||
def rerender(funky):
|
||||
@functools.wraps(funky)
|
||||
def wrap(req,*args,**kwargs):
|
||||
with open('main/utils/navs') as b:
|
||||
navs=parsecat(b,4)
|
||||
namednavs=[{'id':blah[0], 'link':blah[1], 'text':blah[2], 'align':int(blah[3])} for blah in navs['']]
|
||||
out=funky(*args,**kwargs)
|
||||
temp=loader.get_template('main/nav.html')
|
||||
out['nav']=temp.render({"navs":namednavs},None)
|
||||
return render(req, 'main/temp.html', out)
|
||||
return wrap
|
||||
|
||||
def parsecat(file,n):
|
||||
if not isinstance(file,str):
|
||||
# Assume open handle
|
||||
stuff=file.read()
|
||||
else:
|
||||
with open(f'main/pages/{file}') as b:
|
||||
stuff=b.read()
|
||||
cats=stuff.split('\n\n')
|
||||
out={}
|
||||
head=''
|
||||
out['']=[]
|
||||
for cat in cats:
|
||||
if ':' in cat[:cat.index('\n')]:
|
||||
# We have a category name
|
||||
head,cat=cat.split('\n',1)
|
||||
head=head[:-1]
|
||||
out[head]=[]
|
||||
else: head=''
|
||||
for line in cat.split('\n'):
|
||||
lin=line.split(',',n-1)
|
||||
pad=n-len(lin)
|
||||
lin.extend(['']*pad)
|
||||
out[head].append(lin)
|
||||
if out['']==[]: del(out[''])
|
||||
return out
|
@@ -5,6 +5,11 @@ body
|
||||
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
/*Move navbar to the bottom and use flex to reorder it to the top, so it isn't as intrusive without CSS.
|
||||
Thanks to @heftig:archlinux.org (matrix) for showing me this.*/
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
nav
|
||||
@@ -21,6 +26,7 @@ nav
|
||||
display: inline-block;
|
||||
|
||||
background-color: #9999ff;
|
||||
order: 1; /*flex thing*/
|
||||
}
|
||||
|
||||
main
|
||||
@@ -41,6 +47,7 @@ main
|
||||
margin-right: auto;
|
||||
border: 2px solid;
|
||||
text-align: center;
|
||||
order: 2; /*flex thing*/
|
||||
}
|
||||
|
||||
main *
|
||||
@@ -64,7 +71,7 @@ li.navpiece
|
||||
position:relative;
|
||||
}
|
||||
|
||||
a.navpiece, div.navpiece
|
||||
a.navpiece/*, div.navpiece Apparently this wasn't doing anything either.*/
|
||||
{
|
||||
text-decoration-line:none;
|
||||
display: table-cell;
|
||||
@@ -123,7 +130,13 @@ h1
|
||||
background-color: #cccccc;
|
||||
float: right;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-right: 0; /* Need to set this for flex thing*/
|
||||
border: 2px solid;
|
||||
text-align: center;
|
||||
order: 3; /*flex thing*/
|
||||
}
|
||||
|
||||
.tick
|
||||
{
|
||||
color: #dddddd;
|
||||
}
|
Reference in New Issue
Block a user