Added custom Evennia admin and ability to toggle it.

This commit is contained in:
Kelketek Rritaa 2014-06-04 08:58:54 -05:00
parent fbe0eab01c
commit 7d12c6dd69
11 changed files with 70 additions and 474 deletions

1
.gitignore vendored
View file

@ -29,6 +29,7 @@ __pycache__
# Installation-specific
game/settings.py
game/logs/*.log.*
game/gamesrc/web/static/*
# Installer logs
pip-log.txt

View file

@ -85,6 +85,15 @@ SSL_ENABLED = False
SSL_PORTS = [4001]
# Interface addresses to listen to. If 0.0.0.0, listen to all. Use :: for IPv6.
SSL_INTERFACES = ['0.0.0.0']
# Activate Websocket support
WEBSOCKET_ENABLED = False
# Ports to use for Websockets
WEBSOCKET_PORTS = [8021]
# Interface addresses to listen to. If 0.0.0.0, listen to all. Use :: for IPv6.
WEBSOCKET_INTERFACES = ['0.0.0.0']
# This determine's whether Evennia's custom admin page is used, or if the
# standard Django admin is used.
EVENNIA_ADMIN = True
# The path that contains this settings.py file (no trailing slash).
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Path to the src directory containing the bulk of the codebase's code.

View file

@ -1,11 +0,0 @@
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'Evennia site admin' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'Evennia database administration' %}
<a href="{% url "index" %}">(Back)</a> </h1>
{% endblock %}
{% block nav-global %}{% endblock %}

View file

@ -1,184 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
<div id="content-main">
{% if app_list %}
{% for app in app_list %}
{% if app.name in evennia_userapps %}
{% if app.name == 'Players' %}
<h2>Admin</h2>
<p><i>Players are the out-of-character representation of a
game account. A Player can potentially control any number of
in-game character Objects (depending on game).</i></p>
{% endif %}
<div class="module">
<table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
<caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
{% for model in app.models %}
<tr>
{% if model.name == "Players" %}
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">Player</a></th>
{% else %}
<th scope="row">Player</th>
{% endif %}
{% if model.perms.add %}
<td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
{% if model.perms.change %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endif %}
{% endfor %}
</table>
</div>
{% endif %}
{% endfor %}
<h2>Game entities</h2>
{% for app in app_list %}
{% if app.name in evennia_entityapps %}
{% if app.name == 'Comms' %}
<p><i>This defines entities that has an in-game precense or
effect of some kind.</i></p>
{% endif %}
<div class="module">
<table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
<caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.perms.add %}
<td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
{% if model.perms.change %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endif %}
{% endfor %}
<h2>Website</h2>
{% for app in app_list %}
{% if app.name in evennia_websiteapps %}
{% if app.name == 'Flatpages' %}
<p><i>Miscellaneous objects related to the running and
managing of the Web presence.</i></p>
{% endif %}
<div class="module">
<table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
<caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.perms.add %}
<td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
{% if model.perms.change %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endif %}
{% endfor %}
{% else %}
<p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans 'Recent Actions' %}</h2>
<h3>{% trans 'My Actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% trans 'None yet.' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion %}
{{ entry.object_repr }}
{% else %}
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
{% endif %}
<br/>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}

View file

@ -1,14 +0,0 @@
{% extends "admin/players/change_form.html" %}
{% load i18n %}
{% block form_top %}
{% if not is_popup %}
<p>{% trans "First, enter a username and password. Then you'll be able to edit more Player options." %}</p>
{% else %}
<p>{% trans "Enter a username and password." %}</p>
{% endif %}
{% endblock %}
{% block after_field_sets %}
<script type="text/javascript">document.getElementById("id_username").focus();</script>
{% endblock %}

View file

@ -1,70 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_modify admin_static %}
{% block extrahead %}{{ block.super }}
{% url 'admin:jsi18n' as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block coltype %}{% if ordered_objects %}colMS{% else %}colM{% endif %}{% endblock %}
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }}
change-form{% endblock %}
{% block breadcrumbs %}{% if not is_popup %}
<div class="breadcrumbs">
<a href="../../../">{% trans "Home" %}</a> &rsaquo;
<a href="../../">{{ app_label|capfirst|escape }}</a> &rsaquo;
{% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} &rsaquo;
{% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endif %}{% endblock %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
<li><a href="history/" class="historylink">{% trans "History" %}</a></li>
{% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}
{% if save_on_top %}{% submit_row %}{% endif %}
{% if errors %}
<p class="errornote">
{% blocktrans count errors|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% block after_field_sets %}{% endblock %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% block after_related_objects %}{% endblock %}
{% submit_row %}
{% if adminform and add %}
<script type="text/javascript">document.getElementById("{{ adminform.first_field.id_for_label }}").focus();</script>
{% endif %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}

View file

@ -1,103 +0,0 @@
{% extends "admin/base_site.html" %}
{% load admin_static admin_list i18n %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
{% if cl.formset %}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
{% endif %}
{% if cl.formset or action_form %}
{% url 'admin:jsi18n' as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:'../../jsi18n/' }}"></script>
{% endif %}
{{ media.css }}
{% if not actions_on_top and not actions_on_bottom %}
<style>
#changelist table thead th:first-child {width: inherit}
</style>
{% endif %}
{% endblock %}
{% block extrahead %}
{{ block.super }}
{{ media.js }}
{% if action_form %}{% if actions_on_top or actions_on_bottom %}
<script type="text/javascript">
(function($) {
$(document).ready(function($) {
$("tr input.action-select").actions();
});
})(django.jQuery);
</script>
{% endif %}{% endif %}
{% endblock %}
{% block bodyclass %}change-list{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="../../">
{% trans "Home" %}
</a>
&rsaquo;
<a href="../">
{{ app_label|capfirst }}
</a>
&rsaquo;
{{ cl.opts.verbose_name_plural|capfirst }}
</div>
{% endblock %}
{% endif %}
{% block coltype %}flex{% endblock %}
{% block content %}
<div id="content-main">
{% block object-tools %}
{% if has_add_permission %}
<ul class="object-tools">
{% block object-tools-items %}
<li>
<a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">
{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
</a>
</li>
{% endblock %}
</ul>
{% endif %}
{% endblock %}
{% if cl.formset.errors %}
<p class="errornote">
{% blocktrans count cl.formset.errors|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
</p>
{{ cl.formset.non_form_errors }}
{% endif %}
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
{% block search %}{% search_form cl %}{% endblock %}
{% block date_hierarchy %}{% date_hierarchy cl %}{% endblock %}
{% block filters %}
{% if cl.has_filters %}
<div id="changelist-filter">
<h2>{% trans 'Filter' %}</h2>
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
</div>
{% endif %}
{% endblock %}
<form id="changelist-form" action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}>{% csrf_token %}
{% if cl.formset %}
<div>{{ cl.formset.management_form }}</div>
{% endif %}
{% block result_list %}
{% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
{% result_list cl %}
{% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
{% endblock %}
{% block pagination %}{% pagination cl %}{% endblock %}
</form>
</div>
</div>
{% endblock %}

View file

@ -1,82 +0,0 @@
{% load i18n admin_static %}
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
<!--h2>{{ inline_admin_formset.opts.verbose_name_plural|title }}</h2-->
{{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.non_form_errors }}
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
<!--h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span>
{% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.id }}/">{% trans "View on site" %}</a>{% endif %}
{% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
</h3-->
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
{% for fieldset in inline_admin_form %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }}
</div>{% endfor %}
</div>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var rows = "#{{ inline_admin_formset.formset.prefix }}-group .inline-related";
var updateInlineLabel = function(row) {
$(rows).find(".inline_label").each(function(i) {
var count = i + 1;
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
});
}
var reinitDateTimeShortCuts = function() {
// Reinitialize the calendar and clock widgets by force, yuck.
if (typeof DateTimeShortcuts != "undefined") {
$(".datetimeshortcuts").remove();
DateTimeShortcuts.init();
}
}
var updateSelectFilter = function() {
// If any SelectFilter widgets were added, instantiate a new instance.
if (typeof SelectFilter != "undefined"){
$(".selectfilter").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% static "admin/" %}");
});
$(".selectfilterstacked").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% static "admin/" %}");
});
}
}
var initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() {
var field = $(this);
var input = field.find('input, select, textarea');
var dependency_list = input.data('dependency_list') || [];
var dependencies = [];
$.each(dependency_list, function(i, field_name) {
dependencies.push('#' + row.find(field_name).find('input, select, textarea').attr('id'));
});
if (dependencies.length) {
input.prepopulate(dependencies, input.attr('maxlength'));
}
});
}
$(rows).formset({
prefix: "{{ inline_admin_formset.formset.prefix }}",
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
formCssClass: "dynamic-{{ inline_admin_formset.formset.prefix }}",
deleteCssClass: "inline-deletelink",
deleteText: "{% trans "Remove" %}",
emptyCssClass: "empty-form",
removed: updateInlineLabel,
added: (function(row) {
initPrepopulatedFields(row);
reinitDateTimeShortCuts();
updateSelectFilter();
updateInlineLabel(row);
})
});
});
})(django.jQuery);
</script>

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<h1>Admin</h1>
Welcome to the Evennia Admin Page. Here, you can edit many facets of players, characters, and other parts of the game.
<h2><a href="{% url "admin:players_playerdb_changelist" %}">Players</a></h2>
Players are user accounts. Players can have several characters under them. A user's login and password information can be changed here.
<h2><a href="{% url "admin:objects_objectdb_changelist" %}">Objects</a></h2>
Objects include everything from characters to rooms to exits.
<h2><a href="{% url "admin:scripts_scriptdb_changelist" %}">Scripts</a></h2>
Scripts are meta objects used to store game information, handle special functionality or perform timed actions.
<h2><a href="{% url "admin:comms_channeldb_changelist" %}">Channels</a></h2>
Channels are used for player communications.
<h2><a href="{% url "admin:help_helpentry_changelist" %}">Help Topics</a></h2>
<p>If you are an advanced user who needs access to the raw Django Admin, it is available <a href="{% url "django_admin" %}">here</a>.
You can make this the default my changing <code>EVENNIA_ADMIN</code> to <code>False</code> in <code>settings.py</code> and reload.</p>
{% endblock content %}

View file

@ -37,7 +37,6 @@ urlpatterns = [
# Admin interface
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
# favicon
url(r'^favicon\.ico$', RedirectView.as_view(url='/media/images/favicon.ico')),
@ -46,7 +45,22 @@ urlpatterns = [
url(r'^webclient/', include('src.web.webclient.urls', namespace='webclient', app_name='webclient')),
# Front page
url(r'^$', 'src.web.views.page_index', name="index")]
url(r'^$', 'src.web.views.page_index', name="index"),
# 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/', 'src.web.views.admin_wrapper', name="django_admin")]
if settings.EVENNIA_ADMIN:
urlpatterns += [
# Our override for the admin.
url('^admin/$', 'src.web.views.evennia_admin', name="evennia_admin"),
# Makes sure that other admin pages get loaded.
url(r'^admin/', include(admin.site.urls))]
else:
# Just include the normal Django admin.
urlpatterns += [url(r'^admin/', include(admin.site.urls))]
# This sets up the server if the user want to run the Django
# test server (this should normally not be needed).

View file

@ -5,18 +5,18 @@ the other applications. Views are django's way of processing e.g. html
templates on the fly.
"""
from django.shortcuts import render_to_response
from django.template import RequestContext
#from django.contrib.auth.models import User
from django.contrib.admin.sites import site
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import render
from src.objects.models import ObjectDB
#from src.typeclasses.models import TypedObject
from src.players.models import PlayerDB
from src.web.news.models import NewsEntry
_BASE_CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
def page_index(request):
"""
Main root page.
@ -56,8 +56,8 @@ def page_index(request):
"num_others": nothers or "no"
}
context_instance = RequestContext(request)
return render_to_response('index.html', pagevars, context_instance)
return render(request, 'index.html', pagevars)
def to_be_implemented(request):
"""
@ -69,7 +69,21 @@ def to_be_implemented(request):
"page_title": "To Be Implemented...",
}
context_instance = RequestContext(request)
return render_to_response('tbi.html', pagevars, context_instance)
return render(request, 'tbi.html', pagevars)
@staff_member_required
def evennia_admin(request):
"""
Helpful Evennia-specific admin page.
"""
return render(
request, 'evennia_admin.html', {
'playerdb': PlayerDB})
def admin_wrapper(request):
"""
Wrapper that allows us to properly use the base Django admin site, if needed.
"""
return staff_member_required(site.index)(request)