Просмотр исходного кода

- Online list in ACP
- Cleaned Overview APP

Ralfp 12 лет назад
Родитель
Сommit
580ae61bfe

+ 24 - 8
misago/admin/widgets.py

@@ -47,7 +47,7 @@ class BaseWidget(object):
     def get_id(self):
         return 'admin_%s' % self.id
          
-    def get_templates(self, template):
+    def get_template(self, template):
         return ('%s/%s/%s.html' % (str(self.admin.model.__module__).split('.')[1], str(self.admin.route).lower(), template),
                 '%s/%s.html' % (str(self.admin.model.__module__).split('.')[1], template),
                 'admin/%s.html' % template)
@@ -252,9 +252,17 @@ class ListWidget(BaseWidget):
         # Get basic list attributes
         if request.session.get(self.get_token('filter')):
             self.is_filtering = True
-            items_total = self.set_filters(self.admin.model.objects, request.session.get(self.get_token('filter'))).count()
+            items_total = self.set_filters(self.admin.model.objects, request.session.get(self.get_token('filter')))
         else:
-            items_total = self.admin.model.objects.count()
+            items_total = self.admin.model.objects
+            
+        # Set extra filters?
+        try:
+            items_total = self.select_items(items_total).count()
+        except AttributeError:
+            items_total = items_total.count()
+            
+        # Set sorting and paginating
         sorting_method = self.get_sorting(request)
         paginating_method = self.get_pagination(request, items_total, page)
         
@@ -266,7 +274,13 @@ class ListWidget(BaseWidget):
             items = self.set_filters(items, request.session.get(self.get_token('filter')))
         else:
             items = items.all()
-                   
+         
+        # Set extra filters?
+        try:
+            items = self.select_items(items)
+        except AttributeError:
+            pass
+                  
         # Sort them
         items = self.sort_items(request, items, sorting_method);
         
@@ -275,9 +289,11 @@ class ListWidget(BaseWidget):
             items = items[paginating_method['start']:paginating_method['stop']]
         
         # Prefetch related?
-        if self.prefetch_related:
+        try:
             items = self.prefetch_related(items)
-            
+        except AttributeError:
+            pass
+        
         # Default message
         message = request.messages.get_message(self.admin.id)
         
@@ -360,7 +376,7 @@ class ListWidget(BaseWidget):
                 list_form = ListForm(request=request)
                 
         # Render list
-        return request.theme.render_to_response(self.get_templates(self.template),
+        return request.theme.render_to_response(self.get_template(self.template),
                                                 {
                                                  'admin': self.admin,
                                                  'action': self,
@@ -462,7 +478,7 @@ class FormWidget(BaseWidget):
             form = self.get_form_instance(FormType, request, model, self.get_initial_data(request, model))
             
         # Render form
-        return request.theme.render_to_response(self.get_templates(self.template),
+        return request.theme.render_to_response(self.get_template(self.template),
                                                 {
                                                  'admin': self.admin,
                                                  'action': self,

+ 15 - 3
misago/overview/admin/__init__.py

@@ -1,6 +1,7 @@
 from django.conf.urls import patterns, include, url
 from django.utils.translation import ugettext_lazy as _
 from misago.admin import AdminSection, AdminAction
+from misago.sessions.models import Session
 
 ADMIN_SECTIONS=(
     AdminSection(
@@ -40,9 +41,20 @@ ADMIN_ACTIONS=(
                name=_("Online"),
                help=_("See who is currently online on forums."),
                icon='fire',
-               route='admin_overview_online',
-               urlpatterns=patterns('misago.admin.views',
-                        url(r'^$', 'todo', name='admin_overview_online'),
+               model=Session,
+               actions=[
+                        {
+                         'id': 'list',
+                         'icon': 'list-alt',
+                         'name': _("Browse Users"),
+                         'help': _("Browse all registered user accounts"),
+                         'route': 'admin_overview_online'
+                         },
+                        ],
+               route='admin_overview_online', 
+               urlpatterns=patterns('misago.overview.admin.views',
+                        url(r'^$', 'OnlineList', name='admin_overview_online'),
+                        url(r'^(?P<page>\d+)/$', 'OnlineList', name='admin_overview_online'),
                     ),
                ),
    AdminAction(

+ 27 - 1
misago/overview/admin/forms.py

@@ -25,4 +25,30 @@ class GenerateStatisticsForm(Form):
         provider_choices = kwargs.get('provider_choices')
         del kwargs['provider_choices']
         super(GenerateStatisticsForm, self).__init__(*args, **kwargs)
-        self.fields['provider_model'] = forms.ChoiceField(choices=provider_choices)
+        self.fields['provider_model'] = forms.ChoiceField(choices=provider_choices)
+        
+
+class SearchSessionsForm(Form):
+    username = forms.CharField(max_length=255, required=False)
+    ip_address = forms.CharField(max_length=255, required=False)
+    useragent = forms.CharField(max_length=255, required=False)
+    type = forms.ChoiceField(choices=(
+                                      ('all', _("All types")),
+                                      ('registered', _("Registered Members Sessions")),
+                                      ('hidden', _("Hidden Sessions")),
+                                      ('guest', _("Guests Sessions")),
+                                      ('crawler', _("Crawler Sessions")),
+                                      ), required=False)
+    
+    layout = (
+              (
+               _("Search Sessions"),
+               (
+                ('ip_address', {'label': _("IP Address"), 'attrs': {'placeholder': _("IP begins with...")}}),
+                ('username', {'label': _("Username"), 'attrs': {'placeholder': _("Username begings with...")}}),
+                ('useragent', {'label': _("User Agent"), 'attrs': {'placeholder': _("User Agent contains...")}}),
+                ('type', {'label': _("Session Type")}),
+               ),
+              ),
+             )
+    

+ 47 - 14
misago/overview/admin/views.py

@@ -1,3 +1,4 @@
+import math
 from datetime import datetime, timedelta
 from django.conf import settings
 from django.core.urlresolvers import reverse
@@ -7,11 +8,12 @@ from django.shortcuts import redirect
 from django.template import RequestContext
 from django.utils import formats, timezone
 from django.utils.translation import ugettext as _
-import math
+from misago.admin import site
+from misago.admin.widgets import *
 from misago.forms import FormLayout
 from misago.forums.models import Thread, Post
 from misago.messages import Message, BasicMessage
-from misago.overview.admin.forms import GenerateStatisticsForm
+from misago.overview.admin.forms import GenerateStatisticsForm, SearchSessionsForm
 from misago.sessions.models import Session
 from misago.users.models import User
 
@@ -142,17 +144,6 @@ def check_dates(date_start, date_end, precision):
           or (precision == 'year' and date_diff / 31536000 < 1)):
         return BasicMessage(_('Too few items to display on graph'), type='error')
     return None
-
-
-def overview_forums(request, mode=None):
-    return request.theme.render_to_response('overview/forums.html', {                                        
-        'graph_posts': build_stat(Post, mode),                                            
-        'graph_threads': build_stat(Thread, mode),
-        'posts': request.monitor['posts'],
-        'threads': request.monitor['threads'],
-        'mode': mode,
-        }, context_instance=RequestContext(request));
-       
         
 def build_graph(model, date_start, date_end, precision):
     if precision == 'day':
@@ -192,4 +183,46 @@ def build_graph(model, date_start, date_end, precision):
     for i in stat['stat']:
         if i > stat['max']:
             stat['max'] = i
-    return stat
+    return stat
+
+
+class OnlineList(ListWidget):
+    admin = site.get_action('online')
+    id = 'list'
+    columns=(
+             ('owner', _("Session Owner")),
+             ('start', _("Session Start"), 25),
+             ('last', _("Last Click"), 25),
+             )
+    default_sorting = 'start'
+    sortables={
+               'start': 0,
+               'last': 0,
+              }
+    hide_actions = True
+    pagination = 50
+    search_form = SearchSessionsForm
+    empty_message = _('Looks like nobody is currently online on forums.')
+    
+    def set_filters(self, model, filters):
+        if 'username' in filters:
+            model = model.filter(user__username__istartswith=filters['username'])
+        if 'ip_address' in filters:
+            model = model.filter(ip__startswith=filters['ip_address'])
+        if 'useragent' in filters:
+            model = model.filter(agent__icontains=filters['useragent'])
+        if filters['type'] == 'registered':
+            model = model.filter(user__isnull=False)
+        if filters['type'] == 'hidden':
+            model = model.filter(hidden=True)
+        if filters['type'] == 'guest':
+            model = model.filter(user__isnull=True)
+        if filters['type'] == 'crawler':
+            model = model.filter(crawler__isnull=False)
+        return model
+    
+    def prefetch_related(self, items):
+        return items.prefetch_related('user')
+    
+    def select_items(self, items):
+        return items.filter(matched=1).filter(admin=0)

+ 2 - 0
misago/users/admin/__init__.py

@@ -40,6 +40,7 @@ ADMIN_ACTIONS=(
                route='admin_users',
                urlpatterns=patterns('misago.users.admin.users.views',
                         url(r'^$', 'List', name='admin_users'),
+                        url(r'^(?P<page>\d+)/$', 'List', name='admin_users'),
                         url(r'^inactive/$', 'inactive', name='admin_users_inactive'),
                         url(r'^new/$', 'List', name='admin_users_new'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_users_edit'),
@@ -103,6 +104,7 @@ ADMIN_ACTIONS=(
                route='admin_users_bans',
                urlpatterns=patterns('misago.banning.admin.views',
                         url(r'^$', 'List', name='admin_users_bans'),
+                        url(r'^(?P<page>\d+)/$', 'List', name='admin_users_bans'),
                         url(r'^new/$', 'New', name='admin_users_bans_new'),
                         url(r'^edit/(?P<target>\d+)/$', 'Edit', name='admin_users_bans_edit'),
                         url(r'^delete/(?P<target>\d+)/$', 'Delete', name='admin_users_bans_delete'),

+ 0 - 3
misago/users/admin/ranks/views.py

@@ -17,9 +17,6 @@ def reverse(route, target=None):
 Views
 """
 class List(ListWidget):
-    """
-    List Users
-    """
     admin = site.get_action('ranks')
     id = 'list'
     columns=(

+ 3 - 3
templates/admin/admin/list.html

@@ -21,14 +21,14 @@
       {%- else -%}
       {{ url ~ query(sort=column[0],dir=sorting[column[0]]) }}
       {%- endif %}">{{ column[1] }}</a>{% else %}{{ column[1] }}{% endif %}</th>{% endfor %}{% endblock %}
-      <th>{% trans %}Actions{% endtrans %}</th>
-      {% if list_form %}<th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>{% endif %}
+      {% if not action.hide_actions%}<th>{% trans %}Actions{% endtrans %}</th>{% endif -%}
+      {% if list_form %}<th class="check-cell"><label class="checkbox"><input type="checkbox" class="checkbox-master"></label></th>{% endif -%}
     </tr>
   </thead>
   <tbody>{% for item in items %}
     <tr>{% block table_row scoped %}{% for column in action.columns %}
       <td{% if loop.first %} class="lead-cell{% if column[3] is defined %} span{{ widthratio(column[3], 100, 12) }}{% endif %}"{% elif column[3] is defined %} class="span{{ widthratio(column[3], 100, 12) }}"{% endif %}>{{ item[column[0]] }}</td>{% endfor %}{% endblock %}
-      {%- if not hide_actions%}
+      {%- if not action.hide_actions%}
       <td class="span2">
       	{%- set item_actions = action.get_item_actions(request, item) -%}
       	{% if item_actions -%}

+ 0 - 76
templates/admin/overview/forums.html

@@ -1,76 +0,0 @@
-{% extends "admin/layout.html" %}
-{% load i18n %}
-{% load humanize %}
-{% load url from future %}
-{% from "admin/macros.html" import page_title %}
-{% from "admin/overview/plot.html" import draw_plot_tooltips, draw_plot with context %}
-
-{% block title %}{{ page_title(title=_('Forums Overview')) }}{% endblock %}
-
-{% block content %}
-<div class="page-header">
-  <h1>{% trans %}Forums Overview{% endtrans %} <small></small></h1>
-</div>
-
-<div class="row">
-  <div class="span6">
-  	<h2 style="text-align: center;">{{ posts|intcomma }}
-  	<small>{% trans %}Posts{% endtrans %}</small></h2>
-  </div>
-  <div class="span6">
-  	<h2 style="text-align: center;">{{ threads|intcomma }}
-  	<small>{% trans %}Threads{% endtrans %}</small></h2>
-  </div>
-</div>
-
-<hr>
-
-<h2>New Posts</h2>
-<div class="graph">
-  <canvas id="graph-posts" height="150px"></canvas>
-  {{ draw_plot_tooltips('graph-posts', graph_posts) }}
-  <div class="timeline">
-    <div class="pull-left">{{ graph_posts.start|date }}</div>
-    <div class="pull-right">{{ graph_posts.end|date(graph_posts.format) }}</div>
-  </div>
-</div>
-<p class="sub-graph pull-right">{% trans count=graph_posts.total|int, total=graph_posts.total|intcomma -%}One new post found in period requested
-{%- pluralize -%}
-{{ total }} new posts found in period requested
-{%- endtrans %}</p>
-<ul class="nav nav-pills sub-graph">
-  <li{% if mode == "day" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview' %}">{% trans %}Last 24h{% endtrans %}</a></li>
-  <li{% if mode == "week" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_week' %}">{% trans %}Last Week{% endtrans %}</a></li>
-  <li{% if mode == "month" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_month' %}">{% trans %}Last Month{% endtrans %}</a></li>
-  <li{% if mode == "year" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_year' %}">{% trans %}Last Year{% endtrans %}</a></li>
-</ul>
-
-<hr>
-
-<h2>New Threads</h2>
-<div class="graph">
-  <canvas id="graph-threads" height="150px"></canvas>
-  {{ draw_plot_tooltips('graph-threads', graph_threads) }}
-  <div class="timeline">
-    <div class="pull-left">{{ graph_threads.start|date }}</div>
-    <div class="pull-right">{{ graph_threads.end|date(graph_threads.format) }}</div>
-  </div>
-</div>
-<p class="sub-graph pull-right">{% trans count=graph_threads.total|int, total=graph_threads.total|intcomma -%}One new thread found in period requested
-{%- pluralize -%}
-{{ total }} new threads found in period requested
-{%- endtrans %}</p>
-<ul class="nav nav-pills sub-graph">
-  <li{% if mode == "day" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview' %}">{% trans %}Last 24h{% endtrans %}</a></li>
-  <li{% if mode == "week" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_week' %}">{% trans %}Last Week{% endtrans %}</a></li>
-  <li{% if mode == "month" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_month' %}">{% trans %}Last Month{% endtrans %}</a></li>
-  <li{% if mode == "year" %} class="active"{% endif %}><a href="{% url 'admin_forums_overview_year' %}">{% trans %}Last Year{% endtrans %}</a></li>
-</ul>
-{% endblock %}
-
-{% block javascripts %}
-<script type="text/javascript">
-  {{ draw_plot('draw_posts', 'graph-posts', graph_posts.max, graph_posts.stat) }}
-  {{ draw_plot('draw_threads', 'graph-threads', graph_threads.max, graph_threads.stat) }}
-</script>
-{% endblock %}

+ 1 - 1
templates/admin/overview/stats/graph.html

@@ -3,7 +3,7 @@
 
 {% import "admin/messages.html" as messages_theme %}
 {% import "_forms.html" as form_theme with context %}
-{% from "admin/overview/plot.html" import draw_plot_tooltips, draw_plot with context %}
+{% from "admin/overview/stats/plot.html" import draw_plot_tooltips, draw_plot with context %}
 
 {% block title %}{{ page_title(title=title, parent=_('Stats')) }}{% endblock %}
 

+ 0 - 0
templates/admin/overview/plot.html → templates/admin/overview/stats/plot.html


+ 0 - 68
templates/admin/overview/system.html

@@ -1,68 +0,0 @@
-{% extends "admin/layout.html" %}
-{% load i18n %}
-{% load humanize %}
-{% load url from future %}
-{% from "admin/macros.html" import page_title %}
-
-{% block title %}{{ page_title(title=_('System Overview')) }}{% endblock %}
-
-{% block content %}
-<div class="page-header">
-  <h1>{% trans %}System Overview{% endtrans %} <small>{% trans %}Misago {{version}}{% endtrans %}</small></h1>
-</div>
-<div class="row">
-  <div class="span4">
-  	<div class="well well-small">
-  	  <h1 style="text-align: center;">{{ users|intcomma }}
-  	  <small>{% trans %}Users{% endtrans %}</small></h1>
-    </div>
-  </div>
-  <div class="span4">
-  	<div class="well well-small">
-  	  <h1 style="text-align: center;">{{ posts|intcomma }}
-  	  <small>{% trans %}Posts{% endtrans %}</small></h1>
-    </div>
-  </div>
-  <div class="span4">
-  	<div class="well well-small">
-  	  <h1 style="text-align: center;">{{ threads|intcomma }}
-  	  <small>{% trans %}Threads{% endtrans %}</small></h1>
-  	</div>
-  </div>
-</div>
-
-<hr>
-
-<h2>{% trans %}Administrators Online{% endtrans %} <small>{{ admins|length|intcomma }}</small></h2>
-<div class="row list-tiny">{% for session in admins %}
-  <div class="span2 popover-admin-{{ loop.index }} clickable">
-  	<img src="{{ session.user.get_avatar() }}" class="avatar-tiny"> {{ session.user.username }}
-  </div>{% endfor %}
-</div>
-{% endblock %}
-
-{% block javascripts %}{% if admins %}
-<script type="text/javascript">
-  $(function () {
-  	// Register popovers for admin list{% for session in admins %}
-	$('.popover-admin-{{ loop.index }}').popover({
-		placement: 'top',
-		trigger:   'click',
-		title:     '{{ popover_title(session)|escapejs }}',
-		content:   '{{ popover_content(session)|escapejs }}'
-	});{% endfor %}
-  });
-</script>{% endif %}
-{% endblock %}
-
-{% macro popover_title(session) -%}
-  <div class="user-card">
-  	<img src="{{ session.user.get_avatar() }}" class="avatar-small">
-    {{ session.user.username }}
-  </div>
-{%- endmacro %}
-
-{% macro popover_content(session) -%}
-    <strong>{% trans last_action=session.last|timesince, ip=session.ip %}{{ last_action }} ago from {{ ip }}{% endtrans %}</strong>
-    <p>{{ session.agent }}</p>
-{%- endmacro %}

+ 0 - 81
templates/admin/overview/users.html

@@ -1,81 +0,0 @@
-{% extends "admin/layout.html" %}
-{% load i18n %}
-{% load humanize %}
-{% load url from future %}
-{% from "admin/macros.html" import page_title %}
-{% from "admin/overview/plot.html" import draw_plot_tooltips, draw_plot with context %}
-
-{% block title %}{{ page_title(title=_('Users Overview')) }}{% endblock %}
-
-{% block content %}
-<div class="page-header">
-  <h1>{% trans %}Users Overview{% endtrans %} <small>{% trans count=users|int, total=users|intcomma -%}One user registered
-{%- pluralize -%}
-{{ total }} users registered
-{%- endtrans %}</small></h1>
-</div>
-
-<div class="alert alert-error">
-  <div class="alert-icon"><span><i class="icon-fire icon-white"></i></span></div>
-  <p><strong>13 user accounts are awaiting activation.</strong></p>
-  <p class="protip"><a href="">{% trans %}Click here to go to inactive users list.{% endtrans %}</a></p>
-</div>
-
-<h2>User Registrations</h2>
-<div class="graph">
-  <canvas id="graph-users" height="150px"></canvas>
-  {{ draw_plot_tooltips('graph-users', graph) }}
-  <div class="timeline">
-    <div class="pull-left">{{ graph.start|date }}</div>
-    <div class="pull-right">{{ graph.end|date(graph.format) }}</div>
-  </div>
-</div>
-<p class="sub-graph pull-right">{% trans count=graph.total|int, total=graph.total|intcomma -%}One registration found in period requested
-{%- pluralize -%}
-{{ total }} registrations found in period requested
-{%- endtrans %}</p>
-<ul class="nav nav-pills sub-graph">
-  <li{% if mode == "day" %} class="active"{% endif %}><a href="{% url 'admin_users_overview' %}">{% trans %}Last 24h{% endtrans %}</a></li>
-  <li{% if mode == "week" %} class="active"{% endif %}><a href="{% url 'admin_users_overview_week' %}">{% trans %}Last Week{% endtrans %}</a></li>
-  <li{% if mode == "month" %} class="active"{% endif %}><a href="{% url 'admin_users_overview_month' %}">{% trans %}Last Month{% endtrans %}</a></li>
-  <li{% if mode == "year" %} class="active"{% endif %}><a href="{% url 'admin_users_overview_year' %}">{% trans %}Last Year{% endtrans %}</a></li>
-</ul>
-
-<hr>
-
-<h2>{% trans %}Staff Online{% endtrans %} <small>{{ staff|length|intcomma }}</small></h2>{% if staff %}
-<div class="row list-tiny">{% for session in staff %}
-  <div class="span2 popover-staff-{{ loop.index }} clickable">
-  	<img src="{{ session.user.get_avatar() }}" class="avatar-tiny"> {{ session.user.username }}
-  </div>{% endfor %}
-</div>{% else %}
-<p>{% trans %}No staff members are currently browsing forums.{% endtrans %}</p>
-{% endif %}
-{% endblock %}
-
-{% block javascripts %}
-<script type="text/javascript">{% if staff %}
-  $(function () {
-  	// Register popovers{% for session in staff %}
-	$('.popover-staff-{{ loop.index }}').popover({
-		placement: 'top',
-		trigger:   'click',
-		title:     '{{ popover_title(session)|escapejs }}',
-		content:   '{{ popover_content(session)|escapejs }}'
-	});{% endfor %}
-  });{% endif %}
-  {{ draw_plot('draw_users', 'graph-users', graph.max, graph.stat) }}
-</script>
-{% endblock %}
-
-{% macro popover_title(session) -%}
-  <div class="user-card">
-  	<img src="{{ session.user.get_avatar() }}" class="avatar-small">
-    {{ session.user.username }}
-  </div>
-{%- endmacro %}
-
-{% macro popover_content(session) -%}
-    <strong>{% trans last_action=session.last|timesince, ip=session.ip %}{{ last_action }} ago from {{ ip }}{% endtrans %}</strong>
-    <p>{{ session.agent }}</p>
-{%- endmacro %}

+ 27 - 0
templates/admin/sessions/list.html

@@ -0,0 +1,27 @@
+{% extends "admin/admin/list.html" %}
+{% load i18n %}
+{% load l10n %}
+{% load url from future %}
+
+{% block table_row scoped %}
+  <td>
+  	<strong class="lead{% if not item.user %} muted{% endif %}">{% if item.user -%}
+  	<a href="{% url 'user' username=item.user.username_slug, user=item.user.id %}">{{ item.user.username }}</a>
+  	{%- elif item.crawler -%}
+  	{{ item.crawler }}
+  	{%- else -%}
+  	{% trans %}Guest{% endtrans %}
+  	{%- endif %}</strong> {% if item.user -%}
+  	<span class="label label-success">{% trans %}Registered Member{% endtrans %}</span>{% if item.hitten %} <span class="label label-info">{% trans %}Hidden{% endtrans %}</span>{% endif %}
+  	{%- elif item.crawler -%}
+  	<span class="label label-inverse">{% trans %}Crawler{% endtrans %}</span>
+  	{%- endif %}
+  	<div class="muted"><strong>{{ item.ip }}</strong>; {{ item.agent }}</div>
+  </td>
+  <td>
+  	{{ item.start|date(f.DATETIME_FORMAT) }}
+  </td>
+  <td>
+  	{{ item.last|date(f.TIME_FORMAT) }}
+  </td>
+{% endblock %}