diff --git a/.gitignore b/.gitignore index ac4758f..77ae454 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,48 @@ .vscode debug nohup* *swp # Binaries for programs and plugins *.exe *.dll *.so *.dylib # Test binary, build with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ node_modules/ public/api *.idea/* +*.vscode *.log .travis.yml *.bak .tern-project public/build *.tmpl.js public/coverage *.swp frontend/public/assets/* + +#django +*.egg-info +*.pot +*.py[co] +.tox/ +__pycache__ +MANIFEST +dist/ +docs/_build/ +docs/locale/ +node_modules/ +tests/coverage_html/ +tests/.coverage +build/ +tests/report/ diff --git a/frontend/treeview/db.sqlite3 b/frontend/treeview/db.sqlite3 index fb67489..a9ef1b3 100644 Binary files a/frontend/treeview/db.sqlite3 and b/frontend/treeview/db.sqlite3 differ diff --git a/frontend/treeview/test.py b/frontend/treeview/test.py new file mode 100644 index 0000000..b66189c --- /dev/null +++ b/frontend/treeview/test.py @@ -0,0 +1,7 @@ +from jsonview.decorators import json_view + +@json_view +def my_view(request): + return { + 'foo': 'bar', + } diff --git a/frontend/treeview/treeview/settings.py b/frontend/treeview/treeview/settings.py index a3ebdae..8706d33 100644 --- a/frontend/treeview/treeview/settings.py +++ b/frontend/treeview/treeview/settings.py @@ -1,121 +1,123 @@ """ Django settings for treeview project. Generated by 'django-admin startproject' using Django 1.11.3. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'h!khjr!+%c_7v5-^w)*x2*sy5e#0g^3dmzyt1@y0wtr6^x)uiq' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'treeview_app', + 'mptt' ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'treeview.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [os.path.join(BASE_DIR,'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'treeview.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Europe/Moscow' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') + diff --git a/frontend/treeview/treeview/urls.py b/frontend/treeview/treeview/urls.py index 38ea382..6a54e1b 100644 --- a/frontend/treeview/treeview/urls.py +++ b/frontend/treeview/treeview/urls.py @@ -1,21 +1,23 @@ """treeview URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.conf.urls import url +from django.conf.urls import url, include from django.contrib import admin +from django.conf.urls import include urlpatterns = [ url(r'^admin/', admin.site.urls), + url(r'', include('treeview_app.urls')), ] diff --git a/frontend/treeview/treeview_app/admin.py b/frontend/treeview/treeview_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/frontend/treeview/treeview_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/frontend/treeview/treeview_app/apps.py b/frontend/treeview/treeview_app/apps.py new file mode 100644 index 0000000..a14c569 --- /dev/null +++ b/frontend/treeview/treeview_app/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class TreeviewAppConfig(AppConfig): + name = 'treeview_app' diff --git a/frontend/treeview/treeview_app/migrations/0001_initial.py b/frontend/treeview/treeview_app/migrations/0001_initial.py new file mode 100644 index 0000000..9edb7c9 --- /dev/null +++ b/frontend/treeview/treeview_app/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.3 on 2017-07-13 00:30 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='MainModel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True)), + ('value', models.NullBooleanField()), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='treeview_app.MainModel')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/frontend/treeview/treeview_app/migrations/__init__.py b/frontend/treeview/treeview_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/frontend/treeview/treeview_app/models.py b/frontend/treeview/treeview_app/models.py new file mode 100644 index 0000000..24202ce --- /dev/null +++ b/frontend/treeview/treeview_app/models.py @@ -0,0 +1,10 @@ +from django.db import models +from mptt.models import MPTTModel, TreeForeignKey + +class MainModel(MPTTModel): + name = models.CharField(max_length=50, unique=True) + parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) + value = models.NullBooleanField() + + class MPTTMeta: + order_insertion_by = ['name'] \ No newline at end of file diff --git a/frontend/treeview/treeview_app/static/treeview_app/css/jsontree.css b/frontend/treeview/treeview_app/static/treeview_app/css/jsontree.css new file mode 100644 index 0000000..0e8345c --- /dev/null +++ b/frontend/treeview/treeview_app/static/treeview_app/css/jsontree.css @@ -0,0 +1,45 @@ +.jstValue { + white-space: pre-wrap; + font-size: 20px; + font-weight: 400; + font-family: "Lucida Console", Monaco, monospace; +} +.jstComma { + white-space: pre-wrap; +} +.jstProperty { + color: #666; + word-wrap: break-word; +} +.jstBracket { + white-space: pre-wrap;; +} +.jstBool { + color: #2525CC; +} +.jstNum { + color: #D036D0; +} +.jstNull { + color: gray; +} +.jstStr { + color: #2DB669; +} +.jstFold:after { + content: ' -'; + cursor: pointer; +} +.jstExpand { + white-space: normal; +} +.jstExpand:after { + content: ' +'; + cursor: pointer; +} +.jstFolded { + white-space: normal !important; +} +.jstHiddenBlock { + display: none; +} diff --git a/frontend/treeview/treeview_app/static/treeview_app/js/jsontree.js b/frontend/treeview/treeview_app/static/treeview_app/js/jsontree.js new file mode 100644 index 0000000..2f66884 --- /dev/null +++ b/frontend/treeview/treeview_app/static/treeview_app/js/jsontree.js @@ -0,0 +1,155 @@ +var JSONTree = (function() { + + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '/': '/' + }; + + var defaultSettings = { + indent: 2 + }; + + var id = 0; + var instances = 0; + + this.create = function(data, settings) { + instances += 1; + return _span(_jsVal(data, 0, false), {class: 'jstValue'}); + }; + + var _escape = function(text) { + return text.replace(/[&<>'"]/g, function(c) { + return escapeMap[c]; + }); + }; + + var _id = function() { + return instances + '_' + id++; + }; + + var _jsVal = function(value, depth, indent) { + if (value !== null) { + var type = typeof value; + switch (type) { + case 'boolean': + return _jsBool(value, indent ? depth : 0); + case 'number': + return _jsNum(value, indent ? depth : 0); + case 'string': + return _jsStr(value, indent ? depth : 0); + default: + if (value instanceof Array) { + return _jsArr(value, depth, indent); + } else { + return _jsObj(value, depth, indent); + } + } + } else { + return _jsNull(indent ? depth : 0); + } + }; + + var _jsObj = function(object, depth, indent) { + var id = _id(); + var content = Object.keys(object).map(function(property) { + return _property(property, object[property], depth + 1, true); + }).join(_comma()); + var body = [ + _openBracket('{', indent ? depth : 0, id), + _span(content, {id: id}), + _closeBracket('}', depth) + ].join('\n'); + return _span(body, {}) + }; + + var _jsArr = function(array, depth, indent) { + var id = _id(); + var body = array.map(function(element) { + return _jsVal(element, depth + 1, true); + }).join(_comma()); + var arr = [ + _openBracket('[', indent ? depth : 0, id), + _span(body, {id: id}), + _closeBracket(']', depth) + ].join('\n'); + return arr; + }; + + var _jsStr = function(value, depth) { + return _span(_indent(_quote(_escape(value)), depth), {class: 'jstStr'}); + }; + + var _jsNum = function(value, depth) { + return _span(_indent(value, depth), {class: 'jstNum'}); + }; + + var _jsBool = function(value, depth) { + return _span(_indent(value, depth), {class: 'jstBool'}); + }; + + var _jsNull = function(depth) { + return _span(_indent('null', depth), {class: 'jstNull'}); + }; + + var _property = function(name, value, depth) { + var property = _indent(_quote(_escape(name)) + ': ', depth); + var propertyValue = _span(_jsVal(value, depth, false), {}); + return _span(property + propertyValue, {class: 'jstProperty'}); + } + + var _quote = function(value) { + return '"' + value + '"'; + } + + var _comma = function() { + return _span(',\n', {class: 'jstComma'}); + } + + var _span = function(value, attrs) { + return _tag('span', attrs, value); + } + + var _tag = function(tag, attrs, content) { + return '<' + tag + Object.keys(attrs).map(function(attr) { + return ' ' + attr + '="' + attrs[attr] + '"'; + }).join('') + '>' + + content + + ''; + } + + var _openBracket = function(symbol, depth, id) { + return ( + _span(_indent(symbol, depth), {class: 'jstBracket'}) + + _span('', {class: 'jstFold', onclick: 'JSONTree.toggle(\'' + id + '\')'}) + ); + } + + this.toggle = function(id) { + var element = document.getElementById(id); + var parent = element.parentNode; + var toggleButton = element.previousElementSibling; + if (element.className === '') { + element.className = 'jstHiddenBlock'; + parent.className = 'jstFolded'; + toggleButton.className = 'jstExpand'; + } else { + element.className = ''; + parent.className = ''; + toggleButton.className = 'jstFold'; + } + } + + var _closeBracket = function(symbol, depth) { + return _span(_indent(symbol, depth), {}); + } + + var _indent = function(value, depth) { + return Array((depth * 2) + 1).join(' ') + value; + }; + + return this; +})(); \ No newline at end of file diff --git a/frontend/treeview/treeview_app/templates/treeview_app/install_info.html b/frontend/treeview/treeview_app/templates/treeview_app/install_info.html new file mode 100644 index 0000000..b4cbaaf --- /dev/null +++ b/frontend/treeview/treeview_app/templates/treeview_app/install_info.html @@ -0,0 +1,29 @@ + +{% load staticfiles %} + + + json tree example + + + + + + +
+ + + + \ No newline at end of file diff --git a/frontend/treeview/treeview_app/templates/treeview_app/post_list.html b/frontend/treeview/treeview_app/templates/treeview_app/post_list.html new file mode 100644 index 0000000..4f4bdf7 --- /dev/null +++ b/frontend/treeview/treeview_app/templates/treeview_app/post_list.html @@ -0,0 +1,4 @@ + +

Hi there!

+

It works!

+ diff --git a/frontend/treeview/treeview_app/tests.py b/frontend/treeview/treeview_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/frontend/treeview/treeview_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/frontend/treeview/treeview_app/urls.py b/frontend/treeview/treeview_app/urls.py new file mode 100644 index 0000000..35665a3 --- /dev/null +++ b/frontend/treeview/treeview_app/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import url +from . import views +from jsonview.decorators import json_view + + +urlpatterns = [ + url(r'^$', views.post_list, name='post_list'), + url(r'^installInfo/$', views.show_install_info,name='show_install_info'), + +] + diff --git a/frontend/treeview/treeview_app/views.py b/frontend/treeview/treeview_app/views.py new file mode 100644 index 0000000..7533186 --- /dev/null +++ b/frontend/treeview/treeview_app/views.py @@ -0,0 +1,16 @@ +from django.shortcuts import render +from jsonview.decorators import json_view +import json +from django.shortcuts import render_to_response +from treeview_app.models import MainModel + +# Create your views here. + +def show_install_info(request): + json_string = json.dumps({"timestamp1": 22, "timestamp2": 14}) + return render(request,"treeview_app/install_info.html", {'json_string': json_string}) +# def show_genres(request): +# return render("treeview_app/genres.html", +# {'nodes':Genre.objects.all()}) +def post_list(request): + return render(request, 'treeview_app/post_list.html', {})