diff --git a/.gitignore b/.gitignore index 81aa6085e..534a71005 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .DS_Store *_enterprise.* .settings/ +.ipynb_checkpoints # Debian buildings *.debhelper* diff --git a/server/src/notebook/.ipynb_checkpoints/Ploting-checkpoint.ipynb b/server/src/notebook/.ipynb_checkpoints/Ploting-checkpoint.ipynb new file mode 100644 index 000000000..ea2e3eed7 --- /dev/null +++ b/server/src/notebook/.ipynb_checkpoints/Ploting-checkpoint.ipynb @@ -0,0 +1,733 @@ +{ + "metadata": { + "name": "", + "signature": "sha256:0eaa86575e49c9b9d2e8744c96abbde2f5fbef5baabb72d448ebf3974044ec3b" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "code", + "collapsed": false, + "input": [ + "cd ..\n", + "from django import setup\n", + "\n", + "setup()\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider HyperVPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider oVirtPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider PhysicalMachinesServiceProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider SampleProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider TestProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider VmwareVCServiceProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider XenPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinuxManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinRandomPasswordManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WindowsManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WinDomainManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WinRandomPasswordManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinuxManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WindowsManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport HTML5RDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport NXTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TSNXTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport RDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TSRDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport RGSTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TRGSTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.dispatchers:Dispatchers initialized\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.plugins:Initializing plugins\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Loading Handlers\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method actor in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method users in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method groups in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method services in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method cachedservice in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method groups in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method transports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method publications in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method authenticators in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method images in path gallery\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method networks in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method osmanagers in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method providers in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method servicespools in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method transports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method reports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method cache in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method client in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method config in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method connection in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method callback in path gui\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method login in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method logout in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method auths in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method permissions in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method system in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method tickets in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds:Initializing app (ready) ***************\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 5, + "text": [ + "u'm/d/Y'" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from django.template.defaultfilters import date\n", + "from django.utils.formats import get_format\n", + "\n", + "import datetime\n", + "\n", + "date(datetime.datetime.now(), get_format('SHORT_DATETIME_FORMAT'))" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 8, + "text": [ + "u'05/04/2015 5:39 a.m.'" + ] + } + ], + "prompt_number": 8 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# execute from django home\n", + "from __future__ import unicode_literals\n", + "\n", + "from django.utils.translation import ugettext, ugettext_noop as _\n", + "from django.utils import formats\n", + "import django.template.defaultfilters as filters\n", + "\n", + "from uds.core.util.stats import events\n", + "\n", + "import datetime\n", + "import cairo\n", + "import pycha.line\n", + "\n", + "from PIL import Image as PILImage\n", + "import StringIO\n", + "\n", + "# Width & heighth\n", + "width, height = 1920, 1080\n", + "# x axis label format\n", + "\n", + "start, end, samplingPoints = 1420066800, 1451516400, 64\n", + "\n", + "if end - start > 3600*24*2:\n", + " xLabelFormat = formats.get_format('SHORT_DATE_FORMAT')\n", + "else:\n", + " xLabelFormat = formats.get_format('SHORT_DATETIME_FORMAT')\n", + "\n", + "samplingIntervals = []\n", + "prevVal = None\n", + "for val in range(start, end, (end - start) / (samplingPoints + 1)):\n", + " if prevVal is None:\n", + " prevVal = val\n", + " continue\n", + " samplingIntervals.append((prevVal, val))\n", + " prevVal = val\n", + "\n", + "data = []\n", + "for interval in samplingIntervals:\n", + " key = (interval[0] + interval[1]) / 2\n", + " data.append((key, events.statsManager().getEvents(events.OT_AUTHENTICATOR, events.ET_LOGIN, since=interval[0], to=interval[1]).count())) # @UndefinedVariable\n", + "\n", + "surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)\n", + "\n", + "dataset = (('Users access to UDS', data),)\n", + "\n", + "options = {\n", + " 'encoding': 'utf-8',\n", + " 'axis': {\n", + " 'x': {\n", + " 'ticks': [dict(v=i, label=filters.date(datetime.datetime.fromtimestamp(i), xLabelFormat)) for i in range(start, end, (end-start)/11)],\n", + " 'range': (start, end),\n", + " 'showLines': True,\n", + " },\n", + " 'y': {\n", + " 'tickCount': 10,\n", + " 'showLines': True,\n", + " },\n", + " 'tickFontSize': 16,\n", + " },\n", + " 'background': {\n", + " 'chartColor': '#ffffff',\n", + " 'baseColor': '#ffffff',\n", + " 'lineColor': '#187FF2'\n", + " },\n", + " 'colorScheme': {\n", + " 'name': 'gradient',\n", + " 'args': {\n", + " 'initialColor': '#B8CA16',\n", + " },\n", + " },\n", + " 'legend': {\n", + " 'hide': False,\n", + " 'legendFontSize': 16,\n", + " 'position': {\n", + " 'left': 48,\n", + " 'bottom': 8,\n", + " }\n", + " },\n", + " 'padding': {\n", + " 'left': 48,\n", + " 'top': 16,\n", + " 'right': 48,\n", + " 'bottom': 48,\n", + " },\n", + " 'title': _('Users usage of UDS')\n", + "}\n", + "\n", + "chart = pycha.line.LineChart(surface, options)\n", + "chart.addDataset(dataset)\n", + "chart.render()\n", + "\n", + "output = StringIO.StringIO()\n", + "\n", + "surface.write_to_png(output)\n", + "\n", + "im = PILImage.frombuffer(\"RGBA\",( surface.get_width(),surface.get_height() ),surface.get_data(),\"raw\",\"BGRA\",0,1)\n", + "im.save('/tmp/out2.png')\n", + "\n", + "surface.write_to_png('/tmp/out.png')" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 64 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [], + "language": "python", + "metadata": {}, + "outputs": [] + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/server/src/notebook/Ploting.ipynb b/server/src/notebook/Ploting.ipynb new file mode 100644 index 000000000..017a6a05b --- /dev/null +++ b/server/src/notebook/Ploting.ipynb @@ -0,0 +1,757 @@ +{ + "metadata": { + "name": "", + "signature": "sha256:229db3f9737c56e76d4edea1eae84b07d1acd301ecfb4eed6b4fadf15cce4793" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "code", + "collapsed": false, + "input": [ + "cd .." + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "/home/dkmaster/projects/uds/openuds/server/src\n" + ] + } + ], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from django import setup\n", + "\n", + "setup()\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider HyperVPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider oVirtPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider PhysicalMachinesServiceProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider SampleProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider TestProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider VmwareVCServiceProvider as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.services.ServiceProviderFactory:Adding provider XenPlatform as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinuxManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinRandomPasswordManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WindowsManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WinDomainManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WinRandomPasswordManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager LinuxManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.osmanagers.OSManagersFactory:Adding OS Manager WindowsManager as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport HTML5RDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport NXTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TSNXTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport RDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TSRDPTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport RGSTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.core.transports.TransportsFactory:Adding transport TRGSTransport as \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.dispatchers:Dispatchers initialized\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.plugins:Initializing plugins\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Loading Handlers\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method actor in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method users in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method groups in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method services in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method cachedservice in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method groups in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method transports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method publications in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method authenticators in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method images in path gallery\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method networks in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method osmanagers in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method providers in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method servicespools in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method transports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method reports in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method cache in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method client in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method config in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method connection in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method callback in path gui\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method login in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method logout in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method auths in path auth\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method permissions in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method system in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Found class \n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds.REST:Adding handler for method tickets in path None\n" + ] + }, + { + "output_type": "stream", + "stream": "stderr", + "text": [ + "DEBUG:uds:Initializing app (ready) ***************\n" + ] + } + ], + "prompt_number": 4 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from django.template.defaultfilters import date\n", + "from django.utils.formats import get_format\n", + "\n", + "import datetime\n", + "\n", + "date(datetime.datetime.now(), get_format('SHORT_DATETIME_FORMAT'))" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 5, + "text": [ + "u'05/05/2015 5:59 a.m.'" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# execute from django home\n", + "from __future__ import unicode_literals\n", + "\n", + "from django.utils.translation import ugettext, ugettext_noop as _\n", + "from django.utils import formats\n", + "import django.template.defaultfilters as filters\n", + "\n", + "from uds.core.util.stats import events\n", + "\n", + "import datetime\n", + "import cairo\n", + "import pycha.line\n", + "\n", + "from PIL import Image as PILImage\n", + "import StringIO\n", + "\n", + "# Width & heighth\n", + "width, height = 1920, 1080\n", + "# x axis label format\n", + "\n", + "start, end, samplingPoints = 1420066800, 1451516400, 64\n", + "\n", + "if end - start > 3600*24*2:\n", + " xLabelFormat = formats.get_format('SHORT_DATE_FORMAT')\n", + "else:\n", + " xLabelFormat = formats.get_format('SHORT_DATETIME_FORMAT')\n", + "\n", + "samplingIntervals = []\n", + "prevVal = None\n", + "for val in range(start, end, (end - start) / (samplingPoints + 1)):\n", + " if prevVal is None:\n", + " prevVal = val\n", + " continue\n", + " samplingIntervals.append((prevVal, val))\n", + " prevVal = val\n", + "\n", + "data = []\n", + "for interval in samplingIntervals:\n", + " key = (interval[0] + interval[1]) / 2\n", + " data.append((key, events.statsManager().getEvents(events.OT_AUTHENTICATOR, events.ET_LOGIN, since=interval[0], to=interval[1]).count())) # @UndefinedVariable\n", + "\n", + "surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)\n", + "\n", + "dataset = (('Users access to UDS', data),)\n", + "\n", + "options = {\n", + " 'encoding': 'utf-8',\n", + " 'axis': {\n", + " 'x': {\n", + " 'ticks': [dict(v=i, label=filters.date(datetime.datetime.fromtimestamp(i), xLabelFormat)) for i in range(start, end, (end-start)/11)],\n", + " 'range': (start, end),\n", + " 'showLines': True,\n", + " },\n", + " 'y': {\n", + " 'tickCount': 10,\n", + " 'showLines': True,\n", + " },\n", + " 'tickFontSize': 16,\n", + " },\n", + " 'background': {\n", + " 'chartColor': '#ffffff',\n", + " 'baseColor': '#ffffff',\n", + " 'lineColor': '#187FF2'\n", + " },\n", + " 'colorScheme': {\n", + " 'name': 'gradient',\n", + " 'args': {\n", + " 'initialColor': '#B8CA16',\n", + " },\n", + " },\n", + " 'legend': {\n", + " 'hide': False,\n", + " 'legendFontSize': 16,\n", + " 'position': {\n", + " 'left': 48,\n", + " 'bottom': 8,\n", + " }\n", + " },\n", + " 'padding': {\n", + " 'left': 48,\n", + " 'top': 16,\n", + " 'right': 48,\n", + " 'bottom': 48,\n", + " },\n", + " 'title': _('Users usage of UDS')\n", + "}\n", + "\n", + "chart = pycha.line.LineChart(surface, options)\n", + "chart.addDataset(dataset)\n", + "chart.render()\n", + "\n", + "output = StringIO.StringIO()\n", + "\n", + "surface.write_to_png(output)\n", + "\n", + "im = PILImage.frombuffer(\"RGBA\",( surface.get_width(),surface.get_height() ),surface.get_data(),\"raw\",\"BGRA\",0,1)\n", + "#im.save('/tmp/out2.png')\n", + "\n", + "#surface.write_to_png('/tmp/out.png')" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 69 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "im.size" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'im' is not defined", + "output_type": "pyerr", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'im' is not defined" + ] + } + ], + "prompt_number": 1 + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/server/src/uds/core/managers/StatsManager.py b/server/src/uds/core/managers/StatsManager.py index c55d719ee..224132365 100644 --- a/server/src/uds/core/managers/StatsManager.py +++ b/server/src/uds/core/managers/StatsManager.py @@ -176,7 +176,7 @@ class StatsManager(object): logger.exception('Exception handling event stats saving (maybe database is full?)') return False - def getEvents(self, ownerType, eventType, ownerId, since, to): + def getEvents(self, ownerType, eventType, **kwargs): ''' Retrieves counters from item @@ -191,11 +191,7 @@ class StatsManager(object): Iterator, containing (date, counter) each element ''' - # To Unix epoch - since = int(time.mktime(since.timetuple())) - to = int(time.mktime(to.timetuple())) - - return StatsEvents.get_stats(ownerType, eventType, owner_id=ownerId, since=since, to=to) + return StatsEvents.get_stats(ownerType, eventType, **kwargs) def cleanupEvents(self): ''' diff --git a/server/src/uds/core/ui/UserInterface.py b/server/src/uds/core/ui/UserInterface.py index 7d9294436..00b60d9b7 100644 --- a/server/src/uds/core/ui/UserInterface.py +++ b/server/src/uds/core/ui/UserInterface.py @@ -360,7 +360,9 @@ class gui(object): def __init__(self, **options): super(self.__class__, self).__init__(**options) minValue = options.get('minValue', '987654321') + maxValue = options.get('maxValue', '987654321') self._data['minValue'] = int(minValue) + self._data['maxValue'] = int(maxValue) self._type(gui.InputField.NUMERIC_TYPE) diff --git a/server/src/uds/core/util/tools.py b/server/src/uds/core/util/tools.py index 1a3e1a633..7d4b48f9c 100644 --- a/server/src/uds/core/util/tools.py +++ b/server/src/uds/core/util/tools.py @@ -32,10 +32,15 @@ ''' from __future__ import unicode_literals +from django.utils import formats +import django.template.defaultfilters as filters + +import datetime + import sys import os -__updated__ = '2015-05-03' +__updated__ = '2015-05-04' class DictAsObj(object): @@ -64,3 +69,11 @@ def packageRelativeFile(moduleName, fileName): ''' pkgpath = os.path.dirname(sys.modules[moduleName].__file__) return os.path.join(pkgpath, fileName) + + +def timestampAsStr(stamp, format_='SHORT_DATETIME_FORMAT'): + ''' + Converts a timestamp to date string using specified format (DJANGO format such us SHORT_DATETIME_FORMAT..) + ''' + format_ = formats.get_format(format_) + return filters.date(datetime.datetime.fromtimestamp(stamp), format_) diff --git a/server/src/uds/models/StatsCounters.py b/server/src/uds/models/StatsCounters.py index 4175ab2ed..b211f0cc0 100644 --- a/server/src/uds/models/StatsCounters.py +++ b/server/src/uds/models/StatsCounters.py @@ -33,16 +33,17 @@ from __future__ import unicode_literals -__updated__ = '2015-05-03' - from django.db import models from uds.models.Util import NEVER_UNIX from uds.models.Util import getSqlDatetime - import logging + +__updated__ = '2015-05-04' + + logger = logging.getLogger(__name__) diff --git a/server/src/uds/models/StatsEvents.py b/server/src/uds/models/StatsEvents.py index a51b33039..138a99a56 100644 --- a/server/src/uds/models/StatsEvents.py +++ b/server/src/uds/models/StatsEvents.py @@ -40,7 +40,7 @@ from uds.models.Util import getSqlDatetime import logging -__updated__ = '2015-05-03' +__updated__ = '2015-05-04' logger = logging.getLogger(__name__) @@ -92,7 +92,7 @@ class StatsEvents(models.Model): since = since and int(since) or NEVER_UNIX to = to and int(to) or getSqlDatetime(True) - fltr = fltr.filter(stamp__gte=since, stamp__lte=to) + fltr = fltr.filter(stamp__gte=since, stamp__lt=to) # We use result as an iterator return fltr diff --git a/server/src/uds/reports/lists/users.py b/server/src/uds/reports/lists/users.py index 19e6590b6..c69a68692 100644 --- a/server/src/uds/reports/lists/users.py +++ b/server/src/uds/reports/lists/users.py @@ -51,12 +51,12 @@ import logging logger = logging.getLogger(__name__) -__updated__ = '2015-04-29' +__updated__ = '2015-05-03' class UsersReport(Report): - title = 'Test report' - author = 'UDS Enterprise' + title = '' + author = 'UDS' print_if_empty = True page_size = A4 diff --git a/server/src/uds/reports/stats/login.py b/server/src/uds/reports/stats/login.py index de26c418c..9ef7f7552 100644 --- a/server/src/uds/reports/stats/login.py +++ b/server/src/uds/reports/stats/login.py @@ -32,31 +32,44 @@ ''' from __future__ import unicode_literals -from django.utils.translation import ugettext, ugettext_noop as _ +from django.utils.translation import ugettext, ugettext_lazy as _ +from django.utils import formats +import django.template.defaultfilters as filters + from uds.core.ui.UserInterface import gui from uds.core.reports import stock from uds.models import StatsEvents +from uds.core.util.stats import events + import StringIO +import cairo +import pycha.line + from .base import StatsReport from uds.core.util import tools from geraldo.generators.pdf import PDFGenerator -from geraldo import Report, landscape, ReportBand, ObjectValue, SystemField, BAND_WIDTH, Label, Image +from geraldo import Report, landscape, ReportBand, ObjectValue, SystemField, BAND_WIDTH, Label, Image, SubReport from reportlab.lib.pagesizes import A4 from reportlab.lib.units import cm from reportlab.lib.enums import TA_RIGHT, TA_CENTER +from PIL import Image as PILImage import datetime import logging logger = logging.getLogger(__name__) -__updated__ = '2015-05-03' +__updated__ = '2015-05-04' + +# Width & height +WIDTH, HEIGHT = 1800, 1000 +GERARLDO_WIDTH = 800 +GERALDO_HEIGHT = GERARLDO_WIDTH * HEIGHT / WIDTH -class UsersReport(Report): - title = 'Test report' +class AccessReport(Report): author = 'UDS Enterprise' print_if_empty = True @@ -67,27 +80,24 @@ class UsersReport(Report): margin_bottom = 0.5 * cm class band_detail(ReportBand): - height = 0.5 * cm + height = 10 * cm + auto_expand_height = True elements = ( - ObjectValue(attribute_name='name', left=0.5 * cm), - ObjectValue(attribute_name='real_name', left=3 * cm), - ObjectValue(attribute_name='last_access', left=7 * cm), + Label(text='Users', top=0.6 * cm, left=10 * cm, style={'fontName': 'Helvetica-Bold'}), + Image(get_image=lambda x: x.instance['image'], left=1.0 * cm, top=1.0 * cm, width=GERARLDO_WIDTH, height=GERALDO_HEIGHT, stretch=True), ) class band_page_header(ReportBand): - height = 2.0 * cm + height = 1.8 * cm elements = [ SystemField(expression='%(report_title)s', top=0.5 * cm, left=0, width=BAND_WIDTH, style={'fontName': 'Helvetica-Bold', 'fontSize': 14, 'alignment': TA_CENTER}), - Label(text="User ID", top=1.5 * cm, left=0.5 * cm), - Label(text="Real Name", top=1.5 * cm, left=3 * cm), - Label(text="Last access", top=1.5 * cm, left=7 * cm), SystemField(expression=_('Page %(page_number)d of %(page_count)d'), top=0.1 * cm, width=BAND_WIDTH, style={'alignment': TA_RIGHT}), - Image(filename=stock.getStockImagePath(stock.LOGO), left=0.1 * cm, top=0.0 * cm, width=2 * cm, height=2 * cm), + Image(filename=stock.getStockImagePath(stock.LOGO), left=0.1 * cm, top=0.0 * cm, width=2.0 * cm, height=2.0 * cm), ] - borders = {'bottom': True} + # borders = {'bottom': True} class band_page_footer(ReportBand): height = 0.5 * cm @@ -98,13 +108,35 @@ class UsersReport(Report): ] borders = {'top': True} + subreports = [ + SubReport( + queryset_string='%(object)s["data"]', + band_header=ReportBand( + height=2.5 * cm, + elements=( + Label(text='Date range', top=2.0 * cm, left=4.2 * cm, style={'fontName': 'Helvetica-Bold'}), + Label(text='Users', top=2.0 * cm, left=10 * cm, style={'fontName': 'Helvetica-Bold'}), + ), + borders={'bottom': True} + ), + band_detail=ReportBand( + height=0.5 * cm, + elements=( + ObjectValue(attribute_name='date', top=0, left=4.2 * cm), + ObjectValue(attribute_name='users', top=0, left=10 * cm), + ) + ), + ) + ] + class StatsReportLogin(StatsReport): filename = 'access.pdf' - name = _('Users list') # Report name - description = _('List users of platform') # Report description + name = _('Users access report by date') # Report name + description = _('Report of user access to platform by date') # Report description uuid = '0f62f19a-f166-11e4-8f59-10feed05884b' + # Input fields startDate = gui.DateField( order=1, label=_('Starting date'), @@ -114,13 +146,23 @@ class StatsReportLogin(StatsReport): ) endDate = gui.DateField( - order=1, + order=2, label=_('Finish date'), tooltip=_('finish date for report'), defvalue=datetime.date.max, required=True ) + samplingPoints = gui.NumericField( + order=3, + label=_('Number of points'), + length=3, + minValue=16, + maxValue=128, + tooltip=_('Number of sampling points used in charts'), + defvalue='64' + ) + def initialize(self, values): pass @@ -128,41 +170,112 @@ class StatsReportLogin(StatsReport): pass def generate(self): - # Query: - # SELECT count(*) as number, CEIL(stamp/(3600*24*30))*3600*24*30 as stamp - # FROM `uds_stats_e` - # WHERE `event_type` = 0 and stamp >= 1421888752 and stamp <= 1430638561 - # GROUP BY CEIL(stamp/(3600*24*30)) - # ORDER BY stamp + # Sample query: + # 'SELECT *, count(*) as number, CEIL(stamp/(3600))*3600 as block' + # ' FROM {table}' + # ' WHERE event_type = 0 and stamp >= {start} and stamp <= {end}' + # ' GROUP BY CEIL(stamp/(3600))' + # ' ORDER BY block' - logger.debug('minDate: {}, maxDate: {}'.format(self.startDate.date(), self.endDate.date())) - # Graph will have 12 points, no matter where start & end is - query = ( - 'SELECT *, count(*) as number, CEIL(stamp/(3600*24))*3600*24 as block' - ' FROM {table}' - ' WHERE event_type = 0 and stamp >= {start} and stamp <= {end}' - ' GROUP BY CEIL(stamp/(3600*24))' - ' ORDER BY block' - ).format( - start=self.startDate.stamp(), - end=self.endDate.stamp(), - table=StatsEvents._meta.db_table, # @UndefinedVariable - ) + # Generate the sampling intervals and get data from db + start = self.startDate.stamp() + end = self.endDate.stamp() + samplingPoints = self.samplingPoints.num() - logger.debug('Query: {}'.format(query)) - data = list(StatsEvents.objects.raw(query)) + # x axis label format + if end - start > 3600 * 24 * 2: + xLabelFormat = 'SHORT_DATE_FORMAT' + else: + xLabelFormat = 'SHORT_DATETIME_FORMAT' - logger.debug('StatsEvents: {} -> {}'.format(len(data), data)) + samplingIntervals = [] + prevVal = None + for val in range(start, end, (end - start) / (samplingPoints + 1)): + if prevVal is None: + prevVal = val + continue + samplingIntervals.append((prevVal, val)) + prevVal = val - for v in data: - logger.debug('DATA: {} {}'.format(v.number, datetime.date.fromtimestamp(v.block))) + data = [] + reportData = [] + for interval in samplingIntervals: + key = (interval[0] + interval[1]) / 2 + val = events.statsManager().getEvents(events.OT_AUTHENTICATOR, events.ET_LOGIN, since=interval[0], to=interval[1]).count() + data.append((key, val)) # @UndefinedVariable + reportData.append( + { + 'date': tools.timestampAsStr(interval[0], xLabelFormat) + ' - ' + tools.timestampAsStr(interval[1]), + 'users': val + } + ) - # auth = Authenticator.objects.get(uuid=self.authenticator.value) - # users = auth.users.order_by('name') + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT) + + dataset = (('Users access to UDS', data),) + + options = { + 'encoding': 'utf-8', + 'axis': { + 'x': { + 'ticks': [ + dict(v=i, label=filters.date(datetime.datetime.fromtimestamp(i), xLabelFormat)) for i in range(start, end, (end - start) / 11) + ], + 'range': (start, end), + 'showLines': True, + }, + 'y': { + 'tickCount': 10, + 'showLines': True, + }, + 'tickFontSize': 16, + }, + 'background': { + 'chartColor': '#f0f0f0', + 'baseColor': '#f0f0f0', + 'lineColor': '#187FF2' + }, + 'colorScheme': { + 'name': 'gradient', + 'args': { + 'initialColor': '#B8CA16', + }, + }, + 'legend': { + 'hide': False, + 'legendFontSize': 16, + 'position': { + 'left': 48, + 'bottom': 8, + } + }, + 'padding': { + 'left': 48, + 'top': 16, + 'right': 48, + 'bottom': 48, + }, + 'title': _('Users usage of UDS') + } + + chart = pycha.line.LineChart(surface, options) + chart.addDataset(dataset) + chart.render() + + img = PILImage.frombuffer("RGBA", (surface.get_width(), surface.get_height()), surface.get_data(), "raw", "BGRA", 0, 1) output = StringIO.StringIO() - # report = UsersReport(queryset=users) - # report.title = _('Users List for {}').format(auth.name) - # report.generate_by(PDFGenerator, filename=output) - return output.getvalue() + queryset = [ + {'image': img, 'data': reportData} + ] + + logger.debug(queryset) + + try: + report = AccessReport(queryset=queryset) + # report = UsersReport(queryset=users) + report.generate_by(PDFGenerator, filename=output) + return output.getvalue() + except: + logger.exception('Errool') diff --git a/server/src/uds/static/adm/js/datepicker-locales/bootstrap-datepicker.en.min.js b/server/src/uds/static/adm/js/datepicker-locales/bootstrap-datepicker.en.min.js new file mode 100644 index 000000000..e69de29bb diff --git a/server/src/uds/static/adm/js/gui-form.coffee b/server/src/uds/static/adm/js/gui-form.coffee index 628b49bdf..2fc0ed1d8 100644 --- a/server/src/uds/static/adm/js/gui-form.coffee +++ b/server/src/uds/static/adm/js/gui-form.coffee @@ -45,6 +45,7 @@ html += api.templates.evaluate("tmpl_fld_" + f.gui.type, value: value # If no value present, use default value minValue: f.gui.minValue + maxValue: f.gui.maxValue values: f.gui.values label: f.gui.label length: f.gui.length diff --git a/server/src/uds/static/adm/js/gui-tools.coffee b/server/src/uds/static/adm/js/gui-tools.coffee index 6975fdc5e..3621283d8 100644 --- a/server/src/uds/static/adm/js/gui-tools.coffee +++ b/server/src/uds/static/adm/js/gui-tools.coffee @@ -85,8 +85,11 @@ $.each $(selector + " input[type=numeric]:not([readonly])"), (index, tspn) -> $tspn = $(tspn) minVal = parseInt $tspn.attr("data-minval") + maxVal = parseInt $tspn.attr("data-maxval") if minVal == 987654321 minVal = -999999 + if maxVal == 987654321 + maxVal = 999999 gui.doLog minVal $tspn.attr("type", "text") $tspn.TouchSpin @@ -94,7 +97,7 @@ verticalupclass: 'glyphicon glyphicon-plus' verticaldownclass: 'glyphicon glyphicon-minus' min: minVal - max: 999999 + max: maxVal decimals: 0 # TEST: cooler on mobile devices diff --git a/server/src/uds/templates/uds/admin/tmpl/fld/basic-input.html b/server/src/uds/templates/uds/admin/tmpl/fld/basic-input.html index 0625bce04..affa9c24e 100644 --- a/server/src/uds/templates/uds/admin/tmpl/fld/basic-input.html +++ b/server/src/uds/templates/uds/admin/tmpl/fld/basic-input.html @@ -1,6 +1,6 @@ {% extends "uds/admin/tmpl/fld/form-group.html" %} {% block field %} {% verbatim %} - + {% endverbatim %} {% endblock %} \ No newline at end of file diff --git a/server/src/uds/web/views/js.py b/server/src/uds/web/views/js.py index b2b23f4ae..9cd182615 100644 --- a/server/src/uds/web/views/js.py +++ b/server/src/uds/web/views/js.py @@ -30,16 +30,15 @@ ''' from __future__ import unicode_literals -__updated__ = '2015-02-28' - from django.views.decorators.cache import cache_page from django.views.i18n import javascript_catalog import logging -logger = logging.getLogger(__name__) +__updated__ = '2015-05-04' -__updated__ = '2015-01-28' + +logger = logging.getLogger(__name__) # The value returned by get_version() must change when translations change.