forked from karthikrish/django-utils
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Another go at modeling, starting work on the javascript...man, I'm
pretty clueless about javascript.
- Loading branch information
Showing
8 changed files
with
144 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from djutils.utils.helpers import generic_autodiscover | ||
|
||
|
||
def autodiscover(): | ||
return generic_autodiscover('panels') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,16 @@ | ||
from django.contrib import admin | ||
|
||
from djutils.dashboard.models import PanelData | ||
from djutils.dashboard.models import Panel, PanelData | ||
|
||
|
||
class PanelAdmin(admin.ModelAdmin): | ||
list_display = ('title', 'panel_type',) | ||
|
||
|
||
class PanelDataAdmin(admin.ModelAdmin): | ||
date_hierarchy = 'created_date' | ||
list_filter = ('panel_type', 'panel_title',) | ||
list_filter = ('panel',) | ||
|
||
|
||
admin.site.register(Panel, PanelAdmin) | ||
admin.site.register(PanelData, PanelDataAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,106 @@ | ||
import datetime | ||
try: | ||
import cPickle as pickle | ||
except ImportError: | ||
import pickle | ||
|
||
from django.db import models | ||
from django.db.models import Max | ||
from django.template.defaultfilters import slugify | ||
|
||
from djutils.dashboard.provider import PANEL_PROVIDER_TYPES | ||
from djutils.dashboard.registry import registry | ||
|
||
|
||
class PanelDataManager(models.Manager): | ||
def get_distinct_titles(self): | ||
return self.values_list('panel_title', flat=True).order_by().distinct() | ||
|
||
def get_latest(self, max_ids=None): | ||
payload = {} | ||
PANEL_PROVIDER_GRAPH = 0 | ||
PANEL_PROVIDER_TEXT = 1 | ||
|
||
PANEL_PROVIDER_TYPES = ( | ||
(PANEL_PROVIDER_GRAPH, 'Graph'), | ||
(PANEL_PROVIDER_TEXT, 'Text'), | ||
) | ||
|
||
|
||
class PanelManager(models.Manager): | ||
def update_panels(self): | ||
data = [] | ||
shared_now = datetime.datetime.now() | ||
|
||
# function to sort the panels by priority | ||
key = lambda obj: obj.get_priority() | ||
|
||
for title in self.get_distinct_titles(): | ||
payload[title] = self.get_latest_by_title( | ||
panel_title=title, | ||
max_id=max_ids and max_ids.get(panel_title) or None | ||
for provider in sorted(registry.get_provider_instances(), key=key): | ||
# pull the data off the panel and store | ||
panel_obj = provider.get_panel_instance() | ||
|
||
panel_data = PanelData.objects.create( | ||
panel=panel_obj, | ||
data=pickle.dumps(provider.get_data()), | ||
created_date=shared_now, | ||
) | ||
data.append(panel_data) | ||
|
||
return payload | ||
return data | ||
|
||
def get_latest_by_title(self, panel_title, limit=50, max_id=None): | ||
qs = self.filter(panel_title=panel_title) | ||
|
||
if max_id: | ||
qs = qs.filter(id__gt=max_id) | ||
|
||
qs = qs[:limit] | ||
|
||
agg_qs = qs.aggregate(max_id=models.Max('id')) | ||
|
||
return { | ||
'queryset': qs, | ||
'max_id': agg_qs['max_id'], | ||
} | ||
def get_panels(self): | ||
"""\ | ||
Purpose is to get a queryset of panel models matching the registered | ||
panel providers | ||
""" | ||
return self.filter(title__in=registry.get_titles()) | ||
|
||
def get_latest_of_each(self): | ||
# I'm not 100% certain if this is the most efficient way to do this | ||
# query, as I believe it has On**2 complexity -- an alternative would | ||
# simple be to iterate over panel_types and select the latest: | ||
# return [ | ||
# self.filter(panel_title=t)[0] \ | ||
# for t in self.get_distinct_titles() | ||
# ] | ||
return self.raw(""" | ||
SELECT pd.* | ||
FROM ( | ||
SELECT panel_title, max(created_date) AS max_date | ||
FROM %(db_table)s GROUP BY panel_title | ||
) AS subq | ||
INNER JOIN %(db_table)s AS pd ON ( | ||
pd.panel_title = subq.panel_title AND | ||
pd.created_date = max_date | ||
) | ||
""" % {'db_table': self.model._meta.db_table}) | ||
def get_latest(self): | ||
"""\ | ||
Get the latest panel data for the registered panel providers | ||
""" | ||
return [ | ||
PanelData.objects.filter(panel=panel)[0] \ | ||
for panel in self.get_panels() | ||
] | ||
|
||
|
||
class Panel(models.Model): | ||
title = models.CharField(max_length=255, unique=True) | ||
slug = models.SlugField(db_index=True) | ||
panel_type = models.IntegerField(choices=PANEL_PROVIDER_TYPES) | ||
|
||
class Meta: | ||
ordering = ('title',) | ||
|
||
objects = PanelManager() | ||
|
||
def save(self, *args, **kwargs): | ||
self.slug = slugify(self.title) | ||
super(Panel, self).save(*args, **kwargs) | ||
|
||
|
||
class PanelDataManager(models.Manager): | ||
def get_most_recent_update(self): | ||
return self.aggregate(max_date=Max('created_date'))['max_date'] | ||
|
||
def get_data(self, panel, limit=None): | ||
queryset = self.filter(panel=panel) | ||
if limit: | ||
queryset = queryset[:limit] | ||
|
||
return queryset, queryset.aggregate(max_id=Max('id'))['max_id'] | ||
|
||
|
||
class PanelData(models.Model): | ||
""" | ||
Preserve historical data from dashboard. Automatically deleted by the | ||
periodic command :func:`remove_old_panel_data` | ||
""" | ||
panel = models.ForeignKey(Panel, related_name='data') | ||
created_date = models.DateTimeField(db_index=True) | ||
panel_title = models.CharField(max_length=255) | ||
panel_data = models.TextField() | ||
panel_type = models.IntegerField(choices=PANEL_PROVIDER_TYPES) | ||
data = models.TextField() | ||
|
||
objects = PanelDataManager() | ||
|
||
class Meta: | ||
ordering = ('-created_date',) | ||
|
||
def __unicode__(self): | ||
return '%s: %s' % (self.panel_title, self.created_date) | ||
return '%s: %s' % (self.panel.title, self.created_date) | ||
|
||
def get_data(self): | ||
return pickle.loads(str(self.panel_data)) | ||
return pickle.loads(str(self.data)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.