From 8f0a927c3b4ad9b0eaf8cab4f8baf32790a38cbf Mon Sep 17 00:00:00 2001 From: rlagutin Date: Tue, 7 Oct 2014 17:07:00 +0400 Subject: [PATCH] Initial commit --- .gitignore | 2 + api/__init__.py | 0 api/v10/__init__.py | 0 api/v10/urls.py | 12 ++ api/v10/views.py | 94 ++++++++++++ charting_library_charts/__init__.py | 0 charting_library_charts/settings.py | 153 +++++++++++++++++++ charting_library_charts/urls.py | 14 ++ charting_library_charts/wsgi.py | 28 ++++ charts/__init__.py | 0 charts/migrations/0001_initial.py | 26 ++++ charts/migrations/0002_auto_20141007_1601.py | 27 ++++ charts/migrations/__init__.py | 0 charts/models.py | 16 ++ charts/tests.py | 16 ++ manage.py | 10 ++ 16 files changed, 398 insertions(+) create mode 100644 .gitignore create mode 100644 api/__init__.py create mode 100644 api/v10/__init__.py create mode 100644 api/v10/urls.py create mode 100644 api/v10/views.py create mode 100644 charting_library_charts/__init__.py create mode 100644 charting_library_charts/settings.py create mode 100644 charting_library_charts/urls.py create mode 100644 charting_library_charts/wsgi.py create mode 100644 charts/__init__.py create mode 100644 charts/migrations/0001_initial.py create mode 100644 charts/migrations/0002_auto_20141007_1601.py create mode 100644 charts/migrations/__init__.py create mode 100644 charts/models.py create mode 100644 charts/tests.py create mode 100644 manage.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c621b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*sublime* \ No newline at end of file diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/v10/__init__.py b/api/v10/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/v10/urls.py b/api/v10/urls.py new file mode 100644 index 0000000..8b4ae8d --- /dev/null +++ b/api/v10/urls.py @@ -0,0 +1,12 @@ +from django.conf.urls import patterns, url +from . import views + +#GET charts?userid=0&clientid=1 +#GET charts?userid=0&clientid=1&chartid=2 +#DELETE charts?userid=0&clientid=1&chartid=2 +#POST charts?userid=0&clientid=1&chartid=2 +#POST charts?userid=0&clientid=1 + +urlpatterns = patterns('', + url(r'^charts$', views.doTheMagic), +) diff --git a/api/v10/views.py b/api/v10/views.py new file mode 100644 index 0000000..ac3794d --- /dev/null +++ b/api/v10/views.py @@ -0,0 +1,94 @@ +from django.http import HttpResponse +from django.views.decorators.csrf import csrf_exempt +from charts import models +import json +from datetime import datetime +import time + +def error(text): + return HttpResponse(json.dumps({'status': 'error','message': text})) + +@csrf_exempt +def doTheMagic(request): + clientId = request.GET.get('client', '') + + if (clientId == ''): + return error('Wrong client id') + + userId = request.GET.get('user', '') + + if (userId == ''): + return error('Wrong user id') + + chartId = request.GET.get('chart', '') + + if request.method == 'GET': + if chartId == '': + return getAllUserCharts(clientId, userId) + else: + return getChartContent(clientId, userId, chartId) + + elif request.method == 'DELETE': + if chartId == '': + return error('Wrong chart id') + else: + return removeChart(clientId, userId, chartId) + + elif request.method == 'POST': + chartName = request.POST.get('name') + content = request.POST.get('content') + if chartId == '': + return saveChart(clientId, userId, chartName, content) + else: + return rewriteChart(clientId, userId, chartId, chartName, content) + + else: + return error('Wrong request') + + +def response(content): + result = HttpResponse(content) + return result + + +def getAllUserCharts(clientId, userId): + chartsList = models.Chart.objects.filter(ownerSource = clientId, ownerId = userId) + result = map(lambda x : {'id': x.id, 'name': x.name, 'timestamp': time.mktime(x.lastModified.timetuple())} , chartsList) + return response(json.dumps({'status': "ok", 'data': result})) + + +def getChartContent(clientId, userId, chartId): + try: + chart = models.Chart.objects.get(ownerSource = clientId, ownerId = userId, id = chartId) + result = json.dumps({'status': 'ok', 'id': chart.id, 'name': chart.name, 'timestamp': time.mktime(chart.lastModified.timetuple()), 'content': chart.content}) + return response(result) + except: + return error('Chart not found') + + +def removeChart(clientId, userId, chartId): + try: + chart = models.Chart.objects.get(ownerSource = clientId, ownerId = userId, id = chartId) + chart.delete() + return response(json.dumps({'status': 'ok'})) + except: + return error('Chart not found') + + +def saveChart(clientId, userId, chartName, content): + newChart = models.Chart(ownerSource = clientId, ownerId = userId, name = chartName, content = content, lastModified = datetime.utcnow()) + newChart.save() + return response(json.dumps({'status': 'ok', 'id': newChart.id})) + + +def rewriteChart(clientId, userId, chartId, chartName, content): + try: + chart = models.Chart.objects.get(ownerSource = clientId, ownerId = userId, id = chartId) + chart.lastModified = datetime.utcnow() + chart.content = content + chart.name = chartName + + chart.save() + return response(json.dumps({'status': 'ok'})) + except: + return error('Chart not found') \ No newline at end of file diff --git a/charting_library_charts/__init__.py b/charting_library_charts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/charting_library_charts/settings.py b/charting_library_charts/settings.py new file mode 100644 index 0000000..17b6ae0 --- /dev/null +++ b/charting_library_charts/settings.py @@ -0,0 +1,153 @@ +# Django settings for charting_library_charts project. + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@example.com'), +) + +MANAGERS = ADMINS + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'tradingview', + 'USER': 'postgres', + 'PASSWORD': '12345', ### Put your Postgres password here + 'HOST': 'localhost', + 'PORT': '5433', + } +} + + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# In a Windows environment this must be set to your system time zone. +TIME_ZONE = 'America/Chicago' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale. +USE_L10N = True + +# If you set this to False, Django will not use timezone-aware datetimes. +USE_TZ = True + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = '' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = '' + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '/static/' + +# Additional locations of static files +STATICFILES_DIRS = ( + # Put strings here, like "/home/html/static" or "C:/www/django/static". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', +) + +# Make this unique, and don't share it with anybody. +SECRET_KEY = 'c5-%u0l1*(dj@u33!5*o_gtti0)kkh$m%i#@!(!$d%779kaa&b' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + # Uncomment the next line for simple clickjacking protection: + # 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'charting_library_charts.urls' + +# Python dotted path to the WSGI application used by Django's runserver. +WSGI_APPLICATION = 'charting_library_charts.wsgi.application' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +INSTALLED_APPS = ( + #'django.contrib.auth', + #'django.contrib.contenttypes', + #'django.contrib.sessions', + #'django.contrib.sites', + #'django.contrib.messages', + #'django.contrib.staticfiles', + # Uncomment the next line to enable the admin: + # 'django.contrib.admin', + # Uncomment the next line to enable admin documentation: + # 'django.contrib.admindocs', + 'charts', +) + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error when DEBUG=False. +# See http://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': True, + }, + } +} diff --git a/charting_library_charts/urls.py b/charting_library_charts/urls.py new file mode 100644 index 0000000..4f3803e --- /dev/null +++ b/charting_library_charts/urls.py @@ -0,0 +1,14 @@ +from django.conf.urls import patterns, include, url + +# Uncomment the next two lines to enable the admin: +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + url(r'^1\.0/', include('api.v10.urls')), + # Uncomment the admin/doc line below to enable admin documentation: + # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), + + # Uncomment the next line to enable the admin: + # url(r'^admin/', include(admin.site.urls)), +) diff --git a/charting_library_charts/wsgi.py b/charting_library_charts/wsgi.py new file mode 100644 index 0000000..c1b42c2 --- /dev/null +++ b/charting_library_charts/wsgi.py @@ -0,0 +1,28 @@ +""" +WSGI config for charting_library_charts project. + +This module contains the WSGI application used by Django's development server +and any production WSGI deployments. It should expose a module-level variable +named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover +this application via the ``WSGI_APPLICATION`` setting. + +Usually you will have the standard Django WSGI application here, but it also +might make sense to replace the whole Django WSGI application with a custom one +that later delegates to the Django one. For example, you could introduce WSGI +middleware here, or combine a Django application with an application of another +framework. + +""" +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "charting_library_charts.settings") + +# This application object is used by any WSGI server configured to use this +# file. This includes Django's development server, if the WSGI_APPLICATION +# setting points here. +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() + +# Apply WSGI middleware here. +# from helloworld.wsgi import HelloWorldApplication +# application = HelloWorldApplication(application) diff --git a/charts/__init__.py b/charts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/charts/migrations/0001_initial.py b/charts/migrations/0001_initial.py new file mode 100644 index 0000000..4a74c4a --- /dev/null +++ b/charts/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import jsonfield.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Chart', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('ownerSource', models.CharField(max_length=200)), + ('ownerId', models.CharField(max_length=200)), + ('content', jsonfield.fields.JSONField()), + ], + options={ + }, + bases=(models.Model,), + ), + ] diff --git a/charts/migrations/0002_auto_20141007_1601.py b/charts/migrations/0002_auto_20141007_1601.py new file mode 100644 index 0000000..444f446 --- /dev/null +++ b/charts/migrations/0002_auto_20141007_1601.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import datetime + + +class Migration(migrations.Migration): + + dependencies = [ + ('charts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='chart', + name='lastModified', + field=models.DateTimeField(default=datetime.date(2014, 10, 7), auto_now=True), + preserve_default=False, + ), + migrations.AddField( + model_name='chart', + name='name', + field=models.CharField(default='noname', max_length=200), + preserve_default=False, + ), + ] diff --git a/charts/migrations/__init__.py b/charts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/charts/models.py b/charts/models.py new file mode 100644 index 0000000..29bd998 --- /dev/null +++ b/charts/models.py @@ -0,0 +1,16 @@ +from django.db import models +from jsonfield import JSONField + + +class Chart(models.Model): + ownerSource = models.CharField(max_length=200) + ownerId = models.CharField(max_length=200) + name = models.CharField(max_length=200) + lastModified = models.DateTimeField() + content = JSONField() + + def __str__(self): + return self.ownerSource + ":" + self.ownerId + + def setContent(self, _content): + self.content = _content \ No newline at end of file diff --git a/charts/tests.py b/charts/tests.py new file mode 100644 index 0000000..178f860 --- /dev/null +++ b/charts/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..358846a --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "charting_library_charts.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv)