...
 
Commits (36)
......@@ -10,3 +10,4 @@ ALTER "id" SET NOT NULL;
SELECT setval('core_tag_id_seq', (SELECT MAX(id) FROM core_tag)+1);
delete from multiplicity_graphtype where id = 1;
ANONYMIZING DATASET
---------------------
UPDATE auth_user SET username = id, email = id, password = id;
UPDATE core_people SET email = null;
UPDATE core_project SET email = null;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
# Generated by Django 2.1.3 on 2018-11-25 05:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0018_auto_20181104_2313'),
]
operations = [
migrations.AlterField(
model_name='reference',
name='language',
field=models.CharField(choices=[('EN', 'English'), ('ES', 'Spanish'), ('CH', 'Chinese'), ('FR', 'French'), ('GE', 'German'), ('NL', 'Dutch'), ('OT', 'Other')], max_length=2),
),
]
# Generated by Django 2.1.3 on 2018-11-25 05:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0019_auto_20181125_0501'),
]
operations = [
migrations.AlterField(
model_name='reference',
name='title_original_language',
field=models.CharField(blank=True, max_length=255, null=True),
),
]
# Generated by Django 2.1.3 on 2018-11-25 06:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0020_auto_20181125_0510'),
]
operations = [
migrations.AlterField(
model_name='reference',
name='authors',
field=models.ManyToManyField(blank=True, to='core.People'),
),
migrations.AlterField(
model_name='reference',
name='tags',
field=models.ManyToManyField(blank=True, limit_choices_to={'hidden': False}, to='core.Tag'),
),
]
......@@ -188,6 +188,8 @@ class Event(models.Model):
type = models.CharField(max_length=20, choices=EVENT_TYPE)
location = models.CharField(max_length=255, null=True, blank=True)
url = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return self.article.title
class EventForm(ModelForm):
class Meta:
......@@ -248,7 +250,7 @@ class TagForm(ModelForm):
class Reference(models.Model):
title = models.CharField(max_length=255)
title_original_language = models.CharField(max_length=255)
title_original_language = models.CharField(max_length=255, blank=True, null=True)
authorlist = models.TextField()
type = models.ForeignKey(ReferenceType, on_delete=models.CASCADE)
journal = models.ForeignKey(Journal, on_delete=models.CASCADE, null=True, blank=True)
......@@ -263,6 +265,7 @@ class Reference(models.Model):
('CH', 'Chinese'),
('FR', 'French'),
('GE', 'German'),
('NL', 'Dutch'),
('OT', 'Other'),
)
language = models.CharField(max_length=2, choices=LANGUAGES)
......@@ -275,9 +278,9 @@ class Reference(models.Model):
('deleted', 'Deleted'),
)
status = models.CharField(max_length=8, choices=STATUS, db_index=True)
authors = models.ManyToManyField(People)
authors = models.ManyToManyField(People, blank=True)
organizations = models.ManyToManyField(Organization, through='ReferenceOrganization')
tags = models.ManyToManyField(Tag, blank=True)
tags = models.ManyToManyField(Tag, blank=True, limit_choices_to={'hidden': False})
def __str__(self):
return self.title
......@@ -301,6 +304,16 @@ class ReferenceForm(ModelForm):
'url': 'URL',
}
class ReferenceFormAdmin(ModelForm):
class Meta:
model = Reference
exclude = ['id', 'organizations']
labels = {
'authorlist': 'Author(s)',
'doi': 'DOI',
'url': 'URL',
}
class ReferenceOrganization(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
reference = models.ForeignKey(Reference, on_delete=models.CASCADE)
......
......@@ -8,7 +8,7 @@ app_name = 'core'
urlpatterns = [
path('', views.index, name='homepage'),
path('home', views.index, name='home'),
path('home', views.home, name='home'),
path('search', views.search, name='search'),
path('more', views.empty, name='more'),
path('resources/videos', views.videos, name='videos'),
......@@ -95,6 +95,7 @@ urlpatterns = [
path('admin/tags/<int:parent>/child', views.admin_tag, name='admin_tag'),
path('admin/publications/<int:id>', views.referenceform, name='admin_reference'),
path('admin/publications/<int:id>/tags', views.admin_referencetags, name='admin_referencetags'),
path('admin/publications', views.admin_references, name='admin_references'),
#temp
path('updateorgs', views.updateorgs),
......
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from .models import Video, Journal, Organization, Publisher, Reference, ReferenceForm, People, Article, PeopleForm, Video, VideoForm, ReferenceOrganization, Project, UserAction, UserLog, SimpleArticleForm, ProjectForm, EventForm, ReferenceType, Tag, Event, TagForm
from .models import Video, Journal, Organization, Publisher, Reference, ReferenceForm, ReferenceFormAdmin, People, Article, PeopleForm, Video, VideoForm, ReferenceOrganization, Project, UserAction, UserLog, SimpleArticleForm, ProjectForm, EventForm, ReferenceType, Tag, Event, TagForm
from team.models import Category, TaskForceMember, TaskForceTicket, TaskForceUnit
from multiplicity.models import ReferenceSpace
from staf.models import Data
......@@ -37,6 +37,10 @@ def search(request):
context = { 'section': 'resources', 'page': '' }
return render(request, 'core/search.html', context)
def home(request):
context = { 'section': 'home', 'page': '' }
return render(request, 'core/home.html', context)
def index(request):
publications = False
events = False
......@@ -224,15 +228,27 @@ def reference(request, id):
def referenceform(request, id=False, dataset=False):
if id:
info = get_object_or_404(Reference, pk=id)
form = ReferenceForm(instance=info)
if request.user.is_staff:
form = ReferenceFormAdmin(instance=info)
else:
form = ReferenceForm(instance=info)
else:
info = False
form = ReferenceForm()
if request.user.is_staff:
form = ReferenceFormAdmin()
else:
form = ReferenceForm()
if request.method == 'POST':
if not id:
form = ReferenceForm(request.POST)
if request.user.is_staff:
form = ReferenceFormAdmin(request.POST)
else:
form = ReferenceForm(request.POST)
else:
form = ReferenceForm(request.POST, instance=info)
if request.user.is_staff:
form = ReferenceFormAdmin(request.POST, instance=info)
else:
form = ReferenceForm(request.POST, instance=info)
if form.is_valid():
info = form.save()
create_record = get_object_or_404(UserAction, pk=1)
......@@ -713,3 +729,9 @@ def admin_referencetags(request, id):
context = { 'navbar': 'backend', 'tags': tags, 'info': info, 'parent_tags': parent_tags, 'select2': True }
return render(request, 'core/admin/reference.tags.html', context)
@staff_member_required
def admin_references(request):
list = Reference.objects.all()
context = { 'navbar': 'backend', 'list': list, 'datatables': True }
return render(request, 'core/admin/references.list.html', context)
......@@ -28,7 +28,7 @@ DEBUG = True
ALLOWED_HOSTS = ['localhost', 'web']
# MoC = 1, MoI = 2
SITE_ID = 2
SITE_ID = 1
# Application definition
INSTALLED_APPS = [
......@@ -48,6 +48,7 @@ INSTALLED_APPS = [
'bootstrap3',
'tinymce',
'django_cron',
'stdimage',
]
MIDDLEWARE = [
......
from django.contrib import admin
from .models import Topic, DatasetType, ReferenceSpace, ReferenceSpaceType, ReferenceSpaceLocation, ReferenceSpaceFeature, Feature, ReferenceSpaceTypeDescription, DQIRating, DQI, Information, ReferenceSpaceCSV, GraphType, DatasetTypeStructure
from .models import Topic, DatasetType, ReferenceSpace, ReferenceSpaceType, ReferenceSpaceLocation, ReferenceSpaceFeature, Feature, ReferenceSpaceTypeDescription, DQIRating, DQI, Information, ReferenceSpaceCSV, GraphType, DatasetTypeStructure, Photo, ProcessGroup
class ReferenceSpaceTypeAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("name",)}
......@@ -21,3 +21,5 @@ admin.site.register(ReferenceSpaceTypeDescription)
admin.site.register(ReferenceSpaceCSV)
admin.site.register(GraphType)
admin.site.register(DatasetTypeStructure)
admin.site.register(Photo)
admin.site.register(ProcessGroup)
# Generated by Django 2.1.3 on 2018-11-23 05:47
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('multiplicity', '0008_datasettypestructure_icon'),
]
operations = [
migrations.CreateModel(
name='Photo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('image', models.ImageField(blank=True, null=True, upload_to='photos')),
('author', models.CharField(max_length=255)),
('source_url', models.CharField(blank=True, max_length=255, null=True)),
('description', models.TextField(blank=True, null=True)),
('deleted', models.BooleanField(db_index=True, default=False)),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='multiplicity.ReferenceSpace')),
('uploaded_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['-created_at', '-updated_at'],
'abstract': False,
},
),
]
# Generated by Django 2.1.3 on 2018-11-23 05:49
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0009_photo'),
]
operations = [
migrations.AddField(
model_name='photo',
name='topic',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.Topic'),
),
]
# Generated by Django 2.1.3 on 2018-11-23 06:50
from django.db import migrations, models
import django.db.models.deletion
import stdimage.models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0010_photo_topic'),
]
operations = [
migrations.RenameField(
model_name='photo',
old_name='space',
new_name='primary_space',
),
migrations.AlterField(
model_name='photo',
name='image',
field=stdimage.models.StdImageField(default=1, upload_to='photos'),
preserve_default=False,
),
migrations.AlterField(
model_name='photo',
name='topic',
field=models.ForeignKey(blank=True, limit_choices_to={'parent__isnull': True}, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.Topic'),
),
]
# Generated by Django 2.1.3 on 2018-11-24 14:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0011_auto_20181123_0650'),
]
operations = [
migrations.AddField(
model_name='datasettype',
name='slug',
field=models.SlugField(blank=True, null=True),
),
]
# Generated by Django 2.1.3 on 2018-11-25 05:03
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0019_auto_20181125_0501'),
('multiplicity', '0012_datasettype_slug'),
]
operations = [
migrations.AddField(
model_name='referencespace',
name='tag',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Tag'),
),
]
# Generated by Django 2.1.3 on 2018-11-25 06:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0013_referencespace_tag'),
]
operations = [
migrations.AddField(
model_name='topic',
name='deleted',
field=models.BooleanField(db_index=True, default=False),
),
]
# Generated by Django 2.1.3 on 2018-11-25 06:29
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0014_topic_deleted'),
]
operations = [
migrations.AddField(
model_name='information',
name='dataset_types',
field=models.ManyToManyField(blank=True, to='multiplicity.DatasetType'),
),
migrations.AlterField(
model_name='information',
name='topic',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='multiplicity.Topic'),
),
]
# Generated by Django 2.1.3 on 2018-11-25 06:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0015_auto_20181125_0629'),
]
operations = [
migrations.AlterField(
model_name='information',
name='dataset_types',
field=models.ManyToManyField(blank=True, limit_choices_to={'active': True}, to='multiplicity.DatasetType'),
),
]
# Generated by Django 2.1.3 on 2018-11-27 09:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('staf', '0007_process_code'),
('multiplicity', '0016_auto_20181125_0631'),
]
operations = [
migrations.AddField(
model_name='information',
name='processes',
field=models.ManyToManyField(blank=True, limit_choices_to={'is_separator': False}, to='staf.Process'),
),
]
# Generated by Django 2.1.3 on 2018-11-27 20:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0017_information_processes'),
]
operations = [
migrations.AddField(
model_name='graphtype',
name='timeframes',
field=models.CharField(choices=[('single', 'Single material'), ('multiple', 'Multiple materials'), ('both', 'Does not matter')], default='both', max_length=25),
),
]
# Generated by Django 2.1.3 on 2018-11-27 20:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('multiplicity', '0018_graphtype_timeframes'),
]
operations = [
migrations.AddField(
model_name='graphtype',
name='materials',
field=models.CharField(choices=[('single', 'Single material'), ('multiple', 'Multiple materials'), ('both', 'Does not matter')], default='both', max_length=25),
),
migrations.AlterField(
model_name='graphtype',
name='timeframes',
field=models.CharField(choices=[('single', 'Single timeframe'), ('multiple', 'Multiple timeframes'), ('both', 'Does not matter')], default='both', max_length=25),
),
]
# Generated by Django 2.1.3 on 2018-12-01 13:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('staf', '0007_process_code'),
('multiplicity', '0019_auto_20181127_2033'),
]
operations = [
migrations.CreateModel(
name='ProcessGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('icon', models.CharField(blank=True, max_length=255, null=True)),
('slug', models.SlugField(max_length=255, unique=True)),
('description', models.TextField(blank=True, null=True)),
('processes', models.ManyToManyField(blank=True, to='staf.Process')),
],
),
]
......@@ -5,6 +5,9 @@ from django.contrib.auth import get_user_model
from tinymce import HTMLField
from django.forms import ModelForm
# Used for image resizing
from stdimage.models import StdImageField
User = get_user_model()
class TimestampedModel(models.Model):
......@@ -31,6 +34,7 @@ class Topic(models.Model):
position = models.PositiveSmallIntegerField()
description = models.TextField(null=True, blank=True)
materials = models.ManyToManyField('staf.Material', blank=True)
deleted = models.BooleanField(default=False, db_index=True)
def __str__(self):
return self.name
class Meta:
......@@ -92,10 +96,14 @@ class DatasetType(models.Model):
type = models.CharField(max_length=6, choices=TYPES, default='flows')
image = models.ImageField(null=True, blank=True, upload_to='datasettype')
category = models.ForeignKey(DatasetTypeStructure, on_delete=models.CASCADE, null=True, blank=True)
slug = models.SlugField(null=True, blank=True)
active = models.BooleanField()
def __str__(self):
return self.name
if self.category:
return '%s (%s)' % (self.name, self.category.name)
else:
return self.name
class Meta:
ordering = ["name"]
......@@ -103,7 +111,7 @@ class DatasetType(models.Model):
class DatasetTypeForm(ModelForm):
class Meta:
model = DatasetType
fields = ['name', 'description', 'flows', 'type', 'category', 'active']
fields = ['name', 'description', 'flows', 'type', 'category', 'topic', 'slug', 'active']
class ReferenceSpace(models.Model):
......@@ -117,6 +125,7 @@ class ReferenceSpace(models.Model):
image = models.ImageField(null=True, blank=True, upload_to='referencespace')
location = models.ForeignKey('multiplicity.ReferenceSpaceLocation', on_delete=models.SET_NULL, null=True, blank=True)
csv = models.ForeignKey('multiplicity.ReferenceSpaceCSV', on_delete=models.CASCADE, null=True, blank=True)
tag = models.ForeignKey('core.Tag', on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.name
......@@ -145,7 +154,7 @@ class ReferenceSpaceLocation(models.Model):
source = models.CharField(max_length=255, null=True, blank=True)
geojson = models.TextField(null=True, blank=True)
def __str__(self):
return self.name
return self.name or 'Location for ' + self.space.name
class Meta:
ordering = ["name"]
......@@ -209,20 +218,63 @@ class Information(TimestampedModel):
content = HTMLField('Content')
space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE)
references = models.ManyToManyField("core.Reference", blank=True)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE, blank=True, null=True)
dataset_types = models.ManyToManyField(DatasetType, blank=True, limit_choices_to={'active': True})
type = models.ForeignKey(ReferenceSpaceType, on_delete=models.CASCADE, null=True, blank=True)
processes = models.ManyToManyField("staf.Process", blank=True, limit_choices_to={'is_separator': False})
def __str__(self):
return self.title
class InformationForm(ModelForm):
class Meta:
model = Information
fields = ['title', 'content']
fields = ['title', 'content', 'dataset_types']
class GraphType(models.Model):
title = models.CharField(max_length=255)
slug = models.CharField(max_length=255)
url = models.CharField(max_length=255, null=True, blank=True)
notes = HTMLField('Content', null=True, blank=True)
TIMEFRAMES = (
('single', 'Single timeframe'),
('multiple', 'Multiple timeframes'),
('both', 'Does not matter'),
)
timeframes = models.CharField(max_length=25, choices=TIMEFRAMES, default='both')
MATERIALS = (
('single', 'Single material'),
('multiple', 'Multiple materials'),
('both', 'Does not matter'),
)
materials = models.CharField(max_length=25, choices=MATERIALS, default='both')
def __str__(self):
return self.title
class Photo(TimestampedModel):
image = StdImageField(upload_to='photos', variations={'thumbnail': (200, 150), 'large': (1024, 780),})
author = models.CharField(max_length=255)
source_url = models.CharField(max_length=255, null=True, blank=True)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE, null=True, blank=True, limit_choices_to={'parent__isnull': True})
description = models.TextField(null=True, blank=True)
primary_space = models.ForeignKey(ReferenceSpace, on_delete=models.CASCADE)
uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE)
deleted = models.BooleanField(default=False, db_index=True)
def __str__(self):
return self.author or 'No name'
class PhotoForm(ModelForm):
class Meta:
model = Photo
exclude = ['id', 'uploaded_by', 'primary_space', 'deleted']
class ProcessGroup(models.Model):
name = models.CharField(max_length=255)
icon = models.CharField(max_length=255, null=True, blank=True)
slug = models.SlugField(db_index=True, max_length=255, unique=True)
description = models.TextField(null=True, blank=True)
processes = models.ManyToManyField('staf.Process', blank=True)
def __str__(self):
return self.name
......@@ -271,4 +271,52 @@ table.table-striped .even {
.city-overview .table .data-available .data-box.available {
background-color: #8bc34a;
}
\ No newline at end of file
}
#gallery img {
border:1px solid #ccc;
padding:5px;
margin:5px;
float:left;
}
#gallery figcaption{display:none}
.resourcelist .single-resource {
background-color: #f5f5f5;
padding: 15px;
margin-bottom: 3px;
transition: background-color 0.1s;
}
.resourcelist .single-resource:hover {
background-color: #e5e5e5;
cursor: pointer;
}
.resourcelist .single-resource:first-of-type {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.resourcelist .single-resource:last-of-type {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.resourcelist .single-resource .title {
margin: 0 0 10px 0;
font-family: unset;
font-size: 18px;
}
.resourcelist .single-resource .journal-name, .resourcelist .single-resource .type {
border-bottom: 1px solid #ccc;
margin-bottom: 3px;
}
.resourcelist .single-resource .journal-name {
padding-bottom: 3px;
}
.resourcelist .single-resource .year {
opacity:0.6;
}
......@@ -27,18 +27,26 @@ urlpatterns = [
path('', views.index, name='index'),
path('<slug:city>/research', views.research, name='research'),
path('<slug:city>/material-stocks/<slug:type>', views.flow, name='stock'),
path('<slug:city>/material-flows/<slug:slug>', views.overview, name='flows'),
path('<slug:city>/material-flows/<slug:slug>', views.overview, name='overview_flows'),
path('<slug:city>/material-flows/<slug:slug>/<slug:type>', views.flow, name='flow'),
path('<slug:city>/material-stocks', views.overview, {'slug': 'material-stocks' }, name='overview_stocks'),
path('<slug:city>/maps', views.map, name='map_home'),
path('<slug:city>/maps/<slug:type>', views.map, name='map'),
path('<slug:city>/datasets', views.datasets, name='datasets'),
path('<slug:city>/resources/photos', views.photos, name='photos'),
path('<slug:city>/resources/<slug:slug>', views.resources, name='resources'),
path('<slug:city>/datasets/<int:id>', views.dataset, name='dataset'),
path('<slug:city>/datasets/<int:id>/delete', views.delete_dataset, name='delete_dataset'),
path('<slug:city>/datasets/<int:dataset>/graph/<int:id>', views.graph, name='graph'),
path('<slug:city>/datasets/<int:id>/<slug:slug>', views.dataset, name='dataset_slice'),
path('<slug:city>/information', views.information_form, name='information_form'),
path('<slug:city>/information/topic/<int:topic>', views.information_form, name='information_form_topic'),
path('<slug:city>/information/<int:id>', views.information_form, name='information_form'),
path('<slug:city>/photo', views.photo_form, name='photo_form'),
path('<slug:city>/photo/<int:id>', views.photo_form, name='photo_form'),
# Uploading data
path('<slug:city>/upload', views.upload, name='upload'),
......
This diff is collapsed.
......@@ -6,3 +6,4 @@ django-tinymce4-lite
Pillow
django_cron
python-dateutil
django-stdimage
# Generated by Django 2.1.3 on 2018-11-25 05:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('staf', '0005_auto_20181123_0505'),
]
operations = [
migrations.AlterField(
model_name='dataset',
name='topics',
field=models.ManyToManyField(blank=True, to='multiplicity.Topic'),
),
]
# Generated by Django 2.1.3 on 2018-11-27 04:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('staf', '0006_auto_20181125_0501'),
]
operations = [
migrations.AddField(
model_name='process',
name='code',
field=models.CharField(blank=True, db_index=True, max_length=255, null=True),
),
]
......@@ -18,12 +18,19 @@ class ProcessType(models.Model):
class Process(models.Model):
name = models.CharField(max_length=255, db_index=True)
code = models.CharField(max_length=255, null=True, blank=True, db_index=True)
description = models.TextField(null=True, blank=True)
type = models.ForeignKey(ProcessType, on_delete=models.CASCADE, null=True, blank=True)
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
is_separator = models.BooleanField()
def __str__(self):
return self.name
if self.code:
return self.code + " - " + self.name
else:
return self.name
class Meta:
ordering = ["id"]
class ProcessForm(ModelForm):
class Meta:
......@@ -95,11 +102,19 @@ class Dataset(models.Model):
replication = models.TextField(blank=True, null=True)
type = models.ForeignKey('multiplicity.DatasetType', on_delete=models.CASCADE, null=True, blank=True)
graph = models.ForeignKey('multiplicity.GraphType', on_delete=models.CASCADE, null=True, blank=True)
topics = models.ManyToManyField(Topic)
topics = models.ManyToManyField(Topic, blank=True)
deleted = models.BooleanField(default=False, db_index=True)
def __str__(self):
return self.name
def timeframe(self):
from django.db.models import Max
from django.db.models import Min
return Data.objects.filter(dataset=self.id).aggregate(start=Min('timeframe__start'), end=Max('timeframe__end'))
def materials(self):
return Data.objects.filter(dataset=self.id).values('material_name').order_by('material_name').distinct()
class DatasetForm(ModelForm):
class Meta:
model = Dataset
......
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}Publications{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li><a href="{% url 'team:controlpanel' %}">Back-end</a></li>
<li class="active">Publications</li>
</ol>
<h3>Publications</h3>
<div class="row">
<div class="col-lg-12">
<div class="boxit pad-all">
<table class="table table-striped datatable">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Date</th>
<th>Added</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for details in list %}
<tr>
<td><a href="{% url 'core:admin_reference' details.id %}">{{ details.id }}</a></td>
<td>{{ details.title|truncatewords:10 }}</td>
<td>{{ details.year }}</td>
<td>{{ details.date_added }}</td>
<td>{{ details.status }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<p class="pad-top"><a href="{% url 'core:newreference' %}" class="btn btn-success"><i class="fas fa-plus fa-fw"></i> Add new publication</a></p>
</div>
{% endblock %}
{% block head %}
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block footer %}
{% endblock %}
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}SAMPLETITLE{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
{% include 'multiplicity/includes/top.navbar.html' %}
<div class="row">
<div class="col-lg-12">
<div class="panel">
<div class="panel-body">
<h3>Your content here...</h3>
<p>Start putting content on grids or panels, you can also use different combinations of grids.
</div>
</div>
</div>
</div>
{% endblock %}
{% block head %}
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block pagehead %}
<div id="page-head">
<div id="page-title">
<h1 class="page-header text-overflow">Metabolism of Cities</h1>
</div>
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li class="active">Homepage</li>
</ol>
</div>
{% endblock %}
{% block footer %}
{% endblock %}
......@@ -67,6 +67,9 @@ textarea[name='authorlist']{height:100px}
<script type="text/javascript">
$(function(){
$("#id_journal").select2();
$("#id_authors").select2();
$("#id_organizations").select2();
$("#id_tags").select2();
});
</script>
{% endblock %}
......@@ -23,7 +23,7 @@
</div>
</div>
<div class="col-lg-3">
<div class="col-lg-3 noclick">
<div class="panel panel-success panel-colorful">
<div class="pad-all media">
......@@ -81,7 +81,7 @@
</div>
<div class="col-lg-3">
<div class="col-lg-3 noclick">
<div class="panel panel-warning panel-colorful">
<div class="pad-all media">
......@@ -144,8 +144,8 @@
</div>
<div class="row blog">
{% for details in types %}
{% if details.id in count %}
{% if forloop.counter|divisibleby:4 %}</div><div class="row blog">{% endif %}
{% if details.total %}
{% if forloop.counter|divisibleby:4 %}</div><div class="row hide blog">{% endif %}
<div class="col-md-4">
<div class="panel">
<div class="blog-header">
......@@ -172,9 +172,52 @@
{% endfor %}
</div>
<h2>Resources</h2>
<div class="alert alert-warning">
The following resources have been recently added:
</div>
<div class="row">
<div class="col-md-4">
<h4>Material Flows</h4>
<ul class="nav nav-list">
{% for details in datasets_flows %}
<li><a class="list-group-item" href="{% url 'multiplicity:dataset' info.slug details.id %}"><i class="fal fa-database fa-fw"></i> {{ details.name }}</a></li>
{% endfor %}
</ul>
</div>
<div class="col-md-4">
<h4>Material Stock</h4>
<ul class="nav nav-list">
{% for details in datasets_stocks %}
<li><a class="list-group-item" href="{% url 'multiplicity:dataset' info.slug details.id %}"><i class="fal fa-database fa-fw"></i> {{ details.name }}</a></li>
{% endfor %}
</ul>
</div>
<div class="col-md-4">
<h4>Documents</h4>
<ul class="nav nav-list">
{% for details in references %}
<li><a class="list-group-item" href="{% url 'core:reference' details.id %}"><i class="fal fa-file fa-fw"></i> {{ details.title }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="row" style="display:none">
<div class="col-md-12" style="padding-top:20px">
......@@ -254,6 +297,7 @@
.city-header { min-height:330px;previous:298px;}
.morris-legend-items{padding-top:20px}
#page-content .icon-fw{margin-right:-5px;position:relative;top:10px}
.noclick a:hover{cursor:text;text-decoration:none}
</style>
{% endblock %}
......@@ -280,6 +324,10 @@
<script type="text/javascript" src="{% static 'ie/js/raphael.js' %}"></script>
<script type="text/javascript">
$(function(){
$(".noclick a").click(function(e){
e.preventDefault();
});
var chart = Morris.Area({
element: 'largegraph',
data: [{
......
......@@ -189,10 +189,14 @@
<section id="tab-charts" class="tab-pane active in">
<div class="text-center charts-icons">
<div class="btn-group btn-group-lg">
<div class="btn-group btn-group-lg graphlinks">
{% for details in graphs %}
{% with "multiplicity/img/graphs/"|add:details.slug|add:".svg" as picture %}
<a class="btn btn-default" href="{% url 'multiplicity:graph' info.slug dataset.id details.id %}" title="{{ details.title }}"><img src="{% static picture %}"></a>
{% if timeframes > 1 and details.timeframes == "multiple" or details.timeframes == "both" or timeframes == 1 and details.timeframes == "single" %}
{% if materials.count > 1 and details.materials == "multiple" or details.materials == "both" or materials.count == 1 and details.materials == "single" %}
<a class="btn btn-default" href="{% url 'multiplicity:graph' info.slug dataset.id details.id %}" title="{{ details.title }}"><img src="{% static picture %}"></a>
{% endif %}
{% endif %}
{% endwith %}
{% endfor %}
</div>
......@@ -273,6 +277,8 @@
}
});
$(".graphlinks a:first-child").click();
});
</script>
......
{% extends 'multiplicity/base.html' %}
{% load static %}
{% block title %}{{ info.name }} | {{ info.country }}{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<section>
<h2>{{ type.name }}</h2>
{% if information %}
{% for details in information %}
<h3>{{ details.title }}</h3>
{{ details.content|safe }}
{% endfor %}
{% endif %}
<div class="row">
{% for dataset in list %}
<div class="col-lg-6">
<div class="panel panel-dark">
<div class="panel-heading">
<h3 class="panel-title"><a href="{% url 'multiplicity:dataset' info.slug dataset.id %}">{{ dataset.name }}</a></h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-lg-4 is-bold">
City
</div>
<div class="col-lg-8">
{{ dataset.primary_space.name }}, {{ dataset.primary_space.country.name }}
</div>
<div class="col-lg-4 is-bold">
Source(s)
</div>
<div class="col-lg-8">
{% for details in dataset.references.all %}
<a href="{% url 'core:reference' details.id %}">{{ details.title }}</a>
{% endfor %}
</div>
<div class="col-lg-4 is-bold">
Data points
</div>
<div class="col-lg-8">
{{ dataset.data_set.count }}
</div>
<div class="col-lg-4 is-bold">
Time frames
</div>
<div class="col-lg-8">
{{ dataset.timeframe.start }} - {{ dataset.timeframe.end }}
</div>
<div class="col-lg-4 is-bold">
Materials
</div>
<div class="col-lg-8">
<ul class="list-unstyled">
{% for details in dataset.materials %}
<li>
<span class="label label-info">
{{ details.material_name|truncatechars:20 }}
</span>
</li>
{% endfor %}
{% if materials_hidden %}
<li><span class="label label-success">+{{ materials_hidden }} other materials</span></li>
{% endif %}
</ul>
</div>
</div>
<p class="pull-right"><a href="{% url 'multiplicity:dataset' info.slug dataset.id %}" class="btn btn-success">View dataset</a></p>
</div>
</div>
</div>
{% endfor %}
</div>
</section>
{% if photos %}
<h3>Photos</h3>
{% include 'multiplicity/includes/photos.html' %}
{% endif %}
{% endblock %}
{% block head %}
<style type="text/css">
.main-content-block h3.panel-title a{color:#fff}
</style>
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block pagehead %}
<div id="page-head">
<div id="page-title">
<h1 class="page-header text-overflow">{{ info.name }}</h1>
</div>
<ol class="breadcrumb">
<li><a href="./"><i class="pli-home"></i></a></li>
<li><a href="{% url 'multiplicity:index' %}">Cities</a></li>
<li><a href="{% url 'multiplicity:city' info.slug %}">{{ info.name }}</a></li>
<li><a href="{% url 'multiplicity:overview_flows' info.slug type.category.slug %}">Material flows</a></li>
<li><a href="{% url 'multiplicity:overview_flows' info.slug type.category.slug %}">{{ type.category.name }}</a></li>
<li class="active">{{ type.name }}</li>
</ol>
</div>
{% endblock %}
{% block footer %}
<script type="text/javascript">
$(function(){
$(".data-available").each(function() {
var available = $(this).attr("available");
var total = $(this).attr("total");
var unavailable = total - available;
var width = 100 / total;
for (var i = 1; i <= available; i++) {
$(document.createElement('div')).addClass("data-box available").css("width", "calc(" + width + "% - 1px)").appendTo(this);
};
for (var i = 1; i <= unavailable; i++) {
$(document.createElement('div')).addClass("data-box").css("width", "calc(" + width + "% - 1px)").appendTo(this);
};
});
$(".city-overview .table .expand").click(function() {
var parentRow = $(this).parent("tr");
$(parentRow).children("td").each(function() {
$(this).width( $(this).width() );
});
$("i", this).toggleClass("fa-caret-up");
$(this).parent().next("tr.extra-info").toggle();
});
});
</script>
{% endblock %}
{% extends 'multiplicity/base.html' %}
{% load bootstrap3 %}
{% load static %}
{% block title %}Dataset type{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12">
<div class="panel panel-body">
<div class="panel-heading">
<h3>Information</h3>
</div>
<div class="panel-body" style="margin-top:30px">
<form method="post" class="form form-horizontal" enctype="multipart/form-data">
{% bootstrap_form form layout='horizontal' %}
{% buttons %}
<div class="form-group">
<label class="col-md-3 control-label" for="processes">Processes</label>
<div class="col-md-9">
<select class="form-control" name="processes" multiple id="processes">
{% for details in processes %}
<option value="{{ details.id }}" {% if details in information.processes.all %}selected{% endif %}>{{ details.code }}. {{ details.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-success">
Save
</button>
</div>
{% endbuttons %}
{% csrf_token %}
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block head %}
<style type="text/css">
.form-horizontal .col-md-3[for='id_content']{width:90%;text-align:left}
#processes, #id_dataset_types{height:300px}
</style>
{% endblock %}
{% block sidebar %}
{% include 'multiplicity/sidebar.default.html' %}
{% endblock %}
{% block pagehead %}
{% endblock %}
{% block footer %}
{% endblock %}
......@@ -2,7 +2,7 @@
{% load bootstrap3 %}
{% load static %}
{% block title %}Dataset type{% endblock %}
{% block title %}Photo{% endblock %}
{% block container %}stretch-bg-head{% endblock %}
{% block content %}
......@@ -11,9 +11,15 @@
<div class="col-lg-12">
<div class="panel panel-body">
<div class="panel-heading">
<h3>Dataset type</h3>
<h3>Upload photo</h3>
</div>
<div class="panel-body" style="margin-top:30px">
<div class="alert alert-info">
Important note:
only use photos that have a permissive license (creative commons, public domain, etc.).
Do not use photos without a clearly defined permissive license unless you have
permission from the creator.
</div>
<form method="post" class="form form-horizontal" enctype="multipart/form-data">
{% bootstrap_form form layout='horizontal' %}
{% buttons %}
......
......@@ -72,17 +72,17 @@
animation: false
},
title: {
text: 'Title'
text: '{{ dataset.name }}'
},
subtitle: {
text: 'Subtitle'
text: '{{ info.name }}'
},
colors: colorScheme,
xAxis: {
categories: areaCategories,
crosshair: true,
title: {
text: 'X axis label',
text: '',
style: {
fontWeight: 'bold'
},
......@@ -116,4 +116,4 @@
// lines for chart burger menu thinner
$(".highcharts-button-symbol").attr("stroke-width", 1);
</script>
\ No newline at end of file
</script>
......@@ -138,10 +138,10 @@
type: 'bar',
},
title: {
text: 'Title'
text: '{{ dataset.name }}'
},
subtitle: {
text: 'Subtitle'
text: '{{ info.name }}'
},
xAxis: {