Start restructuring web presences

This commit is contained in:
Griatch 2021-05-16 15:34:51 +02:00
parent 98a200533f
commit dac2be3074
92 changed files with 212 additions and 122 deletions

View file

@ -29,8 +29,8 @@ __pycache__
# For group efforts, comment out some or all of these.
server/conf/secret_settings.py
server/logs/*.log.*
web/static/*
web/media/*
server/.static/*
server/.media/*
# Installer logs
pip-log.txt

View file

@ -1,2 +0,0 @@
This directory is where file uploads from Django apps are placed by
default.

View file

@ -1,4 +1,17 @@
DO NOT EDIT FILES IN THIS DIRECTORY! THEY WILL BE OVERWRITTEN.
## Static files
If you need to edit static files, replace them (using the same path)
in the static_overrides directory.
This is the place to put static resources you want to serve from the
Evennia server. This is usually CSS and Javascript files but you _could_ also
serve other media like images, videos and music files from here.
> If you serve a lot of large files (especially videos) you will see a lot
> better performance doing so from a separate dedicated media host.
You can also override default Evennia files from here. The original files are
found in `evennia/web/static/`. Copy the original file into the same
corresponding location/sublocation in this folder (such as website CSS files
into `mygame/static/website/css/`) and modify it, then reload the server.
Note that all static resources will be collected from all over Evennia into
`mygame/server/.static` for serving by the webserver. That folder should not be
modified manually.

View file

@ -1,13 +0,0 @@
If you want to override one of the static files (such as a CSS or JS file) used by Evennia or a Django app installed in your Evennia project,
copy it into this directory's corresponding subdirectory, and it will be placed in the static folder when you run:
python manage.py collectstatic
...or when you reload the server via the command line.
Do note you may have to reproduce any preceeding directory structures for the file to end up in the right place.
Also note that you may need to clear out existing static files for your new ones to be gathered in some cases. Deleting files in static/
will force them to be recollected.
To see what files can be overridden, find where your evennia package is installed, and look in `evennia/web/static/`

View file

@ -1,4 +0,0 @@
Place your own version of templates into this file to override the default ones.
For instance, if there's a template at: `evennia/web/website/templates/website/index.html`
and you want to replace it, create the file `template_overrides/website/index.html`
and it will be loaded instead.

View file

@ -1,3 +0,0 @@
Replace Evennia's webclient django templates with your own here.
You can find the original files in `evennia/web/webclient/templates/webclient/`

View file

@ -1,7 +0,0 @@
You can replace the django templates (html files) for the website
here. It uses the default "prosimii" theme. If you want to maintain
multiple themes rather than just change the default one in-place,
make new folders under `template_overrides/` and change
`settings.ACTIVE_THEME` to point to the folder name to use.
You can find the original files under `evennia/web/website/templates/website/`

View file

@ -0,0 +1,14 @@
# HTML templates
Templates are HTML files that (usually) have special `{{ ... }}` template
markers in them to allow Evennia/Django to insert dynamic content in a web
page. An example is listing how many users are currently online in the game.
Templates are referenced by _views_ - Python functions or callable classes that
prepare the data needed by the template and 'renders' them into a finished
HTML page to return to the user.
You can replace Evennia's default templates by overriding them in this folder.
The originals are in `evennia/web/templates/` - just copy the template into the
corresponding location here (so the website's `index.html` should be copied to
`website/index.html` where it can be modified). Reload the server to see your changes.

View file

@ -0,0 +1,4 @@
Replace Evennia's webclient django template with your own here.
You can find the original files in `evennia/web/templates/webclient/`. Just copy
the original here and modify - after a reload the new template will be used.

View file

@ -0,0 +1,5 @@
You can replace the django templates (html files) for the website
here.
You can find the original files under `evennia/web/templates/website/`. Just
copy a template here and modify to have it override the default.

View file

@ -1,18 +1,27 @@
"""
Url definition file to redistribute incoming URL requests to django
views. Search the Django documentation for "URL dispatcher" for more
help.
This is the starting point when a user enters a url in their web browser.
The urls is matched (by regex) and mapped to a 'view' - a Python function or
callable class that in turn (usually) makes use of a 'template' (a html file
with slots that can be replaced by dynamic content) in order to render a HTML
page to show the user.
This file is already set up to correctly handle all of Evennia's existing web
pages (including the webclient). But if you want to add a new page you needs to
start add by adding its view to `custom_patterns`.
Search the Django documentation for "URL dispatcher" for more help.
"""
from django.conf.urls import url, include
# default evennia patterns
from evennia.web.urls import urlpatterns
from evennia.web.urls import urlpatterns as evennia_default_urlpatterns
# eventual custom patterns
custom_patterns = [
# url(r'/desired/url/', view, name='example'),
# add custom patterns here
urlpatterns = [
# url(r'/desired/url/regex', 'path.to.python.view', name='example'),
]
# this is required by Django.
urlpatterns = custom_patterns + urlpatterns
# 'urlpatterns' must be named such for Django to find it.
urlpatterns = urlpatterns + evennia_default_urlpatterns

View file

@ -0,0 +1,19 @@
"""
A 'view' is python code (can be a function or a callabl class) responsible for
producing a HTML page for a user to view in response for going to a given URL
in their browser. In Evennia lingo, it's similar in function to a Command, with
the input/args being the URL/request and the output being a new web-page.
The urls.py file contains regular expressions that are run against the provided
URL - when a match is found, the execution is passed to a view which is
then responsible (usually) for producing the web page by filling in a
_template_ - a HTML document that can have special tags in it that are replaced
for dynamic content. It then returns the finished HTML page for the user to
view.
See the [Django docs on Views](https://docs.djangoproject.com/en/3.2/topics/http/views/) for
more information.
"""

View file

@ -4,7 +4,7 @@ checks for.
These all print to the terminal.
"""
import os
def check_errors(settings):
"""
@ -123,6 +123,22 @@ def check_errors(settings):
"unused and should be removed. The ChannelHandler is no more; "
"channels are now handled by aliasing the default 'channel' command.")
template_overrides_dir = os.path.join(settings.GAME_DIR, "web", "template_overrides")
static_overrides_dir = os.path.join(settings.GAME_DIR, "web", "static_overrides")
if os.path.exists(template_overrides_dir):
raise DeprecationWarning(
f"The template_overrides directory ({template_overrides_dir}) has changed name.\n"
" - Rename your existing `template_overrides` folder to `templates` instead."
)
if os.path.exists(static_overrides_dir):
raise DeprecationWarning(
f"The static_overrides directory ({static_overrides_dir}) has changed name.\n"
" 1. Delete any existing `web/static` folder and all its contents (this "
"was auto-generated)\n"
" 2. Rename your existing `static_overrides` folder to `static` instead."
)
def check_warnings(settings):
"""
Check conditions and deprecations that should produce warnings but which

View file

@ -281,6 +281,22 @@ ATTRIBUTE_STORED_MODEL_RENAME = [
# Default type of autofield (required by Django)
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
######################################################################
# Evennia webclient options
######################################################################
# default webclient options (without user changing it)
WEBCLIENT_OPTIONS = {
# Gags prompts in output window and puts them on the input bar
"gagprompt": True,
# Shows help files in a new popup window instead of in-pane
"helppopup": False,
# Shows notifications of new messages as popup windows
"notification_popup": False,
# Plays a sound for notifications of new messages
"notification_sound": False
}
######################################################################
# Evennia pluggable modules
######################################################################
@ -816,9 +832,6 @@ MANAGERS = ADMINS
# This is a public point of contact for players or the public to contact
# a staff member or administrator of the site. It is publicly posted.
STAFF_CONTACT_EMAIL = None
# Absolute path to the directory that holds file uploads from web apps.
# Example: "/home/media/media.lawrence.com"
MEDIA_ROOT = os.path.join(GAME_DIR, "web", "media")
# If using Sites/Pages from the web admin, this value must be set to the
# database-id of the Site (domain) we want to use with this game's Pages.
SITE_ID = 1
@ -854,16 +867,17 @@ LOGOUT_URL = reverse_lazy("logout")
# URL that handles the media served from MEDIA_ROOT.
# Example: "http://media.lawrence.com"
MEDIA_URL = "/media/"
# Absolute path to the directory that holds file uploads from web apps.
MEDIA_ROOT = os.path.join(GAME_DIR, "server", ".media")
# URL prefix for admin media -- CSS, JavaScript and images. Make sure
# to use a trailing slash. Django1.4+ will look for admin files under
# STATIC_URL/admin.
# to use a trailing slash. Admin-related files are searched under STATIC_URL/admin.
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(GAME_DIR, "web", "static")
# Absolute path to directory where the static data will be gathered into to be
# served by webserver.
STATIC_ROOT = os.path.join(GAME_DIR, "server", ".static")
# Location of static data to overload the defaults from
# evennia/web/webclient and evennia/web/website's static/ dirs.
STATICFILES_DIRS = [os.path.join(GAME_DIR, "web", "static_overrides")]
STATICFILES_DIRS = [os.path.join(GAME_DIR, "web", "static")]
# Patterns of files in the static directories. Used here to make sure that
# its readme file is preserved but unused.
STATICFILES_IGNORE_PATTERNS = ["README.md"]
@ -871,44 +885,17 @@ STATICFILES_IGNORE_PATTERNS = ["README.md"]
# directory names shown in the templates directory.
WEBSITE_TEMPLATE = "website"
WEBCLIENT_TEMPLATE = "webclient"
# The default options used by the webclient
WEBCLIENT_OPTIONS = {
"gagprompt": True, # Gags prompt from the output window and keep them
# together with the input bar
"helppopup": False, # Shows help files in a new popup window
"notification_popup": False, # Shows notifications of new messages as
# popup windows
"notification_sound": False # Plays a sound for notifications of new
# messages
}
# Django cache settings
# https://docs.djangoproject.com/en/dev/topics/cache/#setting-up-the-cache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
'throttle': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 60 * 5,
'OPTIONS': {
'MAX_ENTRIES': 2000
}
}
}
# We setup the location of the website template as well as the admin site.
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
os.path.join(GAME_DIR, "web", "template_overrides", WEBSITE_TEMPLATE),
os.path.join(GAME_DIR, "web", "template_overrides", WEBCLIENT_TEMPLATE),
os.path.join(GAME_DIR, "web", "template_overrides"),
os.path.join(EVENNIA_DIR, "web", "website", "templates", WEBSITE_TEMPLATE),
os.path.join(EVENNIA_DIR, "web", "website", "templates"),
os.path.join(EVENNIA_DIR, "web", "webclient", "templates", WEBCLIENT_TEMPLATE),
os.path.join(EVENNIA_DIR, "web", "webclient", "templates"),
os.path.join(GAME_DIR, "web", "templates"),
os.path.join(GAME_DIR, "web", "templates", WEBSITE_TEMPLATE),
os.path.join(GAME_DIR, "web", "templates", WEBCLIENT_TEMPLATE),
os.path.join(EVENNIA_DIR, "web", "templates"),
os.path.join(EVENNIA_DIR, "web", "templates", WEBSITE_TEMPLATE),
os.path.join(EVENNIA_DIR, "web", "templates", WEBCLIENT_TEMPLATE),
],
"APP_DIRS": True,
"OPTIONS": {
@ -927,7 +914,20 @@ TEMPLATES = [
},
}
]
# Django cache settings
# https://docs.djangoproject.com/en/dev/topics/cache/#setting-up-the-cache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
'throttle': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 60 * 5,
'OPTIONS': {
'MAX_ENTRIES': 2000
}
}
}
# MiddleWare are semi-transparent extensions to Django's functionality.
# see http://www.djangoproject.com/documentation/middleware/ for a more detailed
# explanation.
@ -969,8 +969,7 @@ INSTALLED_APPS = [
"evennia.comms",
"evennia.help",
"evennia.scripts",
"evennia.web.website",
"evennia.web.webclient",
"evennia.web"
]
# The user profile extends the User object with more functionality;
# This should usually not be changed.

21
evennia/web/README.md Normal file
View file

@ -0,0 +1,21 @@
# Web resources
This folder holds the functioning code, html, js and css files for use by the
Evennia website and -client. This is a standard Django web application.
1. When a user enters an url (or clicks a link) in their web browser, Django will
use this incoming request to refer to the `urls.py` file.
2. The `urls.py` file will use regex to match the url to a _view_ - a Python function
or callable class. The incoming request data will be passed to this code.
3. The view will (usually) refer to a _template_, which is a html document with
templating slots that allows the system to replace parts of it with dynamic
content (like how many users are currently in-game).
4. The view will render the template with any context into a final HTML page
that is returned to the user to view.
I many ways this works like an Evennia Command, with input being the browser's
request and the view being the Command's function body for producing a result.
In the case of the webclient, the html page is rendered once and when doing so
it loads a Javascript application in the browser that opens a websocket to
communicate with the server.

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -1,10 +1,21 @@
#
# File that determines what each URL points to. This uses _Python_ regular
# expressions, not Perl's.
#
# See:
# http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3
#
"""
File that determines what each URL points to. This uses Python regular expressions.
This is the starting point when a user enters an URL.
1. The URL is matched with a regex, tying it to a given view. Note that this central url.py
file includes url.py from all the various web-components found in views/ so the search
space is much larger than what is shown here.
2. The view (a Python function or class is executed)
3. The view uses a template (a HTML file which may contain template markers for dynamically
modifying its contents; the locations of such templates are given by
`settings.TEMPLATES[0]['DIRS']`) and which may in turn may include static
assets (CSS, images etc).
4. The view 'renders' the template into a finished HTML page, replacing all
dynamic content as appropriate.
5. The HTML page is returned to the user.
"""
from django.conf.urls import url
from django.conf import settings
@ -24,4 +35,5 @@ urlpatterns = [
]
if settings.REST_API_ENABLED:
# Rest API
urlpatterns += [url(r"^api/", include("evennia.web.api.urls", namespace="api"))]

View file

@ -1,10 +1,10 @@
"""
This structures the (simple) structure of the
webpage 'application'.
This structures the (simple) structure of the webpage 'application'.
"""
from django.urls import path
from evennia.web.webclient import views as webclient_views
from . import views
app_name = "webclient"
urlpatterns = [path("", webclient_views.webclient, name="index")]
urlpatterns = [path("", views.webclient, name="index")]

View file

@ -6,63 +6,70 @@ from django.conf import settings
from django.contrib import admin
from django.conf.urls import url, include
from django import views as django_views
from evennia.web.website import views as website_views
from . import views
urlpatterns = [
url(r"^$", website_views.EvenniaIndexView.as_view(), name="index"),
url(r"^tbi/", website_views.to_be_implemented, name="to_be_implemented"),
url(r"^$", views.EvenniaIndexView.as_view(), name="index"),
url(r"^tbi/", views.to_be_implemented, name="to_be_implemented"),
# User Authentication (makes login/logout url names available)
url(r"^auth/register", website_views.AccountCreateView.as_view(), name="register"),
url(r"^auth/register", views.AccountCreateView.as_view(), name="register"),
url(r"^auth/", include("django.contrib.auth.urls")),
# Help Topics
url(r"^help/$", website_views.HelpListView.as_view(), name="help"),
url(r"^help/$", views.HelpListView.as_view(), name="help"),
url(
r"^help/(?P<category>[\w\d\-]+)/(?P<topic>[\w\d\-]+)/$",
website_views.HelpDetailView.as_view(),
views.HelpDetailView.as_view(),
name="help-entry-detail",
),
# Channels
url(r"^channels/$", website_views.ChannelListView.as_view(), name="channels"),
url(r"^channels/$", views.ChannelListView.as_view(), name="channels"),
url(
r"^channels/(?P<slug>[\w\d\-]+)/$",
website_views.ChannelDetailView.as_view(),
views.ChannelDetailView.as_view(),
name="channel-detail",
),
# Character management
url(r"^characters/$", website_views.CharacterListView.as_view(), name="characters"),
url(r"^characters/$", views.CharacterListView.as_view(), name="characters"),
url(
r"^characters/create/$",
website_views.CharacterCreateView.as_view(),
views.CharacterCreateView.as_view(),
name="character-create",
),
url(
r"^characters/manage/$",
website_views.CharacterManageView.as_view(),
views.CharacterManageView.as_view(),
name="character-manage",
),
url(
r"^characters/detail/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$",
website_views.CharacterDetailView.as_view(),
views.CharacterDetailView.as_view(),
name="character-detail",
),
url(
r"^characters/puppet/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$",
website_views.CharacterPuppetView.as_view(),
views.CharacterPuppetView.as_view(),
name="character-puppet",
),
url(
r"^characters/update/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$",
website_views.CharacterUpdateView.as_view(),
views.CharacterUpdateView.as_view(),
name="character-update",
),
url(
r"^characters/delete/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$",
website_views.CharacterDeleteView.as_view(),
views.CharacterDeleteView.as_view(),
name="character-delete",
),
# Django original admin page. Make this URL is always available, whether
# we've chosen to use Evennia's custom admin or not.
url(r"django_admin/", website_views.admin_wrapper, name="django_admin"),
url(r"django_admin/", views.admin_wrapper, name="django_admin"),
# Admin docs
url(r"^admin/doc/", include("django.contrib.admindocs.urls")),
]
@ -70,7 +77,7 @@ urlpatterns = [
if settings.EVENNIA_ADMIN:
urlpatterns += [
# Our override for the admin.
url("^admin/$", website_views.evennia_admin, name="evennia_admin"),
url("^admin/$", views.evennia_admin, name="evennia_admin"),
# Makes sure that other admin pages get loaded.
url(r"^admin/", admin.site.urls),
]

View file

@ -26,7 +26,7 @@ from evennia.objects.models import ObjectDB
from evennia.accounts.models import AccountDB
from evennia.utils import class_from_module
from evennia.utils.logger import tail_log_file
from evennia.web.website import forms as website_forms
from . import forms
from django.utils.text import slugify
@ -165,7 +165,7 @@ class EvenniaIndexView(TemplateView):
return context
class TypeclassMixin(object):
class TypeclassMixin:
"""
This is a "mixin", a modifier of sorts.
@ -523,7 +523,7 @@ class AccountMixin(TypeclassMixin):
# -- Django constructs --
model = class_from_module(settings.BASE_ACCOUNT_TYPECLASS,
fallback=settings.FALLBACK_ACCOUNT_TYPECLASS)
form_class = website_forms.AccountForm
form_class = forms.AccountForm
class AccountCreateView(AccountMixin, EvenniaCreateView):
@ -589,7 +589,7 @@ class CharacterMixin(TypeclassMixin):
# -- Django constructs --
model = class_from_module(settings.BASE_CHARACTER_TYPECLASS,
fallback=settings.FALLBACK_CHARACTER_TYPECLASS)
form_class = website_forms.CharacterForm
form_class = forms.CharacterForm
success_url = reverse_lazy("character-manage")
def get_queryset(self):
@ -713,7 +713,7 @@ class CharacterUpdateView(CharacterMixin, ObjectUpdateView):
"""
# -- Django constructs --
form_class = website_forms.CharacterUpdateForm
form_class = forms.CharacterUpdateForm
template_name = "website/character_form.html"