node_type = forms.CharField(widget=forms.HiddenInput, initial='all')
state_type = forms.CharField(widget=forms.HiddenInput, initial='any')
text = forms.CharField(required=False, widget=forms.TextInput(attrs={'size': 40}))
- text_in = forms.ChoiceField(widget=forms.RadioSelect, choices=TEXT_IN_CHOICES, initial='title')
+ text_in = forms.ChoiceField(required=False, widget=forms.RadioSelect, choices=TEXT_IN_CHOICES, initial='title')
+
+
+NODE_SHOW_CHOICES = (
+('score', _('Score')),
+('added_at', 'Added at'),
+('last_activity_at', 'Last activity at'),
+('last_activity_by', 'Last activity by')
+)
+
+class NodeManShowForm(forms.Form):
+ show = forms.MultipleChoiceField(choices=NODE_SHOW_CHOICES, widget=forms.CheckboxSelectMultiple)
\ No newline at end of file
{% extends basetemplate %}
-{% load i18n %}
-{% load user_tags %}
+{% load i18n user_tags extra_tags %}
{% block adminjs %}
<script type="text/javascript">
$form.find('#id_state_type').val($(this).attr('href').substring(1));
$form.submit();
});
+
+ $('.action-select').change(function() {
+ $('#action-toggle').removeAttr('checked');
+ var $tr = $(this).parents('tr');
+ if ($(this).attr('checked')) {
+ $tr.addClass('selected');
+ } else {
+ $tr.removeClass('selected');
+ }
+ }).change();
+
+ $('#action-toggle').change(function() {
+ var $rows = $('#result_list').find('tbody').find('tr');
+ var $boxes = $('#result_list').find('tbody').find('input');
+
+ if ($(this).attr('checked')) {
+ $rows.addClass('selected');
+ $boxes.attr('checked', 'checked')
+ } else {
+ $rows.removeClass('selected');
+ $boxes.removeAttr('checked');
+ }
+ });
});
</script>
<style>
{{ filter_form.text }}
{{ filter_form.node_type }}
{{ filter_form.state_type }}
- <input type="submit" value="Search"><br />
+ <input type="submit" value="{% trans "Search" %}"><br />
{{ filter_form.text_in }}
</div>
</form>
</li>
{% endfor %}
</ul>
+ {% comment %}<h3>{% trans "Show" %}</h3>
+ <form action="" method="get">
+ <div>{{ show_form.show }}</div>
+ <input type="submit" value="{% trans "Refresh" %}" />
+ </form>{% endcomment %}
</div>
<form id="changelist-form" method="POST" action="">
- <div class="action"></div>
+ <div class="actions">
+ <label>
+ {% trans "Action" %}:
+ <select name="action">
+ <option selected="selected" value="">---------</option>
+ <option value="delete_selected">{% trans "Mark deleted" %}</option>
+ </select>
+ </label>
+ <button value="0" name="index" title="{% trans "Run the selected action" %}" class="button" type="submit">{% trans "Go" %}</button>
+ </div>
<table id="result_list" cellspacing="0">
<thead>
<tr>
+ {% spaceless %}
<th class="action-checkbox-column">
<input type="checkbox" id="action-toggle" style="display: inline;" />
</th>
{% ifequal filter_form.node_type.data "all" %}
<th>{% trans "Type" %}</th>
{% endifequal %}
- <th>{% trans "Title" %}</th>
+ <th class="sorted{% ifequal nodes.paginator.current_sort "title" %} ascending{% endifequal %}">
+ <a href="{{ nodes.paginator.title_sort_link }}">{% trans "Title" %}</a>
+ </th>
<th>{% trans "Author" %}</th>
+ <th class="sorted{% ifequal nodes.paginator.current_sort "added_at" %} ascending{% endifequal %}">
+ <a href="{{ nodes.paginator.added_at_sort_link }}">{% trans "Added at" %}</a>
+ </th>
+ <th class="sorted{% ifequal nodes.paginator.current_sort "score" %} ascending{% endifequal %}">
+ <a href="{{ nodes.paginator.score_sort_link }}">{% trans "Score" %}</a>
+ </th>
+ <th>{% trans "Last acivity by" %}</th>
+ <th class="sorted{% ifequal nodes.paginator.current_sort "act_at" %} ascending{% endifequal %}">
+ <a href="{{ nodes.paginator.act_at_sort_link }}">{% trans "Last activity at" %}</a>
+ </th>
+ {% endspaceless %}
</tr>
</thead>
<tbody>
{% for node in nodes.paginator.page %}
<tr class="{% cycle 'row1' 'row2' %}">
- <td><input type="checkbox" name="_selected_action" value="{{ node.id }}" class="action-select"></td>
+ <td><input type="checkbox" name="_selected_node" value="{{ node.id }}" class="action-select"></td>
{% ifequal filter_form.node_type.data "all" %}
<th>{{ node.friendly_name }}</th>
{% endifequal %}
<td><a href="{{ node.get_absolute_url }}" target="_blank">{{ node.headline }}</a></td>
<td><a href="{{ node.author.get_absolute_url }}">{{ node.author.username }}</a></td>
+ <td>{% diff_date node.added_at %}</td>
+ <td>{{ node.score }}</td>
+ <td><a href="{{ node.last_activity_by.get_absolute_url }}">{{ node.last_activity_by.username }}</a></td>
+ <td>{% diff_date node.last_activity_at %}</td>
</tr>
{% endfor %}
</tbody>
url_builder = lambda s: mark_safe("%s%s%s=%s" % (base_path, url_joiner, context.SORT, s))
sorts = [(n, s.label, url_builder(n), strip_tags(s.description)) for n, s in context.sort_methods.items()]
+ for name, label, url, descr in sorts:
+ paginator.__dict__['%s_sort_link' % name] = url
+
return sort_tabs_template.render(template.Context({
'current': sort,
'sorts': sorts,
}))
paginator.sort_tabs = sort_tabs()
paginator.sort_description = mark_safe(context.sort_methods[sort].description)
+ paginator.current_sort = sort
else:
paginator.sort_tabs = paginator.sort_description = ''
+ paginator.current_sort = ''
context.set_preferences(request, session_prefs)
objects.paginator = paginator
from django.utils import simplejson
from django.db import models
from forum.settings.base import Setting
-from forum.forms import MaintenanceModeForm, PageForm, NodeManFilterForm
+from forum.forms import MaintenanceModeForm, PageForm, NodeManFilterForm, NodeManShowForm
from forum.settings.forms import SettingsSetForm
from forum.utils import pagination
from forum.models import Question, Answer, User, Node, Action, Page, NodeState
from forum.models.node import NodeMetaClass
-from forum.actions import NewPageAction, EditPageAction, PublishAction
+from forum.actions import NewPageAction, EditPageAction, PublishAction, DeleteAction
from forum import settings
TOOLS = {}
})
+class NodeManagementPaginatorContext(pagination.PaginatorContext):
+ def __init__(self, id='QUESTIONS_LIST', prefix='', default_pagesize=100):
+ super (NodeManagementPaginatorContext, self).__init__(id, sort_methods=(
+ (_('title'), pagination.SimpleSort(_('title'), '-title', "")),
+ (_('added_at'), pagination.SimpleSort(_('added_at'), '-added_at', "")),
+ (_('score'), pagination.SimpleSort(_('score'), '-score', "")),
+ (_('act_at'), pagination.SimpleSort(_('act_at'), '-last_activity_at', "")),
+ ), pagesizes=(default_pagesize,), default_pagesize=default_pagesize, prefix=prefix)
@admin_tools_page(_("nodeman"), _("Node management"))
def node_management(request):
+ if request.POST:
+ selected_nodes = request.POST.getlist('_selected_node')
+
+ if selected_nodes and request.POST.get('action', None):
+ action = request.POST['action']
+ selected_nodes = Node.objects.filter(id__in=selected_nodes)
+
+ message = _("No action performed")
+
+ if action == 'delete_selected':
+ for node in selected_nodes:
+ if node.node_type in ('question', 'answer', 'comment') and (not node.nis.deleted):
+ DeleteAction(user=request.user, node=node, ip=request.META['REMOTE_ADDR']).save()
+
+ message = _("All selected nodes marked as deleted")
+
+ request.user.message_set.create(message=message)
+ return HttpResponseRedirect(reverse("admin_tools", kwargs={'name': 'nodeman'}))
+
+
nodes = Node.objects.all()
if (request.GET):
if filter:
nodes = nodes.filter(filter)
+ else:
+ print filter_form.errors
node_types = [('all', _("all"))] + [(k, n.friendly_name) for k, n in NodeMetaClass.types.items()]
state_types = NodeState.objects.filter(node__in=nodes).values_list('state_type', flat=True).distinct('state_type')
- return ('osqaadmin/nodeman.html', pagination.paginated(request, ("nodes", ActivityPaginatorContext()), {
+ return ('osqaadmin/nodeman.html', pagination.paginated(request, ("nodes", NodeManagementPaginatorContext()), {
'nodes': nodes,
'node_types': node_types,
'state_types': state_types,