diff --git a/README.md b/README.md index 895dc3a..09fa9e3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,37 @@ -# langserv -prototype server for creating interactive "try SPARK / try Ada" webpages +# code_examples_server + +Prototype server for creating interactive "try SPARK / try Ada" webpages + +## Getting started + +To setup, do this: +```sh + +# This is to create the virtualenv and install Python stuff +virtualenv env +source env/bin/activate +pip install -r REQUIREMENTS.txt + +# This is to initialize the django database + ./manage.py makemigrations + ./manage.py migrate + +# This is to get the ACE editor +cd compile_server/app/static +git clone https://github.com/ajaxorg/ace-builds.git +``` + +To enter the environment, to this +```sh +source env/bin/activate +``` + +To enter some examples in the database, do this: +```sh +./manage.py fill_examples --dir=resources/example/a +``` + +To launch the server, do this: +```sh +./manage.py runserver +``` diff --git a/REQUIREMENTS.txt b/REQUIREMENTS.txt new file mode 100644 index 0000000..6e5370e --- /dev/null +++ b/REQUIREMENTS.txt @@ -0,0 +1,2 @@ +django +djangorestframework diff --git a/compile_server/app/management/commands/fill_examples.py b/compile_server/app/management/commands/fill_examples.py index 2584ec8..0cb46fa 100644 --- a/compile_server/app/management/commands/fill_examples.py +++ b/compile_server/app/management/commands/fill_examples.py @@ -1,24 +1,68 @@ # The manage.py command to enter examples in the database. # This is meant to be used by the administrators of the project only. +import glob import os +import yaml from django.core.management.base import BaseCommand +from compile_server.app.models import Resource, Example + class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('--remove_all', const=True, default=False, - action='store_const', + action='store_const', help='remove all examples from the database') - parser.add_argument('--dirs', nargs='+', type=str, - help='add the examples found in the given dirs') + parser.add_argument('--dir', nargs=1, type=str, + help='add the example found in the given dir') def handle(self, *args, **options): - if 'remove_all' in + if options.get('remove_all', False): + # Remove all examples from the database + Resource.objects.all().delete() + Example.objects.all().delete() - #where = options['add_dir'] + if options.get('dir', None): + d = options.get('dir')[0] - #if not os.path.isdir(where): - # print "Pass a directory to --dir" + # For now, consider all files in the directory to be part of the + # example + if not os.path.isdir(d): + print "{} is not a valid directory".format(d) + return + + # Look for 'example.yaml' + example_yaml = os.path.join(d, 'example.yaml') + if not os.path.isfile(example_yaml): + print 'There is no "example.yaml" in {}'.format(d) + return + + # Check contents of example.yaml + with open(example_yaml, 'rb') as f: + try: + metadata = yaml.load(f.read()) + except: + print format_traceback + print 'Could not decode yaml in {}'.format(example_yaml) + return + for field in ['name', 'description']: + if field not in metadata: + print 'example.yaml should contain a field {}'.format( + field) + return + + resources = [] + for file in glob.glob(os.path.join(d, '*')): + with open(file, 'rB') as f: + r = Resource(basename=os.path.basename(file), + contents=f.read()) + r.save() + resources.append(r) + + e = Example(description=metadata['description'], + name=metadata['name']) + e.save() + e.resources.add(*resources) diff --git a/compile_server/app/models.py b/compile_server/app/models.py index 3747bef..1c11e82 100644 --- a/compile_server/app/models.py +++ b/compile_server/app/models.py @@ -6,13 +6,6 @@ from django.db import models # Create your models here. -class Program(models.Model): - """That's a program for ya!""" - - # The code - code = models.TextField() - - class ToolOutput(models.Model): """The result on running a tool on a program""" @@ -28,9 +21,9 @@ class Resource(models.Model): """ # Base name of the resource - name = models.TextField() + basename = models.TextField() - # The contents of the resource + # The contents of the resource if it is a file contents = models.TextField() # TODO: if necessary (not sure it is) we can add @@ -46,3 +39,6 @@ class Example(models.Model): # A description description = models.TextField() + + # An example is a contains a set of resources + resources = models.ManyToManyField(Resource) diff --git a/compile_server/app/serializers.py b/compile_server/app/serializers.py index c28bb0a..17a6614 100644 --- a/compile_server/app/serializers.py +++ b/compile_server/app/serializers.py @@ -1,6 +1,6 @@ from django.contrib.auth.models import User, Group from rest_framework import serializers -from compile_server.app.models import Program +from compile_server.app.models import Resource class UserSerializer(serializers.HyperlinkedModelSerializer): @@ -15,17 +15,19 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer): fields = ('url', 'name') -class ProgramSerializer(serializers.Serializer): +class ResourceSerializer(serializers.Serializer): class Meta: - model = Program - fields = ('code') + model = Resource + fields = ('basename', 'code') - code = serializers.CharField(style={'base_template': 'textarea.html'}) + contents = serializers.CharField(style={'base_template': 'textarea.html'}) + basename = serializers.CharField(style={'base_template': 'textarea.html'}) def create(self, validated_data): return Snippet.objects.create(**validated_data) def update(self, instance, validated_data): - instance.code = validated_data.get('code', instance.code) - instance.save() # do we actually want to save programs? + instance.contents = validated_data.get('contents', instance.contents) + instance.basename = validated_data.get('basename', instance.basename) + instance.save() return instance diff --git a/compile_server/app/static/.gitignore b/compile_server/app/static/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/compile_server/app/static/ace-builds b/compile_server/app/static/ace-builds new file mode 160000 index 0000000..673da62 --- /dev/null +++ b/compile_server/app/static/ace-builds @@ -0,0 +1 @@ +Subproject commit 673da62ea06f971c30a660095ceaead16d9356ae diff --git a/compile_server/app/static/common.css b/compile_server/app/static/common.css new file mode 100644 index 0000000..592f21f --- /dev/null +++ b/compile_server/app/static/common.css @@ -0,0 +1,5 @@ +div.editor_container{ + height: 30em; + border: 1px solid #ddd; + border-top: 0px; +} diff --git a/compile_server/app/static/editors.js b/compile_server/app/static/editors.js new file mode 100644 index 0000000..2a642e4 --- /dev/null +++ b/compile_server/app/static/editors.js @@ -0,0 +1,121 @@ +// Fills a
with an editable representation of an example. +// container: the
in question +// example_name: the name of the example to load + +var unique_id = 0 + +function fill_editor(container, example_name) { + + unique_id++; + container.attr("the_id", unique_id); + + // request the examples + $.ajax({ + url: "/example/" + example_name, + data: {}, + type: "GET", + dataType : "json", + }) + .done(function( json ) { + // On success, create editors for each of the resources + + // First create the tabs + + var ul = $( '